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_Class.h"
66 # include "native/include/java_lang_ClassLoader.h"
68 # include "native/include/java_lang_reflect_Constructor.h"
69 # include "native/include/java_lang_reflect_Field.h"
70 # include "native/include/java_lang_reflect_Method.h"
72 # include "native/include/java_nio_Buffer.h"
74 # if defined(WITH_CLASSPATH_GNU)
75 # include "native/include/java_nio_DirectByteBufferImpl.h"
79 #if defined(ENABLE_JVMTI)
80 # include "native/jvmti/cacaodbg.h"
83 #include "native/vm/java_lang_Class.h"
85 #if defined(ENABLE_JAVASE)
86 # include "native/vm/java_lang_ClassLoader.h"
87 # include "native/vm/reflect.h"
90 #include "threads/lock-common.h"
91 #include "threads/threads-common.h"
93 #include "toolbox/logging.h"
96 #include "vm/builtin.h"
97 #include "vm/exceptions.h"
98 #include "vm/global.h"
99 #include "vm/initialize.h"
100 #include "vm/primitive.h"
101 #include "vm/resolve.h"
102 #include "vm/stringlocal.h"
105 #include "vm/jit/argument.h"
106 #include "vm/jit/asmpart.h"
107 #include "vm/jit/jit.h"
108 #include "vm/jit/stacktrace.h"
110 #include "vmcore/loader.h"
111 #include "vmcore/options.h"
112 #include "vmcore/statistics.h"
115 /* debug **********************************************************************/
118 # define TRACEJNICALLS(format, ...) \
120 if (opt_TraceJNICalls) { \
121 log_println((format), __VA_ARGS__); \
125 # define TRACEJNICALLS(format, ...)
129 /* global variables ***********************************************************/
131 /* global reference table *****************************************************/
133 /* hashsize must be power of 2 */
135 #define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
137 static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
140 /* direct buffer stuff ********************************************************/
142 #if defined(ENABLE_JAVASE)
143 static classinfo *class_java_nio_Buffer;
145 # if defined(WITH_CLASSPATH_GNU)
147 static classinfo *class_java_nio_DirectByteBufferImpl;
148 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
150 # if SIZEOF_VOID_P == 8
151 static classinfo *class_gnu_classpath_Pointer64;
153 static classinfo *class_gnu_classpath_Pointer32;
156 static methodinfo *dbbirw_init;
158 # elif defined(WITH_CLASSPATH_SUN)
160 static classinfo *class_sun_nio_ch_DirectBuffer;
161 static classinfo *class_java_nio_DirectByteBuffer;
163 static methodinfo *dbb_init;
169 /* some forward declarations **************************************************/
171 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
174 /* jni_init ********************************************************************
176 Initialize the JNI subsystem.
178 *******************************************************************************/
182 /* create global ref hashtable */
184 hashtable_global_ref = NEW(hashtable);
186 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
189 #if defined(ENABLE_JAVASE)
190 /* Direct buffer stuff. */
192 if (!(class_java_nio_Buffer =
193 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
194 !link_class(class_java_nio_Buffer))
197 # if defined(WITH_CLASSPATH_GNU)
199 if (!(class_java_nio_DirectByteBufferImpl =
200 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
201 !link_class(class_java_nio_DirectByteBufferImpl))
204 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
205 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
206 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
210 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
212 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
215 # if SIZEOF_VOID_P == 8
216 if (!(class_gnu_classpath_Pointer64 =
217 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
218 !link_class(class_gnu_classpath_Pointer64))
221 if (!(class_gnu_classpath_Pointer32 =
222 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
223 !link_class(class_gnu_classpath_Pointer32))
227 # elif defined(WITH_CLASSPATH_SUN)
229 if (!(class_sun_nio_ch_DirectBuffer =
230 load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
231 vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
233 if (!link_class(class_sun_nio_ch_DirectBuffer))
234 vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
236 if (!(class_java_nio_DirectByteBuffer =
237 load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
238 vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
240 if (!link_class(class_java_nio_DirectByteBuffer))
241 vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
244 class_resolvemethod(class_java_nio_DirectByteBuffer,
246 utf_new_char("(JI)V"))))
247 vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
251 #endif /* defined(ENABLE_JAVASE) */
257 /* jni_version_check ***********************************************************
259 Check if the given JNI version is supported.
262 version....JNI version to check
266 false......not supported
268 *******************************************************************************/
270 bool jni_version_check(int version)
273 case JNI_VERSION_1_1:
274 case JNI_VERSION_1_2:
275 case JNI_VERSION_1_4:
276 case JNI_VERSION_1_6:
284 /* _Jv_jni_CallObjectMethod ****************************************************
286 Internal function to call Java Object methods.
288 *******************************************************************************/
290 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
292 methodinfo *m, va_list ap)
297 STATISTICS(jniinvokation());
300 exceptions_throw_nullpointerexception();
304 /* Class initialization is done by the JIT compiler. This is ok
305 since a static method always belongs to the declaring class. */
307 if (m->flags & ACC_STATIC) {
308 /* For static methods we reset the object. */
313 /* for convenience */
318 /* For instance methods we make a virtual function table lookup. */
320 resm = method_vftbl_lookup(vftbl, m);
323 STATISTICS(jnicallXmethodnvokation());
325 ro = vm_call_method_valist(resm, o, ap);
331 /* _Jv_jni_CallObjectMethodA ***************************************************
333 Internal function to call Java Object methods.
335 *******************************************************************************/
337 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
345 STATISTICS(jniinvokation());
348 exceptions_throw_nullpointerexception();
352 /* Class initialization is done by the JIT compiler. This is ok
353 since a static method always belongs to the declaring class. */
355 if (m->flags & ACC_STATIC) {
356 /* For static methods we reset the object. */
361 /* for convenience */
366 /* For instance methods we make a virtual function table lookup. */
368 resm = method_vftbl_lookup(vftbl, m);
371 STATISTICS(jnicallXmethodnvokation());
373 ro = vm_call_method_jvalue(resm, o, args);
379 /* _Jv_jni_CallIntMethod *******************************************************
381 Internal function to call Java integer class methods (boolean,
382 byte, char, short, int).
384 *******************************************************************************/
386 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
387 methodinfo *m, va_list ap)
392 STATISTICS(jniinvokation());
395 exceptions_throw_nullpointerexception();
399 /* Class initialization is done by the JIT compiler. This is ok
400 since a static method always belongs to the declaring class. */
402 if (m->flags & ACC_STATIC) {
403 /* For static methods we reset the object. */
408 /* for convenience */
413 /* For instance methods we make a virtual function table lookup. */
415 resm = method_vftbl_lookup(vftbl, m);
418 STATISTICS(jnicallXmethodnvokation());
420 i = vm_call_method_int_valist(resm, o, ap);
426 /* _Jv_jni_CallIntMethodA ******************************************************
428 Internal function to call Java integer class methods (boolean,
429 byte, char, short, int).
431 *******************************************************************************/
433 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
434 methodinfo *m, const jvalue *args)
439 STATISTICS(jniinvokation());
442 exceptions_throw_nullpointerexception();
446 /* Class initialization is done by the JIT compiler. This is ok
447 since a static method always belongs to the declaring class. */
449 if (m->flags & ACC_STATIC) {
450 /* For static methods we reset the object. */
455 /* for convenience */
460 /* For instance methods we make a virtual function table lookup. */
462 resm = method_vftbl_lookup(vftbl, m);
465 STATISTICS(jnicallXmethodnvokation());
467 i = vm_call_method_int_jvalue(resm, o, args);
473 /* _Jv_jni_CallLongMethod ******************************************************
475 Internal function to call Java long methods.
477 *******************************************************************************/
479 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
480 methodinfo *m, va_list ap)
485 STATISTICS(jniinvokation());
488 exceptions_throw_nullpointerexception();
492 /* Class initialization is done by the JIT compiler. This is ok
493 since a static method always belongs to the declaring class. */
495 if (m->flags & ACC_STATIC) {
496 /* For static methods we reset the object. */
501 /* for convenience */
506 /* For instance methods we make a virtual function table lookup. */
508 resm = method_vftbl_lookup(vftbl, m);
511 STATISTICS(jnicallXmethodnvokation());
513 l = vm_call_method_long_valist(resm, o, ap);
519 /* _Jv_jni_CallLongMethodA *****************************************************
521 Internal function to call Java long methods.
523 *******************************************************************************/
525 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
526 methodinfo *m, const jvalue *args)
531 STATISTICS(jniinvokation());
534 exceptions_throw_nullpointerexception();
538 /* Class initialization is done by the JIT compiler. This is ok
539 since a static method always belongs to the declaring class. */
541 if (m->flags & ACC_STATIC) {
542 /* For static methods we reset the object. */
547 /* for convenience */
552 /* For instance methods we make a virtual function table lookup. */
554 resm = method_vftbl_lookup(vftbl, m);
557 STATISTICS(jnicallXmethodnvokation());
559 l = vm_call_method_long_jvalue(resm, o, args);
565 /* _Jv_jni_CallFloatMethod *****************************************************
567 Internal function to call Java float methods.
569 *******************************************************************************/
571 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
572 methodinfo *m, va_list ap)
577 /* Class initialization is done by the JIT compiler. This is ok
578 since a static method always belongs to the declaring class. */
580 if (m->flags & ACC_STATIC) {
581 /* For static methods we reset the object. */
586 /* for convenience */
591 /* For instance methods we make a virtual function table lookup. */
593 resm = method_vftbl_lookup(vftbl, m);
596 STATISTICS(jnicallXmethodnvokation());
598 f = vm_call_method_float_valist(resm, o, ap);
604 /* _Jv_jni_CallFloatMethodA ****************************************************
606 Internal function to call Java float methods.
608 *******************************************************************************/
610 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
611 methodinfo *m, const jvalue *args)
616 /* Class initialization is done by the JIT compiler. This is ok
617 since a static method always belongs to the declaring class. */
619 if (m->flags & ACC_STATIC) {
620 /* For static methods we reset the object. */
625 /* for convenience */
630 /* For instance methods we make a virtual function table lookup. */
632 resm = method_vftbl_lookup(vftbl, m);
635 STATISTICS(jnicallXmethodnvokation());
637 f = vm_call_method_float_jvalue(resm, o, args);
643 /* _Jv_jni_CallDoubleMethod ****************************************************
645 Internal function to call Java double methods.
647 *******************************************************************************/
649 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
650 methodinfo *m, va_list ap)
655 /* Class initialization is done by the JIT compiler. This is ok
656 since a static method always belongs to the declaring class. */
658 if (m->flags & ACC_STATIC) {
659 /* For static methods we reset the object. */
664 /* for convenience */
669 /* For instance methods we make a virtual function table lookup. */
671 resm = method_vftbl_lookup(vftbl, m);
674 d = vm_call_method_double_valist(resm, o, ap);
680 /* _Jv_jni_CallDoubleMethodA ***************************************************
682 Internal function to call Java double methods.
684 *******************************************************************************/
686 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
687 methodinfo *m, const jvalue *args)
692 /* Class initialization is done by the JIT compiler. This is ok
693 since a static method always belongs to the declaring class. */
695 if (m->flags & ACC_STATIC) {
696 /* For static methods we reset the object. */
701 /* for convenience */
706 /* For instance methods we make a virtual function table lookup. */
708 resm = method_vftbl_lookup(vftbl, m);
711 d = vm_call_method_double_jvalue(resm, o, args);
717 /* _Jv_jni_CallVoidMethod ******************************************************
719 Internal function to call Java void methods.
721 *******************************************************************************/
723 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
724 methodinfo *m, va_list ap)
729 exceptions_throw_nullpointerexception();
733 /* Class initialization is done by the JIT compiler. This is ok
734 since a static method always belongs to the declaring class. */
736 if (m->flags & ACC_STATIC) {
737 /* For static methods we reset the object. */
742 /* for convenience */
747 /* For instance methods we make a virtual function table lookup. */
749 resm = method_vftbl_lookup(vftbl, m);
752 STATISTICS(jnicallXmethodnvokation());
754 (void) vm_call_method_valist(resm, o, ap);
758 /* _Jv_jni_CallVoidMethodA *****************************************************
760 Internal function to call Java void methods.
762 *******************************************************************************/
764 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
765 methodinfo *m, const jvalue *args)
770 exceptions_throw_nullpointerexception();
774 /* Class initialization is done by the JIT compiler. This is ok
775 since a static method always belongs to the declaring class. */
777 if (m->flags & ACC_STATIC) {
778 /* For static methods we reset the object. */
783 /* for convenience */
788 /* For instance methods we make a virtual function table lookup. */
790 resm = method_vftbl_lookup(vftbl, m);
793 STATISTICS(jnicallXmethodnvokation());
795 (void) vm_call_method_jvalue(resm, o, args);
799 /* _Jv_jni_invokeNative ********************************************************
801 Invoke a method on the given object with the given arguments.
803 For instance methods OBJ must be != NULL and the method is looked up
804 in the vftbl of the object.
806 For static methods, OBJ is ignored.
808 *******************************************************************************/
810 java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
811 java_handle_objectarray_t *params)
819 exceptions_throw_nullpointerexception();
823 argcount = m->parseddesc->paramcount;
824 paramcount = argcount;
826 /* if method is non-static, remove the `this' pointer */
828 if (!(m->flags & ACC_STATIC))
831 /* For instance methods the object has to be an instance of the
832 class the method belongs to. For static methods the obj
833 parameter is ignored. */
835 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
836 exceptions_throw_illegalargumentexception();
840 /* check if we got the right number of arguments */
842 if (((params == NULL) && (paramcount != 0)) ||
843 (params && (LLNI_array_size(params) != paramcount)))
845 exceptions_throw_illegalargumentexception();
849 /* for instance methods we need an object */
851 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
852 /* XXX not sure if that is the correct exception */
853 exceptions_throw_nullpointerexception();
857 /* for static methods, zero object to make subsequent code simpler */
858 if (m->flags & ACC_STATIC)
862 /* for instance methods we must do a vftbl lookup */
863 resm = method_vftbl_lookup(LLNI_vftbl_direct(o), m);
866 /* for static methods, just for convenience */
870 ro = vm_call_method_objectarray(resm, o, params);
876 /* GetVersion ******************************************************************
878 Returns the major version number in the higher 16 bits and the
879 minor version number in the lower 16 bits.
881 *******************************************************************************/
883 jint _Jv_JNI_GetVersion(JNIEnv *env)
885 TRACEJNICALLS("_Jv_JNI_GetVersion(env=%p)", env);
887 /* We support JNI 1.6. */
889 return JNI_VERSION_1_6;
893 /* Class Operations ***********************************************************/
895 /* DefineClass *****************************************************************
897 Loads a class from a buffer of raw class data. The buffer
898 containing the raw class data is not referenced by the VM after the
899 DefineClass call returns, and it may be discarded if desired.
901 *******************************************************************************/
903 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
904 const jbyte *buf, jsize bufLen)
906 #if defined(ENABLE_JAVASE)
912 TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen);
914 u = utf_new_char(name);
915 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
917 c = class_define(u, cl, bufLen, (const uint8_t *) buf, NULL);
919 co = LLNI_classinfo_wrap(c);
921 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
923 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
925 /* keep compiler happy */
932 /* FindClass *******************************************************************
934 This function loads a locally-defined class. It searches the
935 directories and zip files specified by the CLASSPATH environment
936 variable for the class with the specified name.
938 *******************************************************************************/
940 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
942 #if defined(ENABLE_JAVASE)
949 TRACEJNICALLS("_Jv_JNI_FindClass(env=%p, name=%s)", env, name);
951 u = utf_new_char_classname((char *) name);
953 /* Check stacktrace for classloader, if one found use it,
954 otherwise use the system classloader. */
956 /* Quote from the JNI documentation:
958 In the Java 2 Platform, FindClass locates the class loader
959 associated with the current native method. If the native code
960 belongs to a system class, no class loader will be
961 involved. Otherwise, the proper class loader will be invoked to
962 load and link the named class. When FindClass is called through
963 the Invocation Interface, there is no current native method or
964 its associated class loader. In that case, the result of
965 ClassLoader.getBaseClassLoader is used." */
967 cc = stacktrace_getCurrentClass();
970 c = load_class_from_sysloader(u);
972 c = load_class_from_classloader(u, cc->classloader);
980 co = LLNI_classinfo_wrap(c);
982 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
984 #elif defined(ENABLE_JAVAME_CLDC1_1)
989 TRACEJNICALLS("_Jv_JNI_FindClass(env=%p, name=%s)", env, name);
991 u = utf_new_char_classname((char *) name);
992 c = load_class_bootstrap(u);
1000 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1003 vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1005 /* keep compiler happy */
1012 /* GetSuperclass ***************************************************************
1014 If clazz represents any class other than the class Object, then
1015 this function returns the object that represents the superclass of
1016 the class specified by clazz.
1018 *******************************************************************************/
1020 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1024 java_lang_Class *co;
1026 TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
1028 c = LLNI_classinfo_unwrap(sub);
1033 super = class_get_superclass(c);
1035 co = LLNI_classinfo_wrap(super);
1037 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1041 /* IsAssignableFrom ************************************************************
1043 Determines whether an object of sub can be safely cast to sup.
1045 *******************************************************************************/
1047 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1049 java_lang_Class *csup;
1050 java_lang_Class *csub;
1052 csup = (java_lang_Class *) sup;
1053 csub = (java_lang_Class *) sub;
1055 STATISTICS(jniinvokation());
1057 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1061 /* Throw ***********************************************************************
1063 Causes a java.lang.Throwable object to be thrown.
1065 *******************************************************************************/
1067 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1071 STATISTICS(jniinvokation());
1073 o = (java_handle_t *) obj;
1075 exceptions_set_exception(o);
1081 /* ThrowNew ********************************************************************
1083 Constructs an exception object from the specified class with the
1084 message specified by message and causes that exception to be
1087 *******************************************************************************/
1089 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1095 STATISTICS(jniinvokation());
1097 c = LLNI_classinfo_unwrap(clazz);
1100 s = javastring_new_from_utf_string(msg);
1102 /* instantiate exception object */
1104 o = native_new_and_init_string(c, s);
1109 exceptions_set_exception(o);
1115 /* ExceptionOccurred ***********************************************************
1117 Determines if an exception is being thrown. The exception stays
1118 being thrown until either the native code calls ExceptionClear(),
1119 or the Java code handles the exception.
1121 *******************************************************************************/
1123 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1127 TRACEJNICALLS("_Jv_JNI_ExceptionOccurred(env=%p)", env);
1129 o = exceptions_get_exception();
1131 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1135 /* ExceptionDescribe ***********************************************************
1137 Prints an exception and a backtrace of the stack to a system
1138 error-reporting channel, such as stderr. This is a convenience
1139 routine provided for debugging.
1141 *******************************************************************************/
1143 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1149 TRACEJNICALLS("_Jv_JNI_ExceptionDescribe(env=%p)", env);
1151 /* Clear exception, because we are probably calling Java code
1154 o = exceptions_get_and_clear_exception();
1157 /* get printStackTrace method from exception class */
1159 LLNI_class_get(o, c);
1161 m = class_resolveclassmethod(c,
1162 utf_printStackTrace,
1168 vm_abort("_Jv_JNI_ExceptionDescribe: could not find printStackTrace");
1170 /* Print the stacktrace. */
1172 (void) vm_call_method(m, o);
1177 /* ExceptionClear **************************************************************
1179 Clears any exception that is currently being thrown. If no
1180 exception is currently being thrown, this routine has no effect.
1182 *******************************************************************************/
1184 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1186 STATISTICS(jniinvokation());
1188 exceptions_clear_exception();
1192 /* FatalError ******************************************************************
1194 Raises a fatal error and does not expect the VM to recover. This
1195 function does not return.
1197 *******************************************************************************/
1199 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1201 STATISTICS(jniinvokation());
1203 /* this seems to be the best way */
1205 vm_abort("JNI Fatal error: %s", msg);
1209 /* PushLocalFrame **************************************************************
1211 Creates a new local reference frame, in which at least a given
1212 number of local references can be created.
1214 *******************************************************************************/
1216 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1218 STATISTICS(jniinvokation());
1223 /* add new local reference frame to current table */
1225 if (!localref_frame_push(capacity))
1232 /* PopLocalFrame ***************************************************************
1234 Pops off the current local reference frame, frees all the local
1235 references, and returns a local reference in the previous local
1236 reference frame for the given result object.
1238 *******************************************************************************/
1240 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1242 STATISTICS(jniinvokation());
1244 /* release all current local frames */
1246 localref_frame_pop_all();
1248 /* add local reference and return the value */
1250 return _Jv_JNI_NewLocalRef(env, result);
1254 /* DeleteLocalRef **************************************************************
1256 Deletes the local reference pointed to by localRef.
1258 *******************************************************************************/
1260 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1264 STATISTICS(jniinvokation());
1266 o = (java_handle_t *) localRef;
1271 /* delete the reference */
1277 /* IsSameObject ****************************************************************
1279 Tests whether two references refer to the same Java object.
1281 *******************************************************************************/
1283 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1289 STATISTICS(jniinvokation());
1291 o1 = (java_handle_t *) ref1;
1292 o2 = (java_handle_t *) ref2;
1294 LLNI_CRITICAL_START;
1296 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1307 /* NewLocalRef *****************************************************************
1309 Creates a new local reference that refers to the same object as ref.
1311 *******************************************************************************/
1313 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1316 java_handle_t *localref;
1318 STATISTICS(jniinvokation());
1320 o = (java_handle_t *) ref;
1325 /* insert the reference */
1327 localref = localref_add(LLNI_DIRECT(o));
1333 /* EnsureLocalCapacity *********************************************************
1335 Ensures that at least a given number of local references can be
1336 created in the current thread
1338 *******************************************************************************/
1340 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1342 localref_table *lrt;
1344 STATISTICS(jniinvokation());
1346 /* get local reference table (thread specific) */
1348 lrt = LOCALREFTABLE;
1350 /* check if capacity elements are available in the local references table */
1352 if ((lrt->used + capacity) > lrt->capacity)
1353 return _Jv_JNI_PushLocalFrame(env, capacity);
1359 /* AllocObject *****************************************************************
1361 Allocates a new Java object without invoking any of the
1362 constructors for the object. Returns a reference to the object.
1364 *******************************************************************************/
1366 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1371 STATISTICS(jniinvokation());
1373 c = LLNI_classinfo_unwrap(clazz);
1375 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1376 exceptions_throw_instantiationexception(c);
1382 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1386 /* NewObject *******************************************************************
1388 Programmers place all arguments that are to be passed to the
1389 constructor immediately following the methodID
1390 argument. NewObject() accepts these arguments and passes them to
1391 the Java method that the programmer wishes to invoke.
1393 *******************************************************************************/
1395 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1402 STATISTICS(jniinvokation());
1404 c = LLNI_classinfo_unwrap(clazz);
1405 m = (methodinfo *) methodID;
1414 /* call constructor */
1416 va_start(ap, methodID);
1417 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1420 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1424 /* NewObjectV ******************************************************************
1426 Programmers place all arguments that are to be passed to the
1427 constructor in an args argument of type va_list that immediately
1428 follows the methodID argument. NewObjectV() accepts these
1429 arguments, and, in turn, passes them to the Java method that the
1430 programmer wishes to invoke.
1432 *******************************************************************************/
1434 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1441 STATISTICS(jniinvokation());
1443 c = LLNI_classinfo_unwrap(clazz);
1444 m = (methodinfo *) methodID;
1453 /* call constructor */
1455 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1457 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1461 /* NewObjectA *****************************************************************
1463 Programmers place all arguments that are to be passed to the
1464 constructor in an args array of jvalues that immediately follows
1465 the methodID argument. NewObjectA() accepts the arguments in this
1466 array, and, in turn, passes them to the Java method that the
1467 programmer wishes to invoke.
1469 *******************************************************************************/
1471 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1478 STATISTICS(jniinvokation());
1480 c = LLNI_classinfo_unwrap(clazz);
1481 m = (methodinfo *) methodID;
1490 /* call constructor */
1492 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1494 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1498 /* GetObjectClass **************************************************************
1500 Returns the class of an object.
1502 *******************************************************************************/
1504 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1508 java_lang_Class *co;
1510 STATISTICS(jniinvokation());
1512 o = (java_handle_t *) obj;
1514 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1517 LLNI_class_get(o, c);
1519 co = LLNI_classinfo_wrap(c);
1521 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1525 /* IsInstanceOf ****************************************************************
1527 Tests whether an object is an instance of a class.
1529 *******************************************************************************/
1531 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1534 java_lang_Object *o;
1536 STATISTICS(jniinvokation());
1538 c = (java_lang_Class *) clazz;
1539 o = (java_lang_Object *) obj;
1541 return _Jv_java_lang_Class_isInstance(c, o);
1545 /* Reflection Support *********************************************************/
1547 /* FromReflectedMethod *********************************************************
1549 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1550 object to a method ID.
1552 *******************************************************************************/
1554 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1556 #if defined(ENABLE_JAVASE)
1562 STATISTICS(jniinvokation());
1564 o = (java_handle_t *) method;
1569 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1570 java_lang_reflect_Method *rm;
1572 rm = (java_lang_reflect_Method *) method;
1573 LLNI_field_get_cls(rm, clazz, c);
1574 LLNI_field_get_val(rm, slot , slot);
1576 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1577 java_lang_reflect_Constructor *rc;
1579 rc = (java_lang_reflect_Constructor *) method;
1580 LLNI_field_get_cls(rc, clazz, c);
1581 LLNI_field_get_val(rc, slot , slot);
1586 m = &(c->methods[slot]);
1588 return (jmethodID) m;
1590 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1592 /* keep compiler happy */
1599 /* FromReflectedField **********************************************************
1601 Converts a java.lang.reflect.Field to a field ID.
1603 *******************************************************************************/
1605 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1607 #if defined(ENABLE_JAVASE)
1608 java_lang_reflect_Field *rf;
1613 STATISTICS(jniinvokation());
1615 rf = (java_lang_reflect_Field *) field;
1620 LLNI_field_get_cls(rf, clazz, c);
1621 LLNI_field_get_val(rf, slot , slot);
1622 f = &(c->fields[slot]);
1624 return (jfieldID) f;
1626 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1628 /* keep compiler happy */
1635 /* ToReflectedMethod ***********************************************************
1637 Converts a method ID derived from cls to an instance of the
1638 java.lang.reflect.Method class or to an instance of the
1639 java.lang.reflect.Constructor class.
1641 *******************************************************************************/
1643 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1646 #if defined(ENABLE_JAVASE)
1648 java_lang_reflect_Constructor *rc;
1649 java_lang_reflect_Method *rm;
1651 TRACEJNICALLS("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic);
1653 m = (methodinfo *) methodID;
1655 /* HotSpot does the same assert. */
1657 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1659 if (m->name == utf_init) {
1660 rc = reflect_constructor_new(m);
1662 return (jobject) rc;
1665 rm = reflect_method_new(m);
1667 return (jobject) rm;
1670 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1672 /* keep compiler happy */
1679 /* ToReflectedField ************************************************************
1681 Converts a field ID derived from cls to an instance of the
1682 java.lang.reflect.Field class.
1684 *******************************************************************************/
1686 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1689 STATISTICS(jniinvokation());
1691 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1697 /* Calling Instance Methods ***************************************************/
1699 /* GetMethodID *****************************************************************
1701 Returns the method ID for an instance (nonstatic) method of a class
1702 or interface. The method may be defined in one of the clazz's
1703 superclasses and inherited by clazz. The method is determined by
1704 its name and signature.
1706 GetMethodID() causes an uninitialized class to be initialized.
1708 *******************************************************************************/
1710 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1718 STATISTICS(jniinvokation());
1720 c = LLNI_classinfo_unwrap(clazz);
1725 if (!(c->state & CLASS_INITIALIZED))
1726 if (!initialize_class(c))
1729 /* try to get the method of the class or one of it's superclasses */
1731 uname = utf_new_char((char *) name);
1732 udesc = utf_new_char((char *) sig);
1734 m = class_resolvemethod(c, uname, udesc);
1736 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1737 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1742 return (jmethodID) m;
1746 /* JNI-functions for calling instance methods *********************************/
1748 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1749 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1750 jmethodID methodID, ...) \
1757 o = (java_handle_t *) obj; \
1758 m = (methodinfo *) methodID; \
1760 va_start(ap, methodID); \
1761 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1767 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1768 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1769 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1770 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1771 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1772 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1773 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1774 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1777 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1778 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1779 jmethodID methodID, va_list args) \
1785 o = (java_handle_t *) obj; \
1786 m = (methodinfo *) methodID; \
1788 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1793 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1794 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1795 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1796 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1797 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1798 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1799 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1800 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1803 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1804 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1805 jmethodID methodID, \
1806 const jvalue *args) \
1812 o = (java_handle_t *) obj; \
1813 m = (methodinfo *) methodID; \
1815 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1820 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1821 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1822 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1823 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1824 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1825 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1826 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1827 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1830 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1838 o = (java_handle_t *) obj;
1839 m = (methodinfo *) methodID;
1841 va_start(ap, methodID);
1842 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1845 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1849 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1856 o = (java_handle_t *) obj;
1857 m = (methodinfo *) methodID;
1859 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1861 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1865 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1872 o = (java_handle_t *) obj;
1873 m = (methodinfo *) methodID;
1875 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1877 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1882 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1888 o = (java_handle_t *) obj;
1889 m = (methodinfo *) methodID;
1891 va_start(ap, methodID);
1892 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1897 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1903 o = (java_handle_t *) obj;
1904 m = (methodinfo *) methodID;
1906 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1910 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1916 o = (java_handle_t *) obj;
1917 m = (methodinfo *) methodID;
1919 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1924 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1925 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1926 jclass clazz, jmethodID methodID, \
1935 o = (java_handle_t *) obj; \
1936 c = LLNI_classinfo_unwrap(clazz); \
1937 m = (methodinfo *) methodID; \
1939 va_start(ap, methodID); \
1940 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1946 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1947 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1948 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1949 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1950 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1951 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1952 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1953 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1956 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1957 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1958 jclass clazz, jmethodID methodID, \
1966 o = (java_handle_t *) obj; \
1967 c = LLNI_classinfo_unwrap(clazz); \
1968 m = (methodinfo *) methodID; \
1970 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1975 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1976 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1977 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1978 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1979 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1980 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1981 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1982 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1985 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1986 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1987 jclass clazz, jmethodID methodID, \
1988 const jvalue *args) \
1990 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
1995 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
1996 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
1997 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
1998 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
1999 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
2000 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
2001 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
2002 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
2004 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2005 jclass clazz, jmethodID methodID,
2014 o = (java_handle_t *) obj;
2015 c = LLNI_classinfo_unwrap(clazz);
2016 m = (methodinfo *) methodID;
2018 va_start(ap, methodID);
2019 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2022 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2026 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2027 jclass clazz, jmethodID methodID,
2035 o = (java_handle_t *) obj;
2036 c = LLNI_classinfo_unwrap(clazz);
2037 m = (methodinfo *) methodID;
2039 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2041 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2045 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2046 jclass clazz, jmethodID methodID,
2049 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2051 return _Jv_JNI_NewLocalRef(env, NULL);
2055 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2056 jmethodID methodID, ...)
2063 o = (java_handle_t *) obj;
2064 c = LLNI_classinfo_unwrap(clazz);
2065 m = (methodinfo *) methodID;
2067 va_start(ap, methodID);
2068 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2073 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2074 jmethodID methodID, va_list args)
2080 o = (java_handle_t *) obj;
2081 c = LLNI_classinfo_unwrap(clazz);
2082 m = (methodinfo *) methodID;
2084 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2088 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2089 jmethodID methodID, const jvalue * args)
2095 o = (java_handle_t *) obj;
2096 c = LLNI_classinfo_unwrap(clazz);
2097 m = (methodinfo *) methodID;
2099 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2103 /* Accessing Fields of Objects ************************************************/
2105 /* GetFieldID ******************************************************************
2107 Returns the field ID for an instance (nonstatic) field of a
2108 class. The field is specified by its name and signature. The
2109 Get<type>Field and Set<type>Field families of accessor functions
2110 use field IDs to retrieve object fields.
2112 *******************************************************************************/
2114 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2122 STATISTICS(jniinvokation());
2124 c = LLNI_classinfo_unwrap(clazz);
2126 /* XXX NPE check? */
2128 uname = utf_new_char((char *) name);
2129 udesc = utf_new_char((char *) sig);
2131 f = class_findfield(c, uname, udesc);
2134 exceptions_throw_nosuchfielderror(c, uname);
2136 return (jfieldID) f;
2140 /* Get<type>Field Routines *****************************************************
2142 This family of accessor routines returns the value of an instance
2143 (nonstatic) field of an object. The field to access is specified by
2144 a field ID obtained by calling GetFieldID().
2146 *******************************************************************************/
2148 #define GET_FIELD(o,type,f) \
2149 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
2151 #define JNI_GET_FIELD(name, type, intern) \
2152 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2156 STATISTICS(jniinvokation()); \
2158 LLNI_CRITICAL_START; \
2160 ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
2162 LLNI_CRITICAL_END; \
2164 return (type) ret; \
2167 JNI_GET_FIELD(Boolean, jboolean, s4)
2168 JNI_GET_FIELD(Byte, jbyte, s4)
2169 JNI_GET_FIELD(Char, jchar, s4)
2170 JNI_GET_FIELD(Short, jshort, s4)
2171 JNI_GET_FIELD(Int, jint, s4)
2172 JNI_GET_FIELD(Long, jlong, s8)
2173 JNI_GET_FIELD(Float, jfloat, float)
2174 JNI_GET_FIELD(Double, jdouble, double)
2177 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2181 TRACEJNICALLS("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID);
2183 LLNI_CRITICAL_START;
2185 o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
2189 return _Jv_JNI_NewLocalRef(env, o);
2193 /* Set<type>Field Routines *****************************************************
2195 This family of accessor routines sets the value of an instance
2196 (nonstatic) field of an object. The field to access is specified by
2197 a field ID obtained by calling GetFieldID().
2199 *******************************************************************************/
2201 #define SET_FIELD(o,type,f,value) \
2202 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
2204 #define JNI_SET_FIELD(name, type, intern) \
2205 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2208 STATISTICS(jniinvokation()); \
2210 LLNI_CRITICAL_START; \
2212 SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
2214 LLNI_CRITICAL_START; \
2217 JNI_SET_FIELD(Boolean, jboolean, s4)
2218 JNI_SET_FIELD(Byte, jbyte, s4)
2219 JNI_SET_FIELD(Char, jchar, s4)
2220 JNI_SET_FIELD(Short, jshort, s4)
2221 JNI_SET_FIELD(Int, jint, s4)
2222 JNI_SET_FIELD(Long, jlong, s8)
2223 JNI_SET_FIELD(Float, jfloat, float)
2224 JNI_SET_FIELD(Double, jdouble, double)
2227 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2230 TRACEJNICALLS("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value);
2232 LLNI_CRITICAL_START;
2234 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
2240 /* Calling Static Methods *****************************************************/
2242 /* GetStaticMethodID ***********************************************************
2244 Returns the method ID for a static method of a class. The method is
2245 specified by its name and signature.
2247 GetStaticMethodID() causes an uninitialized class to be
2250 *******************************************************************************/
2252 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2260 TRACEJNICALLS("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig);
2262 c = LLNI_classinfo_unwrap(clazz);
2267 if (!(c->state & CLASS_INITIALIZED))
2268 if (!initialize_class(c))
2271 /* try to get the static method of the class */
2273 uname = utf_new_char((char *) name);
2274 udesc = utf_new_char((char *) sig);
2276 m = class_resolvemethod(c, uname, udesc);
2278 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2279 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2284 return (jmethodID) m;
2288 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2289 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2290 jmethodID methodID, ...) \
2296 m = (methodinfo *) methodID; \
2298 va_start(ap, methodID); \
2299 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2305 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2306 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2307 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2308 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2309 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2310 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2311 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2312 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2315 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2316 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2317 jmethodID methodID, va_list args) \
2322 m = (methodinfo *) methodID; \
2324 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2329 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2330 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2331 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2332 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2333 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2334 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2335 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2336 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2339 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2340 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2341 jmethodID methodID, const jvalue *args) \
2346 m = (methodinfo *) methodID; \
2348 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2353 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2354 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2355 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2356 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2357 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2358 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2359 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2360 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2363 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2364 jmethodID methodID, ...)
2370 m = (methodinfo *) methodID;
2372 va_start(ap, methodID);
2373 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2376 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2380 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2381 jmethodID methodID, va_list args)
2386 m = (methodinfo *) methodID;
2388 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2390 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2394 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2395 jmethodID methodID, const jvalue *args)
2400 m = (methodinfo *) methodID;
2402 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2404 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2408 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2409 jmethodID methodID, ...)
2414 m = (methodinfo *) methodID;
2416 va_start(ap, methodID);
2417 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2422 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2423 jmethodID methodID, va_list args)
2427 m = (methodinfo *) methodID;
2429 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2433 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2434 jmethodID methodID, const jvalue * args)
2438 m = (methodinfo *) methodID;
2440 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2444 /* Accessing Static Fields ****************************************************/
2446 /* GetStaticFieldID ************************************************************
2448 Returns the field ID for a static field of a class. The field is
2449 specified by its name and signature. The GetStatic<type>Field and
2450 SetStatic<type>Field families of accessor functions use field IDs
2451 to retrieve static fields.
2453 *******************************************************************************/
2455 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2463 STATISTICS(jniinvokation());
2465 c = LLNI_classinfo_unwrap(clazz);
2467 uname = utf_new_char((char *) name);
2468 usig = utf_new_char((char *) sig);
2470 f = class_findfield(c, uname, usig);
2473 exceptions_throw_nosuchfielderror(c, uname);
2475 return (jfieldID) f;
2479 /* GetStatic<type>Field ********************************************************
2481 This family of accessor routines returns the value of a static
2484 *******************************************************************************/
2486 #define JNI_GET_STATIC_FIELD(name, type, field) \
2487 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2493 STATISTICS(jniinvokation()); \
2495 c = LLNI_classinfo_unwrap(clazz); \
2496 f = (fieldinfo *) fieldID; \
2498 if (!(c->state & CLASS_INITIALIZED)) \
2499 if (!initialize_class(c)) \
2502 return f->value->field; \
2505 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2506 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2507 JNI_GET_STATIC_FIELD(Char, jchar, i)
2508 JNI_GET_STATIC_FIELD(Short, jshort, i)
2509 JNI_GET_STATIC_FIELD(Int, jint, i)
2510 JNI_GET_STATIC_FIELD(Long, jlong, l)
2511 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2512 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2515 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2522 STATISTICS(jniinvokation());
2524 c = LLNI_classinfo_unwrap(clazz);
2525 f = (fieldinfo *) fieldID;
2527 if (!(c->state & CLASS_INITIALIZED))
2528 if (!initialize_class(c))
2531 h = LLNI_WRAP(f->value->a);
2533 return _Jv_JNI_NewLocalRef(env, h);
2537 /* SetStatic<type>Field *******************************************************
2539 This family of accessor routines sets the value of a static field
2542 *******************************************************************************/
2544 #define JNI_SET_STATIC_FIELD(name, type, field) \
2545 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2552 STATISTICS(jniinvokation()); \
2554 c = LLNI_classinfo_unwrap(clazz); \
2555 f = (fieldinfo *) fieldID; \
2557 if (!(c->state & CLASS_INITIALIZED)) \
2558 if (!initialize_class(c)) \
2561 f->value->field = value; \
2564 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2565 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2566 JNI_SET_STATIC_FIELD(Char, jchar, i)
2567 JNI_SET_STATIC_FIELD(Short, jshort, i)
2568 JNI_SET_STATIC_FIELD(Int, jint, i)
2569 JNI_SET_STATIC_FIELD(Long, jlong, l)
2570 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2571 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2574 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2580 STATISTICS(jniinvokation());
2582 c = LLNI_classinfo_unwrap(clazz);
2583 f = (fieldinfo *) fieldID;
2585 if (!(c->state & CLASS_INITIALIZED))
2586 if (!initialize_class(c))
2589 f->value->a = LLNI_UNWRAP((java_handle_t *) value);
2593 /* String Operations **********************************************************/
2595 /* NewString *******************************************************************
2597 Create new java.lang.String object from an array of Unicode
2600 *******************************************************************************/
2602 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2604 java_lang_String *s;
2605 java_handle_chararray_t *a;
2608 STATISTICS(jniinvokation());
2610 s = (java_lang_String *) builtin_new(class_java_lang_String);
2611 a = builtin_newarray_char(len);
2613 /* javastring or characterarray could not be created */
2614 if ((a == NULL) || (s == NULL))
2618 for (i = 0; i < len; i++)
2619 LLNI_array_direct(a, i) = buf[i];
2621 LLNI_field_set_ref(s, value , a);
2622 LLNI_field_set_val(s, offset, 0);
2623 LLNI_field_set_val(s, count , len);
2625 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2629 static jchar emptyStringJ[]={0,0};
2631 /* GetStringLength *************************************************************
2633 Returns the length (the count of Unicode characters) of a Java
2636 *******************************************************************************/
2638 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2640 java_lang_String *s;
2643 TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
2645 s = (java_lang_String *) str;
2647 LLNI_field_get_val(s, count, len);
2653 /******************** convertes javastring to u2-array ****************************/
2655 u2 *javastring_tou2(jstring so)
2657 java_lang_String *s;
2658 java_handle_chararray_t *a;
2664 STATISTICS(jniinvokation());
2666 s = (java_lang_String *) so;
2671 LLNI_field_get_ref(s, value, a);
2676 LLNI_field_get_val(s, count, count);
2677 LLNI_field_get_val(s, offset, offset);
2679 /* allocate memory */
2681 stringbuffer = MNEW(u2, count + 1);
2685 for (i = 0; i < count; i++)
2686 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2688 /* terminate string */
2690 stringbuffer[i] = '\0';
2692 return stringbuffer;
2696 /* GetStringChars **************************************************************
2698 Returns a pointer to the array of Unicode characters of the
2699 string. This pointer is valid until ReleaseStringChars() is called.
2701 *******************************************************************************/
2703 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2707 STATISTICS(jniinvokation());
2709 jc = javastring_tou2(str);
2721 return emptyStringJ;
2725 /* ReleaseStringChars **********************************************************
2727 Informs the VM that the native code no longer needs access to
2728 chars. The chars argument is a pointer obtained from string using
2731 *******************************************************************************/
2733 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2735 java_lang_String *s;
2737 STATISTICS(jniinvokation());
2739 if (chars == emptyStringJ)
2742 s = (java_lang_String *) str;
2744 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2748 /* NewStringUTF ****************************************************************
2750 Constructs a new java.lang.String object from an array of UTF-8
2753 *******************************************************************************/
2755 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2757 java_lang_String *s;
2759 TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
2761 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2763 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2767 /****************** returns the utf8 length in bytes of a string *******************/
2769 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2771 java_lang_String *s;
2774 TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
2776 s = (java_lang_String *) string;
2778 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2784 /* GetStringUTFChars ***********************************************************
2786 Returns a pointer to an array of UTF-8 characters of the
2787 string. This array is valid until it is released by
2788 ReleaseStringUTFChars().
2790 *******************************************************************************/
2792 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2797 STATISTICS(jniinvokation());
2805 u = javastring_toutf((java_handle_t *) string, false);
2814 /* ReleaseStringUTFChars *******************************************************
2816 Informs the VM that the native code no longer needs access to
2817 utf. The utf argument is a pointer derived from string using
2818 GetStringUTFChars().
2820 *******************************************************************************/
2822 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2824 STATISTICS(jniinvokation());
2826 /* XXX we don't release utf chars right now, perhaps that should be done
2827 later. Since there is always one reference the garbage collector will
2832 /* Array Operations ***********************************************************/
2834 /* GetArrayLength **************************************************************
2836 Returns the number of elements in the array.
2838 *******************************************************************************/
2840 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2845 STATISTICS(jniinvokation());
2847 a = (java_handle_t *) array;
2849 size = LLNI_array_size(a);
2855 /* NewObjectArray **************************************************************
2857 Constructs a new array holding objects in class elementClass. All
2858 elements are initially set to initialElement.
2860 *******************************************************************************/
2862 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2863 jclass elementClass, jobject initialElement)
2867 java_handle_objectarray_t *oa;
2870 STATISTICS(jniinvokation());
2872 c = LLNI_classinfo_unwrap(elementClass);
2873 o = (java_handle_t *) initialElement;
2876 exceptions_throw_negativearraysizeexception();
2880 oa = builtin_anewarray(length, c);
2885 /* set all elements to initialElement */
2887 for (i = 0; i < length; i++)
2888 array_objectarray_element_set(oa, i, o);
2890 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2894 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2897 java_handle_objectarray_t *oa;
2900 STATISTICS(jniinvokation());
2902 oa = (java_handle_objectarray_t *) array;
2904 if (index >= LLNI_array_size(oa)) {
2905 exceptions_throw_arrayindexoutofboundsexception();
2909 o = array_objectarray_element_get(oa, index);
2911 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2915 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2916 jsize index, jobject val)
2918 java_handle_objectarray_t *oa;
2921 STATISTICS(jniinvokation());
2923 oa = (java_handle_objectarray_t *) array;
2924 o = (java_handle_t *) val;
2926 if (index >= LLNI_array_size(oa)) {
2927 exceptions_throw_arrayindexoutofboundsexception();
2931 /* check if the class of value is a subclass of the element class
2934 if (!builtin_canstore(oa, o))
2937 array_objectarray_element_set(oa, index, o);
2941 #define JNI_NEW_ARRAY(name, type, intern) \
2942 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2944 java_handle_##intern##array_t *a; \
2946 STATISTICS(jniinvokation()); \
2949 exceptions_throw_negativearraysizeexception(); \
2953 a = builtin_newarray_##intern(len); \
2955 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2958 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2959 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2960 JNI_NEW_ARRAY(Char, jcharArray, char)
2961 JNI_NEW_ARRAY(Short, jshortArray, byte)
2962 JNI_NEW_ARRAY(Int, jintArray, int)
2963 JNI_NEW_ARRAY(Long, jlongArray, long)
2964 JNI_NEW_ARRAY(Float, jfloatArray, float)
2965 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2968 /* Get<PrimitiveType>ArrayElements *********************************************
2970 A family of functions that returns the body of the primitive array.
2972 *******************************************************************************/
2974 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2975 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2978 java_handle_##intern##array_t *a; \
2980 STATISTICS(jniinvokation()); \
2982 a = (java_handle_##intern##array_t *) array; \
2985 *isCopy = JNI_FALSE; \
2987 return (type *) LLNI_array_data(a); \
2990 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2991 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2992 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2993 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2994 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2995 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2996 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2997 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
3000 /* Release<PrimitiveType>ArrayElements *****************************************
3002 A family of functions that informs the VM that the native code no
3003 longer needs access to elems. The elems argument is a pointer
3004 derived from array using the corresponding
3005 Get<PrimitiveType>ArrayElements() function. If necessary, this
3006 function copies back all changes made to elems to the original
3009 *******************************************************************************/
3011 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
3012 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
3013 type *elems, jint mode) \
3015 java_handle_##intern##array_t *a; \
3017 STATISTICS(jniinvokation()); \
3019 a = (java_handle_##intern##array_t *) array; \
3021 if (elems != (type *) LLNI_array_data(a)) { \
3024 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3027 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3028 /* XXX TWISTI how should it be freed? */ \
3031 /* XXX TWISTI how should it be freed? */ \
3037 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3038 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3039 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3040 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3041 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3042 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3043 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3044 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3047 /* Get<PrimitiveType>ArrayRegion **********************************************
3049 A family of functions that copies a region of a primitive array
3052 *******************************************************************************/
3054 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3055 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3056 jsize start, jsize len, type *buf) \
3058 java_handle_##intern##array_t *a; \
3060 STATISTICS(jniinvokation()); \
3062 a = (java_handle_##intern##array_t *) array; \
3064 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3065 exceptions_throw_arrayindexoutofboundsexception(); \
3067 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3070 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3071 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3072 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3073 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3074 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3075 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3076 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3077 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3080 /* Set<PrimitiveType>ArrayRegion **********************************************
3082 A family of functions that copies back a region of a primitive
3083 array from a buffer.
3085 *******************************************************************************/
3087 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3088 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3089 jsize start, jsize len, const type *buf) \
3091 java_handle_##intern##array_t *a; \
3093 STATISTICS(jniinvokation()); \
3095 a = (java_handle_##intern##array_t *) array; \
3097 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3098 exceptions_throw_arrayindexoutofboundsexception(); \
3100 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3103 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3104 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3105 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3106 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3107 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3108 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3109 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3110 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3113 /* Registering Native Methods *************************************************/
3115 /* RegisterNatives *************************************************************
3117 Registers native methods with the class specified by the clazz
3118 argument. The methods parameter specifies an array of
3119 JNINativeMethod structures that contain the names, signatures, and
3120 function pointers of the native methods. The nMethods parameter
3121 specifies the number of native methods in the array.
3123 *******************************************************************************/
3125 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3126 const JNINativeMethod *methods, jint nMethods)
3130 STATISTICS(jniinvokation());
3132 c = LLNI_classinfo_unwrap(clazz);
3134 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3135 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3138 native_method_register(c->name, methods, nMethods);
3144 /* UnregisterNatives ***********************************************************
3146 Unregisters native methods of a class. The class goes back to the
3147 state before it was linked or registered with its native method
3150 This function should not be used in normal native code. Instead, it
3151 provides special programs a way to reload and relink native
3154 *******************************************************************************/
3156 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3158 STATISTICS(jniinvokation());
3160 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3162 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3168 /* Monitor Operations *********************************************************/
3170 /* MonitorEnter ****************************************************************
3172 Enters the monitor associated with the underlying Java object
3175 *******************************************************************************/
3177 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3179 STATISTICS(jniinvokation());
3182 exceptions_throw_nullpointerexception();
3186 LOCK_MONITOR_ENTER(obj);
3192 /* MonitorExit *****************************************************************
3194 The current thread must be the owner of the monitor associated with
3195 the underlying Java object referred to by obj. The thread
3196 decrements the counter indicating the number of times it has
3197 entered this monitor. If the value of the counter becomes zero, the
3198 current thread releases the monitor.
3200 *******************************************************************************/
3202 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3204 STATISTICS(jniinvokation());
3207 exceptions_throw_nullpointerexception();
3211 LOCK_MONITOR_EXIT(obj);
3217 /* JavaVM Interface ***********************************************************/
3219 /* GetJavaVM *******************************************************************
3221 Returns the Java VM interface (used in the Invocation API)
3222 associated with the current thread. The result is placed at the
3223 location pointed to by the second argument, vm.
3225 *******************************************************************************/
3227 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3229 STATISTICS(jniinvokation());
3231 *vm = (JavaVM *) _Jv_jvm;
3237 /* GetStringRegion *************************************************************
3239 Copies len number of Unicode characters beginning at offset start
3240 to the given buffer buf.
3242 Throws StringIndexOutOfBoundsException on index overflow.
3244 *******************************************************************************/
3246 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3249 java_lang_String *s;
3250 java_handle_chararray_t *ca;
3252 STATISTICS(jniinvokation());
3254 s = (java_lang_String *) str;
3255 LLNI_field_get_ref(s, value, ca);
3257 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3258 (start + len > LLNI_field_direct(s, count))) {
3259 exceptions_throw_stringindexoutofboundsexception();
3263 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3267 /* GetStringUTFRegion **********************************************************
3269 Translates len number of Unicode characters beginning at offset
3270 start into UTF-8 format and place the result in the given buffer
3273 Throws StringIndexOutOfBoundsException on index overflow.
3275 *******************************************************************************/
3277 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3278 jsize len, char *buf)
3280 java_lang_String *s;
3281 java_handle_chararray_t *ca;
3286 TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
3288 s = (java_lang_String *) str;
3289 LLNI_field_get_ref(s, value, ca);
3290 LLNI_field_get_val(s, count, count);
3291 LLNI_field_get_val(s, offset, offset);
3293 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3294 exceptions_throw_stringindexoutofboundsexception();
3298 for (i = 0; i < len; i++)
3299 buf[i] = LLNI_array_direct(ca, offset + start + i);
3305 /* GetPrimitiveArrayCritical ***************************************************
3307 Obtain a direct pointer to array elements.
3309 *******************************************************************************/
3311 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3314 java_handle_bytearray_t *ba;
3317 ba = (java_handle_bytearray_t *) array;
3319 /* do the same as Kaffe does */
3321 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3327 /* ReleasePrimitiveArrayCritical ***********************************************
3329 No specific documentation.
3331 *******************************************************************************/
3333 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3334 void *carray, jint mode)
3336 STATISTICS(jniinvokation());
3338 /* do the same as Kaffe does */
3340 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3345 /* GetStringCritical ***********************************************************
3347 The semantics of these two functions are similar to the existing
3348 Get/ReleaseStringChars functions.
3350 *******************************************************************************/
3352 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3355 STATISTICS(jniinvokation());
3357 return _Jv_JNI_GetStringChars(env, string, isCopy);
3361 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3362 const jchar *cstring)
3364 STATISTICS(jniinvokation());
3366 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3370 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3372 TRACEJNICALLS("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj);
3378 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3380 TRACEJNICALLS("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref);
3384 /* NewGlobalRef ****************************************************************
3386 Creates a new global reference to the object referred to by the obj
3389 *******************************************************************************/
3391 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3393 hashtable_global_ref_entry *gre;
3394 u4 key; /* hashkey */
3395 u4 slot; /* slot in hashtable */
3398 STATISTICS(jniinvokation());
3400 o = (java_handle_t *) obj;
3402 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3404 LLNI_CRITICAL_START;
3406 /* normally addresses are aligned to 4, 8 or 16 bytes */
3408 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3409 slot = key & (hashtable_global_ref->size - 1);
3410 gre = hashtable_global_ref->ptr[slot];
3412 /* search external hash chain for the entry */
3415 if (gre->o == LLNI_DIRECT(o)) {
3416 /* global object found, increment the reference */
3423 gre = gre->hashlink; /* next element in external chain */
3428 /* global ref not found, create a new one */
3431 gre = NEW(hashtable_global_ref_entry);
3433 #if defined(ENABLE_GC_CACAO)
3434 /* register global ref with the GC */
3436 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3439 LLNI_CRITICAL_START;
3441 gre->o = LLNI_DIRECT(o);
3446 /* insert entry into hashtable */
3448 gre->hashlink = hashtable_global_ref->ptr[slot];
3450 hashtable_global_ref->ptr[slot] = gre;
3452 /* update number of hashtable-entries */
3454 hashtable_global_ref->entries++;
3457 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3459 #if defined(ENABLE_HANDLES)
3467 /* DeleteGlobalRef *************************************************************
3469 Deletes the global reference pointed to by globalRef.
3471 *******************************************************************************/
3473 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3475 hashtable_global_ref_entry *gre;
3476 hashtable_global_ref_entry *prevgre;
3477 u4 key; /* hashkey */
3478 u4 slot; /* slot in hashtable */
3481 STATISTICS(jniinvokation());
3483 o = (java_handle_t *) globalRef;
3485 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3487 LLNI_CRITICAL_START;
3489 /* normally addresses are aligned to 4, 8 or 16 bytes */
3491 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3492 slot = key & (hashtable_global_ref->size - 1);
3493 gre = hashtable_global_ref->ptr[slot];
3495 /* initialize prevgre */
3499 /* search external hash chain for the entry */
3502 if (gre->o == LLNI_DIRECT(o)) {
3503 /* global object found, decrement the reference count */
3507 /* if reference count is 0, remove the entry */
3509 if (gre->refs == 0) {
3510 /* special handling if it's the first in the chain */
3512 if (prevgre == NULL)
3513 hashtable_global_ref->ptr[slot] = gre->hashlink;
3515 prevgre->hashlink = gre->hashlink;
3517 #if defined(ENABLE_GC_CACAO)
3518 /* unregister global ref with the GC */
3520 gc_reference_unregister(&(gre->o));
3523 FREE(gre, hashtable_global_ref_entry);
3528 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3533 prevgre = gre; /* save current pointer for removal */
3534 gre = gre->hashlink; /* next element in external chain */
3537 log_println("JNI-DeleteGlobalRef: global reference not found");
3541 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3545 /* ExceptionCheck **************************************************************
3547 Returns JNI_TRUE when there is a pending exception; otherwise,
3550 *******************************************************************************/
3552 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3556 STATISTICS(jniinvokation());
3558 o = exceptions_get_exception();
3560 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3564 /* New JNI 1.4 functions ******************************************************/
3566 /* NewDirectByteBuffer *********************************************************
3568 Allocates and returns a direct java.nio.ByteBuffer referring to the
3569 block of memory starting at the memory address address and
3570 extending capacity bytes.
3572 *******************************************************************************/
3574 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3576 #if defined(ENABLE_JAVASE)
3577 # if defined(WITH_CLASSPATH_GNU)
3578 java_handle_t *nbuf;
3580 # if SIZEOF_VOID_P == 8
3581 gnu_classpath_Pointer64 *paddress;
3583 gnu_classpath_Pointer32 *paddress;
3586 TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3588 /* alocate a gnu.classpath.Pointer{32,64} object */
3590 # if SIZEOF_VOID_P == 8
3591 if (!(paddress = (gnu_classpath_Pointer64 *)
3592 builtin_new(class_gnu_classpath_Pointer64)))
3594 if (!(paddress = (gnu_classpath_Pointer32 *)
3595 builtin_new(class_gnu_classpath_Pointer32)))
3599 /* fill gnu.classpath.Pointer{32,64} with address */
3601 LLNI_field_set_val(paddress, data, (ptrint) address);
3603 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3605 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3606 (jmethodID) dbbirw_init, NULL, paddress,
3607 (jint) capacity, (jint) capacity, (jint) 0);
3609 /* add local reference and return the value */
3611 return _Jv_JNI_NewLocalRef(env, nbuf);
3613 # elif defined(WITH_CLASSPATH_SUN)
3619 TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3621 /* Be paranoid about address sign-extension. */
3623 addr = (int64_t) ((uintptr_t) address);
3624 cap = (int32_t) capacity;
3626 o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3627 (jmethodID) dbb_init, addr, cap);
3629 /* Add local reference and return the value. */
3631 return _Jv_JNI_NewLocalRef(env, o);
3634 # error unknown classpath configuration
3638 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3640 /* keep compiler happy */
3647 /* GetDirectBufferAddress ******************************************************
3649 Fetches and returns the starting address of the memory region
3650 referenced by the given direct java.nio.Buffer.
3652 *******************************************************************************/
3654 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3656 #if defined(ENABLE_JAVASE)
3657 # if defined(WITH_CLASSPATH_GNU)
3659 java_nio_DirectByteBufferImpl *nbuf;
3660 # if SIZEOF_VOID_P == 8
3661 gnu_classpath_Pointer64 *paddress;
3663 gnu_classpath_Pointer32 *paddress;
3667 TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3669 if ((buf != NULL) && !builtin_instanceof(buf, class_java_nio_Buffer))
3672 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3674 LLNI_field_get_ref(nbuf, address, paddress);
3676 if (paddress == NULL)
3679 LLNI_field_get_val(paddress, data, address);
3680 /* this was the cast to avaoid warning: (void *) paddress->data */
3684 # elif defined(WITH_CLASSPATH_SUN)
3690 TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3692 if ((buf != NULL) && !builtin_instanceof(buf, class_sun_nio_ch_DirectBuffer))
3695 o = (java_nio_Buffer *) buf;
3697 LLNI_field_get_val(o, address, address);
3699 p = (void *) (intptr_t) address;
3704 # error unknown classpath configuration
3709 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3711 /* keep compiler happy */
3719 /* GetDirectBufferCapacity *****************************************************
3721 Fetches and returns the capacity in bytes of the memory region
3722 referenced by the given direct java.nio.Buffer.
3724 *******************************************************************************/
3726 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3728 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3730 java_nio_Buffer *nbuf;
3733 STATISTICS(jniinvokation());
3735 o = (java_handle_t *) buf;
3737 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3740 nbuf = (java_nio_Buffer *) o;
3742 LLNI_field_get_val(nbuf, cap, capacity);
3746 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3748 /* keep compiler happy */
3755 /* GetObjectRefType ************************************************************
3757 Returns the type of the object referred to by the obj argument. The
3758 argument obj can either be a local, global or weak global
3761 *******************************************************************************/
3763 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3765 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3771 /* DestroyJavaVM ***************************************************************
3773 Unloads a Java VM and reclaims its resources. Only the main thread
3774 can unload the VM. The system waits until the main thread is only
3775 remaining user thread before it destroys the VM.
3777 *******************************************************************************/
3779 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3783 TRACEJNICALLS("_Jv_JNI_DestroyJavaVM(vm=%p)", vm);
3785 status = vm_destroy(vm);
3791 /* AttachCurrentThread *********************************************************
3793 Attaches the current thread to a Java VM. Returns a JNI interface
3794 pointer in the JNIEnv argument.
3796 Trying to attach a thread that is already attached is a no-op.
3798 A native thread cannot be attached simultaneously to two Java VMs.
3800 When a thread is attached to the VM, the context class loader is
3801 the bootstrap loader.
3803 *******************************************************************************/
3805 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3807 JavaVMAttachArgs *vm_aargs;
3809 #if defined(ENABLE_THREADS)
3810 if (threads_get_current_threadobject() == NULL) {
3811 vm_aargs = (JavaVMAttachArgs *) thr_args;
3813 if (vm_aargs != NULL) {
3814 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3815 (vm_aargs->version != JNI_VERSION_1_4))
3816 return JNI_EVERSION;
3819 if (!threads_attach_current_thread(vm_aargs, false))
3822 if (!localref_table_init())
3833 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3835 STATISTICS(jniinvokation());
3837 return jni_attach_current_thread(p_env, thr_args, false);
3841 /* DetachCurrentThread *********************************************************
3843 Detaches the current thread from a Java VM. All Java monitors held
3844 by this thread are released. All Java threads waiting for this
3845 thread to die are notified.
3847 In JDK 1.1, the main thread cannot be detached from the VM. It must
3848 call DestroyJavaVM to unload the entire VM.
3850 In the JDK, the main thread can be detached from the VM.
3852 The main thread, which is the thread that created the Java VM,
3853 cannot be detached from the VM. Instead, the main thread must call
3854 JNI_DestroyJavaVM() to unload the entire VM.
3856 *******************************************************************************/
3858 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3860 #if defined(ENABLE_THREADS)
3861 threadobject *thread;
3863 STATISTICS(jniinvokation());
3865 thread = threads_get_current_threadobject();
3870 /* We need to pop all frames before we can destroy the table. */
3872 localref_frame_pop_all();
3874 if (!localref_table_destroy())
3877 if (!threads_detach_thread(thread))
3885 /* GetEnv **********************************************************************
3887 If the current thread is not attached to the VM, sets *env to NULL,
3888 and returns JNI_EDETACHED. If the specified version is not
3889 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3890 sets *env to the appropriate interface, and returns JNI_OK.
3892 *******************************************************************************/
3894 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3896 TRACEJNICALLS("_Jv_JNI_GetEnv(vm=%p, env=%p, %d=version)", vm, env, version);
3898 #if defined(ENABLE_THREADS)
3899 if (threads_get_current_threadobject() == NULL) {
3902 return JNI_EDETACHED;
3906 /* Check the JNI version. */
3908 if (jni_version_check(version) == true) {
3913 #if defined(ENABLE_JVMTI)
3914 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3915 == JVMTI_VERSION_INTERFACE_JVMTI) {
3917 *env = (void *) jvmti_new_environment();
3926 return JNI_EVERSION;
3930 /* AttachCurrentThreadAsDaemon *************************************************
3932 Same semantics as AttachCurrentThread, but the newly-created
3933 java.lang.Thread instance is a daemon.
3935 If the thread has already been attached via either
3936 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3937 simply sets the value pointed to by penv to the JNIEnv of the
3938 current thread. In this case neither AttachCurrentThread nor this
3939 routine have any effect on the daemon status of the thread.
3941 *******************************************************************************/
3943 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3945 STATISTICS(jniinvokation());
3947 return jni_attach_current_thread(penv, args, true);
3951 /* JNI invocation table *******************************************************/
3953 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3958 _Jv_JNI_DestroyJavaVM,
3959 _Jv_JNI_AttachCurrentThread,
3960 _Jv_JNI_DetachCurrentThread,
3962 _Jv_JNI_AttachCurrentThreadAsDaemon
3966 /* JNI function table *********************************************************/
3968 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3975 _Jv_JNI_DefineClass,
3977 _Jv_JNI_FromReflectedMethod,
3978 _Jv_JNI_FromReflectedField,
3979 _Jv_JNI_ToReflectedMethod,
3980 _Jv_JNI_GetSuperclass,
3981 _Jv_JNI_IsAssignableFrom,
3982 _Jv_JNI_ToReflectedField,
3986 _Jv_JNI_ExceptionOccurred,
3987 _Jv_JNI_ExceptionDescribe,
3988 _Jv_JNI_ExceptionClear,
3990 _Jv_JNI_PushLocalFrame,
3991 _Jv_JNI_PopLocalFrame,
3993 _Jv_JNI_NewGlobalRef,
3994 _Jv_JNI_DeleteGlobalRef,
3995 _Jv_JNI_DeleteLocalRef,
3996 _Jv_JNI_IsSameObject,
3997 _Jv_JNI_NewLocalRef,
3998 _Jv_JNI_EnsureLocalCapacity,
4000 _Jv_JNI_AllocObject,
4005 _Jv_JNI_GetObjectClass,
4006 _Jv_JNI_IsInstanceOf,
4008 _Jv_JNI_GetMethodID,
4010 _Jv_JNI_CallObjectMethod,
4011 _Jv_JNI_CallObjectMethodV,
4012 _Jv_JNI_CallObjectMethodA,
4013 _Jv_JNI_CallBooleanMethod,
4014 _Jv_JNI_CallBooleanMethodV,
4015 _Jv_JNI_CallBooleanMethodA,
4016 _Jv_JNI_CallByteMethod,
4017 _Jv_JNI_CallByteMethodV,
4018 _Jv_JNI_CallByteMethodA,
4019 _Jv_JNI_CallCharMethod,
4020 _Jv_JNI_CallCharMethodV,
4021 _Jv_JNI_CallCharMethodA,
4022 _Jv_JNI_CallShortMethod,
4023 _Jv_JNI_CallShortMethodV,
4024 _Jv_JNI_CallShortMethodA,
4025 _Jv_JNI_CallIntMethod,
4026 _Jv_JNI_CallIntMethodV,
4027 _Jv_JNI_CallIntMethodA,
4028 _Jv_JNI_CallLongMethod,
4029 _Jv_JNI_CallLongMethodV,
4030 _Jv_JNI_CallLongMethodA,
4031 _Jv_JNI_CallFloatMethod,
4032 _Jv_JNI_CallFloatMethodV,
4033 _Jv_JNI_CallFloatMethodA,
4034 _Jv_JNI_CallDoubleMethod,
4035 _Jv_JNI_CallDoubleMethodV,
4036 _Jv_JNI_CallDoubleMethodA,
4037 _Jv_JNI_CallVoidMethod,
4038 _Jv_JNI_CallVoidMethodV,
4039 _Jv_JNI_CallVoidMethodA,
4041 _Jv_JNI_CallNonvirtualObjectMethod,
4042 _Jv_JNI_CallNonvirtualObjectMethodV,
4043 _Jv_JNI_CallNonvirtualObjectMethodA,
4044 _Jv_JNI_CallNonvirtualBooleanMethod,
4045 _Jv_JNI_CallNonvirtualBooleanMethodV,
4046 _Jv_JNI_CallNonvirtualBooleanMethodA,
4047 _Jv_JNI_CallNonvirtualByteMethod,
4048 _Jv_JNI_CallNonvirtualByteMethodV,
4049 _Jv_JNI_CallNonvirtualByteMethodA,
4050 _Jv_JNI_CallNonvirtualCharMethod,
4051 _Jv_JNI_CallNonvirtualCharMethodV,
4052 _Jv_JNI_CallNonvirtualCharMethodA,
4053 _Jv_JNI_CallNonvirtualShortMethod,
4054 _Jv_JNI_CallNonvirtualShortMethodV,
4055 _Jv_JNI_CallNonvirtualShortMethodA,
4056 _Jv_JNI_CallNonvirtualIntMethod,
4057 _Jv_JNI_CallNonvirtualIntMethodV,
4058 _Jv_JNI_CallNonvirtualIntMethodA,
4059 _Jv_JNI_CallNonvirtualLongMethod,
4060 _Jv_JNI_CallNonvirtualLongMethodV,
4061 _Jv_JNI_CallNonvirtualLongMethodA,
4062 _Jv_JNI_CallNonvirtualFloatMethod,
4063 _Jv_JNI_CallNonvirtualFloatMethodV,
4064 _Jv_JNI_CallNonvirtualFloatMethodA,
4065 _Jv_JNI_CallNonvirtualDoubleMethod,
4066 _Jv_JNI_CallNonvirtualDoubleMethodV,
4067 _Jv_JNI_CallNonvirtualDoubleMethodA,
4068 _Jv_JNI_CallNonvirtualVoidMethod,
4069 _Jv_JNI_CallNonvirtualVoidMethodV,
4070 _Jv_JNI_CallNonvirtualVoidMethodA,
4074 _Jv_JNI_GetObjectField,
4075 _Jv_JNI_GetBooleanField,
4076 _Jv_JNI_GetByteField,
4077 _Jv_JNI_GetCharField,
4078 _Jv_JNI_GetShortField,
4079 _Jv_JNI_GetIntField,
4080 _Jv_JNI_GetLongField,
4081 _Jv_JNI_GetFloatField,
4082 _Jv_JNI_GetDoubleField,
4083 _Jv_JNI_SetObjectField,
4084 _Jv_JNI_SetBooleanField,
4085 _Jv_JNI_SetByteField,
4086 _Jv_JNI_SetCharField,
4087 _Jv_JNI_SetShortField,
4088 _Jv_JNI_SetIntField,
4089 _Jv_JNI_SetLongField,
4090 _Jv_JNI_SetFloatField,
4091 _Jv_JNI_SetDoubleField,
4093 _Jv_JNI_GetStaticMethodID,
4095 _Jv_JNI_CallStaticObjectMethod,
4096 _Jv_JNI_CallStaticObjectMethodV,
4097 _Jv_JNI_CallStaticObjectMethodA,
4098 _Jv_JNI_CallStaticBooleanMethod,
4099 _Jv_JNI_CallStaticBooleanMethodV,
4100 _Jv_JNI_CallStaticBooleanMethodA,
4101 _Jv_JNI_CallStaticByteMethod,
4102 _Jv_JNI_CallStaticByteMethodV,
4103 _Jv_JNI_CallStaticByteMethodA,
4104 _Jv_JNI_CallStaticCharMethod,
4105 _Jv_JNI_CallStaticCharMethodV,
4106 _Jv_JNI_CallStaticCharMethodA,
4107 _Jv_JNI_CallStaticShortMethod,
4108 _Jv_JNI_CallStaticShortMethodV,
4109 _Jv_JNI_CallStaticShortMethodA,
4110 _Jv_JNI_CallStaticIntMethod,
4111 _Jv_JNI_CallStaticIntMethodV,
4112 _Jv_JNI_CallStaticIntMethodA,
4113 _Jv_JNI_CallStaticLongMethod,
4114 _Jv_JNI_CallStaticLongMethodV,
4115 _Jv_JNI_CallStaticLongMethodA,
4116 _Jv_JNI_CallStaticFloatMethod,
4117 _Jv_JNI_CallStaticFloatMethodV,
4118 _Jv_JNI_CallStaticFloatMethodA,
4119 _Jv_JNI_CallStaticDoubleMethod,
4120 _Jv_JNI_CallStaticDoubleMethodV,
4121 _Jv_JNI_CallStaticDoubleMethodA,
4122 _Jv_JNI_CallStaticVoidMethod,
4123 _Jv_JNI_CallStaticVoidMethodV,
4124 _Jv_JNI_CallStaticVoidMethodA,
4126 _Jv_JNI_GetStaticFieldID,
4128 _Jv_JNI_GetStaticObjectField,
4129 _Jv_JNI_GetStaticBooleanField,
4130 _Jv_JNI_GetStaticByteField,
4131 _Jv_JNI_GetStaticCharField,
4132 _Jv_JNI_GetStaticShortField,
4133 _Jv_JNI_GetStaticIntField,
4134 _Jv_JNI_GetStaticLongField,
4135 _Jv_JNI_GetStaticFloatField,
4136 _Jv_JNI_GetStaticDoubleField,
4137 _Jv_JNI_SetStaticObjectField,
4138 _Jv_JNI_SetStaticBooleanField,
4139 _Jv_JNI_SetStaticByteField,
4140 _Jv_JNI_SetStaticCharField,
4141 _Jv_JNI_SetStaticShortField,
4142 _Jv_JNI_SetStaticIntField,
4143 _Jv_JNI_SetStaticLongField,
4144 _Jv_JNI_SetStaticFloatField,
4145 _Jv_JNI_SetStaticDoubleField,
4148 _Jv_JNI_GetStringLength,
4149 _Jv_JNI_GetStringChars,
4150 _Jv_JNI_ReleaseStringChars,
4152 _Jv_JNI_NewStringUTF,
4153 _Jv_JNI_GetStringUTFLength,
4154 _Jv_JNI_GetStringUTFChars,
4155 _Jv_JNI_ReleaseStringUTFChars,
4157 _Jv_JNI_GetArrayLength,
4159 _Jv_JNI_NewObjectArray,
4160 _Jv_JNI_GetObjectArrayElement,
4161 _Jv_JNI_SetObjectArrayElement,
4163 _Jv_JNI_NewBooleanArray,
4164 _Jv_JNI_NewByteArray,
4165 _Jv_JNI_NewCharArray,
4166 _Jv_JNI_NewShortArray,
4167 _Jv_JNI_NewIntArray,
4168 _Jv_JNI_NewLongArray,
4169 _Jv_JNI_NewFloatArray,
4170 _Jv_JNI_NewDoubleArray,
4172 _Jv_JNI_GetBooleanArrayElements,
4173 _Jv_JNI_GetByteArrayElements,
4174 _Jv_JNI_GetCharArrayElements,
4175 _Jv_JNI_GetShortArrayElements,
4176 _Jv_JNI_GetIntArrayElements,
4177 _Jv_JNI_GetLongArrayElements,
4178 _Jv_JNI_GetFloatArrayElements,
4179 _Jv_JNI_GetDoubleArrayElements,
4181 _Jv_JNI_ReleaseBooleanArrayElements,
4182 _Jv_JNI_ReleaseByteArrayElements,
4183 _Jv_JNI_ReleaseCharArrayElements,
4184 _Jv_JNI_ReleaseShortArrayElements,
4185 _Jv_JNI_ReleaseIntArrayElements,
4186 _Jv_JNI_ReleaseLongArrayElements,
4187 _Jv_JNI_ReleaseFloatArrayElements,
4188 _Jv_JNI_ReleaseDoubleArrayElements,
4190 _Jv_JNI_GetBooleanArrayRegion,
4191 _Jv_JNI_GetByteArrayRegion,
4192 _Jv_JNI_GetCharArrayRegion,
4193 _Jv_JNI_GetShortArrayRegion,
4194 _Jv_JNI_GetIntArrayRegion,
4195 _Jv_JNI_GetLongArrayRegion,
4196 _Jv_JNI_GetFloatArrayRegion,
4197 _Jv_JNI_GetDoubleArrayRegion,
4198 _Jv_JNI_SetBooleanArrayRegion,
4199 _Jv_JNI_SetByteArrayRegion,
4200 _Jv_JNI_SetCharArrayRegion,
4201 _Jv_JNI_SetShortArrayRegion,
4202 _Jv_JNI_SetIntArrayRegion,
4203 _Jv_JNI_SetLongArrayRegion,
4204 _Jv_JNI_SetFloatArrayRegion,
4205 _Jv_JNI_SetDoubleArrayRegion,
4207 _Jv_JNI_RegisterNatives,
4208 _Jv_JNI_UnregisterNatives,
4210 _Jv_JNI_MonitorEnter,
4211 _Jv_JNI_MonitorExit,
4215 /* New JNI 1.2 functions. */
4217 _Jv_JNI_GetStringRegion,
4218 _Jv_JNI_GetStringUTFRegion,
4220 _Jv_JNI_GetPrimitiveArrayCritical,
4221 _Jv_JNI_ReleasePrimitiveArrayCritical,
4223 _Jv_JNI_GetStringCritical,
4224 _Jv_JNI_ReleaseStringCritical,
4226 _Jv_JNI_NewWeakGlobalRef,
4227 _Jv_JNI_DeleteWeakGlobalRef,
4229 _Jv_JNI_ExceptionCheck,
4231 /* New JNI 1.4 functions. */
4233 _Jv_JNI_NewDirectByteBuffer,
4234 _Jv_JNI_GetDirectBufferAddress,
4235 _Jv_JNI_GetDirectBufferCapacity,
4237 /* New JNI 1.6 functions. */
4239 jni_GetObjectRefType
4243 /* Invocation API Functions ***************************************************/
4245 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4247 Returns a default configuration for the Java VM.
4249 *******************************************************************************/
4251 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4253 JavaVMInitArgs *_vm_args;
4255 _vm_args = (JavaVMInitArgs *) vm_args;
4257 /* GNU classpath currently supports JNI 1.2 */
4259 switch (_vm_args->version) {
4260 case JNI_VERSION_1_1:
4261 _vm_args->version = JNI_VERSION_1_1;
4264 case JNI_VERSION_1_2:
4265 case JNI_VERSION_1_4:
4266 _vm_args->ignoreUnrecognized = JNI_FALSE;
4267 _vm_args->options = NULL;
4268 _vm_args->nOptions = 0;
4279 /* JNI_GetCreatedJavaVMs *******************************************************
4281 Returns all Java VMs that have been created. Pointers to VMs are written in
4282 the buffer vmBuf in the order they are created. At most bufLen number of
4283 entries will be written. The total number of created VMs is returned in
4286 *******************************************************************************/
4288 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4290 TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
4295 /* We currently only support 1 VM running. */
4297 vmBuf[0] = (JavaVM *) _Jv_jvm;
4304 /* JNI_CreateJavaVM ************************************************************
4306 Loads and initializes a Java VM. The current thread becomes the main thread.
4307 Sets the env argument to the JNI interface pointer of the main thread.
4309 *******************************************************************************/
4311 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4313 TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
4315 /* actually create the JVM */
4317 if (!vm_createjvm(p_vm, p_env, vm_args))
4325 * These are local overrides for various environment variables in Emacs.
4326 * Please do not remove this and leave it at the end of the file, where
4327 * Emacs will automagically detect them.
4328 * ---------------------------------------------------------------------
4331 * indent-tabs-mode: t
4335 * vim:noexpandtab:sw=4:ts=4: