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
25 $Id: jni.c 8390 2007-08-21 19:22:16Z michi $
38 #include "mm/gc-common.h"
39 #include "mm/memory.h"
41 #include "native/jni.h"
42 #include "native/llni.h"
43 #include "native/localref.h"
44 #include "native/native.h"
46 #if defined(ENABLE_JAVASE)
47 # if defined(WITH_CLASSPATH_GNU)
48 # include "native/include/gnu_classpath_Pointer.h"
50 # if SIZEOF_VOID_P == 8
51 # include "native/include/gnu_classpath_Pointer64.h"
53 # include "native/include/gnu_classpath_Pointer32.h"
58 #include "native/include/java_lang_Object.h"
59 #include "native/include/java_lang_Byte.h"
60 #include "native/include/java_lang_Character.h"
61 #include "native/include/java_lang_Short.h"
62 #include "native/include/java_lang_Integer.h"
63 #include "native/include/java_lang_Boolean.h"
64 #include "native/include/java_lang_Long.h"
65 #include "native/include/java_lang_Float.h"
66 #include "native/include/java_lang_Double.h"
67 #include "native/include/java_lang_String.h"
68 #include "native/include/java_lang_Throwable.h"
70 #if defined(ENABLE_JAVASE)
71 # if defined(WITH_CLASSPATH_SUN)
72 # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
75 # include "native/include/java_lang_ClassLoader.h"
77 # include "native/include/java_lang_reflect_Constructor.h"
78 # include "native/include/java_lang_reflect_Field.h"
79 # include "native/include/java_lang_reflect_Method.h"
81 # include "native/include/java_nio_Buffer.h"
83 # if defined(WITH_CLASSPATH_GNU)
84 # include "native/include/java_nio_DirectByteBufferImpl.h"
88 #if defined(ENABLE_JVMTI)
89 # include "native/jvmti/cacaodbg.h"
92 #include "native/vm/java_lang_Class.h"
94 #if defined(ENABLE_JAVASE)
95 # include "native/vm/java_lang_ClassLoader.h"
96 # include "native/vm/reflect.h"
99 #include "threads/lock-common.h"
100 #include "threads/threads-common.h"
102 #include "toolbox/logging.h"
104 #include "vm/builtin.h"
105 #include "vm/exceptions.h"
106 #include "vm/global.h"
107 #include "vm/initialize.h"
108 #include "vm/primitive.h"
109 #include "vm/resolve.h"
110 #include "vm/stringlocal.h"
113 #include "vm/jit/asmpart.h"
114 #include "vm/jit/jit.h"
115 #include "vm/jit/stacktrace.h"
117 #include "vmcore/loader.h"
118 #include "vmcore/options.h"
119 #include "vmcore/statistics.h"
122 /* debug **********************************************************************/
125 # define TRACEJNICALLS(format, ...) \
127 if (opt_TraceJNICalls) { \
128 log_println((format), __VA_ARGS__); \
132 # define TRACEJNICALLS(format, ...)
136 /* global variables ***********************************************************/
138 /* global reference table *****************************************************/
140 /* hashsize must be power of 2 */
142 #define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
144 static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
147 /* direct buffer stuff ********************************************************/
149 #if defined(ENABLE_JAVASE)
150 static classinfo *class_java_nio_Buffer;
151 static classinfo *class_java_nio_DirectByteBufferImpl;
152 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
154 # if defined(WITH_CLASSPATH_GNU)
155 # if SIZEOF_VOID_P == 8
156 static classinfo *class_gnu_classpath_Pointer64;
158 static classinfo *class_gnu_classpath_Pointer32;
162 static methodinfo *dbbirw_init;
166 /* accessing instance fields macros *******************************************/
168 #define SET_FIELD(o,type,f,value) \
169 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
171 #define GET_FIELD(o,type,f) \
172 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
175 /* some forward declarations **************************************************/
177 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
180 /* jni_init ********************************************************************
182 Initialize the JNI subsystem.
184 *******************************************************************************/
188 /* create global ref hashtable */
190 hashtable_global_ref = NEW(hashtable);
192 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
195 #if defined(ENABLE_JAVASE)
196 /* direct buffer stuff */
198 if (!(class_java_nio_Buffer =
199 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
200 !link_class(class_java_nio_Buffer))
203 # if defined(WITH_CLASSPATH_GNU)
204 if (!(class_java_nio_DirectByteBufferImpl =
205 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
206 !link_class(class_java_nio_DirectByteBufferImpl))
209 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
210 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
211 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
215 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
217 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
220 # if SIZEOF_VOID_P == 8
221 if (!(class_gnu_classpath_Pointer64 =
222 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
223 !link_class(class_gnu_classpath_Pointer64))
226 if (!(class_gnu_classpath_Pointer32 =
227 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
228 !link_class(class_gnu_classpath_Pointer32))
232 #endif /* defined(ENABLE_JAVASE) */
238 /* _Jv_jni_CallObjectMethod ****************************************************
240 Internal function to call Java Object methods.
242 *******************************************************************************/
244 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
246 methodinfo *m, va_list ap)
251 STATISTICS(jniinvokation());
254 exceptions_throw_nullpointerexception();
258 /* Class initialization is done by the JIT compiler. This is ok
259 since a static method always belongs to the declaring class. */
261 if (m->flags & ACC_STATIC) {
262 /* For static methods we reset the object. */
267 /* for convenience */
272 /* For instance methods we make a virtual function table lookup. */
274 resm = method_vftbl_lookup(vftbl, m);
277 STATISTICS(jnicallXmethodnvokation());
279 ro = vm_call_method_valist(resm, o, ap);
285 /* _Jv_jni_CallObjectMethodA ***************************************************
287 Internal function to call Java Object methods.
289 *******************************************************************************/
291 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
299 STATISTICS(jniinvokation());
302 exceptions_throw_nullpointerexception();
306 /* Class initialization is done by the JIT compiler. This is ok
307 since a static method always belongs to the declaring class. */
309 if (m->flags & ACC_STATIC) {
310 /* For static methods we reset the object. */
315 /* for convenience */
320 /* For instance methods we make a virtual function table lookup. */
322 resm = method_vftbl_lookup(vftbl, m);
325 STATISTICS(jnicallXmethodnvokation());
327 ro = vm_call_method_jvalue(resm, o, args);
333 /* _Jv_jni_CallIntMethod *******************************************************
335 Internal function to call Java integer class methods (boolean,
336 byte, char, short, int).
338 *******************************************************************************/
340 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
341 methodinfo *m, va_list ap)
346 STATISTICS(jniinvokation());
349 exceptions_throw_nullpointerexception();
353 /* Class initialization is done by the JIT compiler. This is ok
354 since a static method always belongs to the declaring class. */
356 if (m->flags & ACC_STATIC) {
357 /* For static methods we reset the object. */
362 /* for convenience */
367 /* For instance methods we make a virtual function table lookup. */
369 resm = method_vftbl_lookup(vftbl, m);
372 STATISTICS(jnicallXmethodnvokation());
374 i = vm_call_method_int_valist(resm, o, ap);
380 /* _Jv_jni_CallIntMethodA ******************************************************
382 Internal function to call Java integer class methods (boolean,
383 byte, char, short, int).
385 *******************************************************************************/
387 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
388 methodinfo *m, const jvalue *args)
393 STATISTICS(jniinvokation());
396 exceptions_throw_nullpointerexception();
400 /* Class initialization is done by the JIT compiler. This is ok
401 since a static method always belongs to the declaring class. */
403 if (m->flags & ACC_STATIC) {
404 /* For static methods we reset the object. */
409 /* for convenience */
414 /* For instance methods we make a virtual function table lookup. */
416 resm = method_vftbl_lookup(vftbl, m);
419 STATISTICS(jnicallXmethodnvokation());
421 i = vm_call_method_int_jvalue(resm, o, args);
427 /* _Jv_jni_CallLongMethod ******************************************************
429 Internal function to call Java long methods.
431 *******************************************************************************/
433 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
434 methodinfo *m, va_list ap)
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 l = vm_call_method_long_valist(resm, o, ap);
473 /* _Jv_jni_CallLongMethodA *****************************************************
475 Internal function to call Java long methods.
477 *******************************************************************************/
479 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
480 methodinfo *m, const jvalue *args)
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_jvalue(resm, o, args);
519 /* _Jv_jni_CallFloatMethod *****************************************************
521 Internal function to call Java float methods.
523 *******************************************************************************/
525 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
526 methodinfo *m, va_list ap)
531 /* Class initialization is done by the JIT compiler. This is ok
532 since a static method always belongs to the declaring class. */
534 if (m->flags & ACC_STATIC) {
535 /* For static methods we reset the object. */
540 /* for convenience */
545 /* For instance methods we make a virtual function table lookup. */
547 resm = method_vftbl_lookup(vftbl, m);
550 STATISTICS(jnicallXmethodnvokation());
552 f = vm_call_method_float_valist(resm, o, ap);
558 /* _Jv_jni_CallFloatMethodA ****************************************************
560 Internal function to call Java float methods.
562 *******************************************************************************/
564 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
565 methodinfo *m, const jvalue *args)
570 /* Class initialization is done by the JIT compiler. This is ok
571 since a static method always belongs to the declaring class. */
573 if (m->flags & ACC_STATIC) {
574 /* For static methods we reset the object. */
579 /* for convenience */
584 /* For instance methods we make a virtual function table lookup. */
586 resm = method_vftbl_lookup(vftbl, m);
589 STATISTICS(jnicallXmethodnvokation());
591 f = vm_call_method_float_jvalue(resm, o, args);
597 /* _Jv_jni_CallDoubleMethod ****************************************************
599 Internal function to call Java double methods.
601 *******************************************************************************/
603 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
604 methodinfo *m, va_list ap)
609 /* Class initialization is done by the JIT compiler. This is ok
610 since a static method always belongs to the declaring class. */
612 if (m->flags & ACC_STATIC) {
613 /* For static methods we reset the object. */
618 /* for convenience */
623 /* For instance methods we make a virtual function table lookup. */
625 resm = method_vftbl_lookup(vftbl, m);
628 d = vm_call_method_double_valist(resm, o, ap);
634 /* _Jv_jni_CallDoubleMethodA ***************************************************
636 Internal function to call Java double methods.
638 *******************************************************************************/
640 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
641 methodinfo *m, const jvalue *args)
646 /* Class initialization is done by the JIT compiler. This is ok
647 since a static method always belongs to the declaring class. */
649 if (m->flags & ACC_STATIC) {
650 /* For static methods we reset the object. */
655 /* for convenience */
660 /* For instance methods we make a virtual function table lookup. */
662 resm = method_vftbl_lookup(vftbl, m);
665 d = vm_call_method_double_jvalue(resm, o, args);
671 /* _Jv_jni_CallVoidMethod ******************************************************
673 Internal function to call Java void methods.
675 *******************************************************************************/
677 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
678 methodinfo *m, va_list ap)
683 exceptions_throw_nullpointerexception();
687 /* Class initialization is done by the JIT compiler. This is ok
688 since a static method always belongs to the declaring class. */
690 if (m->flags & ACC_STATIC) {
691 /* For static methods we reset the object. */
696 /* for convenience */
701 /* For instance methods we make a virtual function table lookup. */
703 resm = method_vftbl_lookup(vftbl, m);
706 STATISTICS(jnicallXmethodnvokation());
708 (void) vm_call_method_valist(resm, o, ap);
712 /* _Jv_jni_CallVoidMethodA *****************************************************
714 Internal function to call Java void methods.
716 *******************************************************************************/
718 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
719 methodinfo *m, const jvalue *args)
724 exceptions_throw_nullpointerexception();
728 /* Class initialization is done by the JIT compiler. This is ok
729 since a static method always belongs to the declaring class. */
731 if (m->flags & ACC_STATIC) {
732 /* For static methods we reset the object. */
737 /* for convenience */
742 /* For instance methods we make a virtual function table lookup. */
744 resm = method_vftbl_lookup(vftbl, m);
747 STATISTICS(jnicallXmethodnvokation());
749 (void) vm_call_method_jvalue(resm, o, args);
753 /* _Jv_jni_invokeNative ********************************************************
755 Invoke a method on the given object with the given arguments.
757 For instance methods OBJ must be != NULL and the method is looked up
758 in the vftbl of the object.
760 For static methods, OBJ is ignored.
762 *******************************************************************************/
764 java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
765 java_handle_objectarray_t *params)
777 exceptions_throw_nullpointerexception();
781 argcount = m->parseddesc->paramcount;
782 paramcount = argcount;
784 /* if method is non-static, remove the `this' pointer */
786 if (!(m->flags & ACC_STATIC))
789 /* For instance methods the object has to be an instance of the
790 class the method belongs to. For static methods the obj
791 parameter is ignored. */
793 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
794 exceptions_throw_illegalargumentexception();
798 /* check if we got the right number of arguments */
800 if (((params == NULL) && (paramcount != 0)) ||
801 (params && (LLNI_array_size(params) != paramcount)))
803 exceptions_throw_illegalargumentexception();
807 /* for instance methods we need an object */
809 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
810 /* XXX not sure if that is the correct exception */
811 exceptions_throw_nullpointerexception();
815 /* for static methods, zero object to make subsequent code simpler */
816 if (m->flags & ACC_STATIC)
820 /* for instance methods we must do a vftbl lookup */
821 resm = method_vftbl_lookup(LLNI_vftbl_direct(o), m);
824 /* for static methods, just for convenience */
828 /* mark start of dump memory area */
830 dumpsize = dump_size();
832 /* Fill the argument array from a object-array. */
834 array = vm_array_from_objectarray(resm, o, params);
836 /* The array can be NULL if we don't have any arguments to pass
837 and the architecture does not have any argument registers
838 (e.g. i386). In that case we additionally check for an
841 if ((array == NULL) && (exceptions_get_exception() != NULL)) {
842 /* release dump area */
844 dump_release(dumpsize);
849 switch (resm->parseddesc->returntype.decltype) {
851 (void) vm_call_array(resm, array);
855 case PRIMITIVETYPE_BOOLEAN:
856 case PRIMITIVETYPE_BYTE:
857 case PRIMITIVETYPE_CHAR:
858 case PRIMITIVETYPE_SHORT:
859 case PRIMITIVETYPE_INT:
860 value.i = vm_call_int_array(resm, array);
861 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
864 case PRIMITIVETYPE_LONG:
865 value.l = vm_call_long_array(resm, array);
866 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
869 case PRIMITIVETYPE_FLOAT:
870 value.f = vm_call_float_array(resm, array);
871 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
874 case PRIMITIVETYPE_DOUBLE:
875 value.d = vm_call_double_array(resm, array);
876 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
880 ro = vm_call_array(resm, array);
884 vm_abort("_Jv_jni_invokeNative: invalid return type %d", resm->parseddesc->returntype.decltype);
887 xptr = exceptions_get_exception();
890 /* clear exception pointer, we are calling JIT code again */
892 exceptions_clear_exception();
894 exceptions_throw_invocationtargetexception(xptr);
897 /* release dump area */
899 dump_release(dumpsize);
905 /* GetVersion ******************************************************************
907 Returns the major version number in the higher 16 bits and the
908 minor version number in the lower 16 bits.
910 *******************************************************************************/
912 jint _Jv_JNI_GetVersion(JNIEnv *env)
914 STATISTICS(jniinvokation());
916 /* we support JNI 1.4 */
918 return JNI_VERSION_1_4;
922 /* Class Operations ***********************************************************/
924 /* DefineClass *****************************************************************
926 Loads a class from a buffer of raw class data. The buffer
927 containing the raw class data is not referenced by the VM after the
928 DefineClass call returns, and it may be discarded if desired.
930 *******************************************************************************/
932 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
933 const jbyte *buf, jsize bufLen)
935 #if defined(ENABLE_JAVASE)
941 TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d", env, name, loader, buf, bufLen);
943 u = utf_new_char(name);
944 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
946 c = class_define(u, cl, bufLen, (const uint8_t *) buf);
948 co = LLNI_classinfo_wrap(c);
950 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
952 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
954 /* keep compiler happy */
961 /* FindClass *******************************************************************
963 This function loads a locally-defined class. It searches the
964 directories and zip files specified by the CLASSPATH environment
965 variable for the class with the specified name.
967 *******************************************************************************/
969 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
971 #if defined(ENABLE_JAVASE)
977 STATISTICS(jniinvokation());
979 u = utf_new_char_classname((char *) name);
981 /* Check stacktrace for classloader, if one found use it,
982 otherwise use the system classloader. */
984 /* Quote from the JNI documentation:
986 In the Java 2 Platform, FindClass locates the class loader
987 associated with the current native method. If the native code
988 belongs to a system class, no class loader will be
989 involved. Otherwise, the proper class loader will be invoked to
990 load and link the named class. When FindClass is called through
991 the Invocation Interface, there is no current native method or
992 its associated class loader. In that case, the result of
993 ClassLoader.getBaseClassLoader is used." */
995 cc = stacktrace_getCurrentClass();
998 c = load_class_from_sysloader(u);
1000 c = load_class_from_classloader(u, cc->classloader);
1008 co = LLNI_classinfo_wrap(c);
1010 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1012 vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1014 /* keep compiler happy */
1021 /* GetSuperclass ***************************************************************
1023 If clazz represents any class other than the class Object, then
1024 this function returns the object that represents the superclass of
1025 the class specified by clazz.
1027 *******************************************************************************/
1029 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1033 java_lang_Class *co;
1035 TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
1037 c = LLNI_classinfo_unwrap(sub);
1042 super = class_get_superclass(c);
1044 co = LLNI_classinfo_wrap(super);
1046 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1050 /* IsAssignableFrom ************************************************************
1052 Determines whether an object of sub can be safely cast to sup.
1054 *******************************************************************************/
1056 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1058 java_lang_Class *csup;
1059 java_lang_Class *csub;
1061 csup = (java_lang_Class *) sup;
1062 csub = (java_lang_Class *) sub;
1064 STATISTICS(jniinvokation());
1066 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1070 /* Throw ***********************************************************************
1072 Causes a java.lang.Throwable object to be thrown.
1074 *******************************************************************************/
1076 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1080 STATISTICS(jniinvokation());
1082 o = (java_handle_t *) obj;
1084 exceptions_set_exception(o);
1090 /* ThrowNew ********************************************************************
1092 Constructs an exception object from the specified class with the
1093 message specified by message and causes that exception to be
1096 *******************************************************************************/
1098 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1104 STATISTICS(jniinvokation());
1106 c = LLNI_classinfo_unwrap(clazz);
1109 s = javastring_new_from_utf_string(msg);
1111 /* instantiate exception object */
1113 o = native_new_and_init_string(c, s);
1118 exceptions_set_exception(o);
1124 /* ExceptionOccurred ***********************************************************
1126 Determines if an exception is being thrown. The exception stays
1127 being thrown until either the native code calls ExceptionClear(),
1128 or the Java code handles the exception.
1130 *******************************************************************************/
1132 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1136 STATISTICS(jniinvokation());
1138 o = exceptions_get_exception();
1140 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1144 /* ExceptionDescribe ***********************************************************
1146 Prints an exception and a backtrace of the stack to a system
1147 error-reporting channel, such as stderr. This is a convenience
1148 routine provided for debugging.
1150 *******************************************************************************/
1152 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1158 STATISTICS(jniinvokation());
1160 o = exceptions_get_exception();
1163 /* clear exception, because we are calling jit code again */
1165 exceptions_clear_exception();
1167 /* get printStackTrace method from exception class */
1169 LLNI_class_get(o, c);
1171 m = class_resolveclassmethod(c,
1172 utf_printStackTrace,
1178 /* XXX what should we do? */
1181 /* print the stacktrace */
1183 (void) vm_call_method(m, o);
1188 /* ExceptionClear **************************************************************
1190 Clears any exception that is currently being thrown. If no
1191 exception is currently being thrown, this routine has no effect.
1193 *******************************************************************************/
1195 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1197 STATISTICS(jniinvokation());
1199 exceptions_clear_exception();
1203 /* FatalError ******************************************************************
1205 Raises a fatal error and does not expect the VM to recover. This
1206 function does not return.
1208 *******************************************************************************/
1210 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1212 STATISTICS(jniinvokation());
1214 /* this seems to be the best way */
1216 vm_abort("JNI Fatal error: %s", msg);
1220 /* PushLocalFrame **************************************************************
1222 Creates a new local reference frame, in which at least a given
1223 number of local references can be created.
1225 *******************************************************************************/
1227 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1229 STATISTICS(jniinvokation());
1234 /* add new local reference frame to current table */
1236 if (!localref_frame_push(capacity))
1243 /* PopLocalFrame ***************************************************************
1245 Pops off the current local reference frame, frees all the local
1246 references, and returns a local reference in the previous local
1247 reference frame for the given result object.
1249 *******************************************************************************/
1251 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1253 STATISTICS(jniinvokation());
1255 /* release all current local frames */
1257 localref_frame_pop_all();
1259 /* add local reference and return the value */
1261 return _Jv_JNI_NewLocalRef(env, result);
1265 /* DeleteLocalRef **************************************************************
1267 Deletes the local reference pointed to by localRef.
1269 *******************************************************************************/
1271 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1274 localref_table *lrt;
1277 STATISTICS(jniinvokation());
1279 o = (java_handle_t *) localRef;
1281 /* get local reference table (thread specific) */
1283 lrt = LOCALREFTABLE;
1285 /* go through all local frames */
1287 for (; lrt != NULL; lrt = lrt->prev) {
1289 /* and try to remove the reference */
1291 for (i = 0; i < lrt->capacity; i++) {
1292 if (lrt->refs[i] == o) {
1293 lrt->refs[i] = NULL;
1301 /* this should not happen */
1303 /* if (opt_checkjni) */
1304 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1305 log_text("JNI-DeleteLocalRef: Local ref passed to JNI not found");
1309 /* IsSameObject ****************************************************************
1311 Tests whether two references refer to the same Java object.
1313 *******************************************************************************/
1315 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1321 STATISTICS(jniinvokation());
1323 o1 = (java_handle_t *) ref1;
1324 o2 = (java_handle_t *) ref2;
1326 LLNI_CRITICAL_START;
1328 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1339 /* NewLocalRef *****************************************************************
1341 Creates a new local reference that refers to the same object as ref.
1343 *******************************************************************************/
1345 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1348 java_handle_t *localref;
1350 STATISTICS(jniinvokation());
1355 o = (java_handle_t *) ref;
1357 /* insert the reference */
1359 localref = localref_add(LLNI_DIRECT(o));
1365 /* EnsureLocalCapacity *********************************************************
1367 Ensures that at least a given number of local references can be
1368 created in the current thread
1370 *******************************************************************************/
1372 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1374 localref_table *lrt;
1376 STATISTICS(jniinvokation());
1378 /* get local reference table (thread specific) */
1380 lrt = LOCALREFTABLE;
1382 /* check if capacity elements are available in the local references table */
1384 if ((lrt->used + capacity) > lrt->capacity)
1385 return _Jv_JNI_PushLocalFrame(env, capacity);
1391 /* AllocObject *****************************************************************
1393 Allocates a new Java object without invoking any of the
1394 constructors for the object. Returns a reference to the object.
1396 *******************************************************************************/
1398 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1403 STATISTICS(jniinvokation());
1405 c = LLNI_classinfo_unwrap(clazz);
1407 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1408 exceptions_throw_instantiationexception(c);
1414 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1418 /* NewObject *******************************************************************
1420 Programmers place all arguments that are to be passed to the
1421 constructor immediately following the methodID
1422 argument. NewObject() accepts these arguments and passes them to
1423 the Java method that the programmer wishes to invoke.
1425 *******************************************************************************/
1427 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1434 STATISTICS(jniinvokation());
1436 c = LLNI_classinfo_unwrap(clazz);
1437 m = (methodinfo *) methodID;
1446 /* call constructor */
1448 va_start(ap, methodID);
1449 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1452 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1456 /* NewObjectV ******************************************************************
1458 Programmers place all arguments that are to be passed to the
1459 constructor in an args argument of type va_list that immediately
1460 follows the methodID argument. NewObjectV() accepts these
1461 arguments, and, in turn, passes them to the Java method that the
1462 programmer wishes to invoke.
1464 *******************************************************************************/
1466 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1473 STATISTICS(jniinvokation());
1475 c = LLNI_classinfo_unwrap(clazz);
1476 m = (methodinfo *) methodID;
1485 /* call constructor */
1487 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1489 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1493 /* NewObjectA *****************************************************************
1495 Programmers place all arguments that are to be passed to the
1496 constructor in an args array of jvalues that immediately follows
1497 the methodID argument. NewObjectA() accepts the arguments in this
1498 array, and, in turn, passes them to the Java method that the
1499 programmer wishes to invoke.
1501 *******************************************************************************/
1503 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1510 STATISTICS(jniinvokation());
1512 c = LLNI_classinfo_unwrap(clazz);
1513 m = (methodinfo *) methodID;
1522 /* call constructor */
1524 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1526 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1530 /* GetObjectClass **************************************************************
1532 Returns the class of an object.
1534 *******************************************************************************/
1536 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1540 java_lang_Class *co;
1542 STATISTICS(jniinvokation());
1544 o = (java_handle_t *) obj;
1546 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1549 LLNI_class_get(o, c);
1551 co = LLNI_classinfo_wrap(c);
1553 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1557 /* IsInstanceOf ****************************************************************
1559 Tests whether an object is an instance of a class.
1561 *******************************************************************************/
1563 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1566 java_lang_Object *o;
1568 STATISTICS(jniinvokation());
1570 c = (java_lang_Class *) clazz;
1571 o = (java_lang_Object *) obj;
1573 return _Jv_java_lang_Class_isInstance(c, o);
1577 /* Reflection Support *********************************************************/
1579 /* FromReflectedMethod *********************************************************
1581 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1582 object to a method ID.
1584 *******************************************************************************/
1586 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1588 #if defined(ENABLE_JAVASE)
1594 STATISTICS(jniinvokation());
1596 o = (java_handle_t *) method;
1601 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1602 java_lang_reflect_Method *rm;
1604 rm = (java_lang_reflect_Method *) method;
1605 LLNI_field_get_cls(rm, clazz, c);
1606 LLNI_field_get_val(rm, slot , slot);
1608 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1609 java_lang_reflect_Constructor *rc;
1611 rc = (java_lang_reflect_Constructor *) method;
1612 LLNI_field_get_cls(rc, clazz, c);
1613 LLNI_field_get_val(rc, slot , slot);
1618 m = &(c->methods[slot]);
1620 return (jmethodID) m;
1622 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1624 /* keep compiler happy */
1631 /* FromReflectedField **********************************************************
1633 Converts a java.lang.reflect.Field to a field ID.
1635 *******************************************************************************/
1637 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1639 #if defined(ENABLE_JAVASE)
1640 java_lang_reflect_Field *rf;
1645 STATISTICS(jniinvokation());
1647 rf = (java_lang_reflect_Field *) field;
1652 LLNI_field_get_cls(rf, clazz, c);
1653 LLNI_field_get_val(rf, slot , slot);
1654 f = &(c->fields[slot]);
1656 return (jfieldID) f;
1658 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1660 /* keep compiler happy */
1667 /* ToReflectedMethod ***********************************************************
1669 Converts a method ID derived from cls to an instance of the
1670 java.lang.reflect.Method class or to an instance of the
1671 java.lang.reflect.Constructor class.
1673 *******************************************************************************/
1675 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1678 #if defined(ENABLE_JAVASE)
1680 java_lang_reflect_Constructor *rc;
1681 java_lang_reflect_Method *rm;
1683 STATISTICS(jniinvokation());
1685 m = (methodinfo *) methodID;
1687 /* HotSpot does the same assert. */
1689 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1691 if (m->name == utf_init) {
1692 rc = reflect_constructor_new(m);
1694 return (jobject) rc;
1697 rm = reflect_method_new(m);
1699 return (jobject) rm;
1702 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1704 /* keep compiler happy */
1711 /* ToReflectedField ************************************************************
1713 Converts a field ID derived from cls to an instance of the
1714 java.lang.reflect.Field class.
1716 *******************************************************************************/
1718 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1721 STATISTICS(jniinvokation());
1723 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1729 /* Calling Instance Methods ***************************************************/
1731 /* GetMethodID *****************************************************************
1733 Returns the method ID for an instance (nonstatic) method of a class
1734 or interface. The method may be defined in one of the clazz's
1735 superclasses and inherited by clazz. The method is determined by
1736 its name and signature.
1738 GetMethodID() causes an uninitialized class to be initialized.
1740 *******************************************************************************/
1742 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1750 STATISTICS(jniinvokation());
1752 c = LLNI_classinfo_unwrap(clazz);
1757 if (!(c->state & CLASS_INITIALIZED))
1758 if (!initialize_class(c))
1761 /* try to get the method of the class or one of it's superclasses */
1763 uname = utf_new_char((char *) name);
1764 udesc = utf_new_char((char *) sig);
1766 m = class_resolvemethod(c, uname, udesc);
1768 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1769 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1774 return (jmethodID) m;
1778 /* JNI-functions for calling instance methods *********************************/
1780 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1781 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1782 jmethodID methodID, ...) \
1789 o = (java_handle_t *) obj; \
1790 m = (methodinfo *) methodID; \
1792 va_start(ap, methodID); \
1793 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1799 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1800 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1801 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1802 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1803 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1804 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1805 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1806 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1809 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1810 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1811 jmethodID methodID, va_list args) \
1817 o = (java_handle_t *) obj; \
1818 m = (methodinfo *) methodID; \
1820 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1825 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1826 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1827 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1828 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1829 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1830 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1831 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1832 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1835 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1836 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1837 jmethodID methodID, \
1838 const jvalue *args) \
1844 o = (java_handle_t *) obj; \
1845 m = (methodinfo *) methodID; \
1847 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1852 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1853 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1854 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1855 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1856 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1857 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1858 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1859 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1862 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1870 o = (java_handle_t *) obj;
1871 m = (methodinfo *) methodID;
1873 va_start(ap, methodID);
1874 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1877 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1881 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1888 o = (java_handle_t *) obj;
1889 m = (methodinfo *) methodID;
1891 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1893 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1897 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1904 o = (java_handle_t *) obj;
1905 m = (methodinfo *) methodID;
1907 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1909 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1914 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1920 o = (java_handle_t *) obj;
1921 m = (methodinfo *) methodID;
1923 va_start(ap, methodID);
1924 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1929 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1935 o = (java_handle_t *) obj;
1936 m = (methodinfo *) methodID;
1938 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1942 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1948 o = (java_handle_t *) obj;
1949 m = (methodinfo *) methodID;
1951 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1956 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1957 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1958 jclass clazz, jmethodID methodID, \
1967 o = (java_handle_t *) obj; \
1968 c = LLNI_classinfo_unwrap(clazz); \
1969 m = (methodinfo *) methodID; \
1971 va_start(ap, methodID); \
1972 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1978 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1979 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1980 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1981 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1982 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1983 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1984 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1985 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1988 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1989 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1990 jclass clazz, jmethodID methodID, \
1998 o = (java_handle_t *) obj; \
1999 c = LLNI_classinfo_unwrap(clazz); \
2000 m = (methodinfo *) methodID; \
2002 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
2007 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
2008 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
2009 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
2010 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
2011 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
2012 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
2013 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
2014 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
2017 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
2018 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
2019 jclass clazz, jmethodID methodID, \
2020 const jvalue *args) \
2022 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
2027 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
2028 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
2029 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
2030 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
2031 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
2032 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
2033 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
2034 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
2036 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2037 jclass clazz, jmethodID methodID,
2046 o = (java_handle_t *) obj;
2047 c = LLNI_classinfo_unwrap(clazz);
2048 m = (methodinfo *) methodID;
2050 va_start(ap, methodID);
2051 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2054 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2058 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2059 jclass clazz, jmethodID methodID,
2067 o = (java_handle_t *) obj;
2068 c = LLNI_classinfo_unwrap(clazz);
2069 m = (methodinfo *) methodID;
2071 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2073 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2077 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2078 jclass clazz, jmethodID methodID,
2081 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2083 return _Jv_JNI_NewLocalRef(env, NULL);
2087 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2088 jmethodID methodID, ...)
2095 o = (java_handle_t *) obj;
2096 c = LLNI_classinfo_unwrap(clazz);
2097 m = (methodinfo *) methodID;
2099 va_start(ap, methodID);
2100 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2105 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2106 jmethodID methodID, va_list args)
2112 o = (java_handle_t *) obj;
2113 c = LLNI_classinfo_unwrap(clazz);
2114 m = (methodinfo *) methodID;
2116 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2120 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2121 jmethodID methodID, const jvalue * args)
2127 o = (java_handle_t *) obj;
2128 c = LLNI_classinfo_unwrap(clazz);
2129 m = (methodinfo *) methodID;
2131 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2135 /* Accessing Fields of Objects ************************************************/
2137 /* GetFieldID ******************************************************************
2139 Returns the field ID for an instance (nonstatic) field of a
2140 class. The field is specified by its name and signature. The
2141 Get<type>Field and Set<type>Field families of accessor functions
2142 use field IDs to retrieve object fields.
2144 *******************************************************************************/
2146 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2154 STATISTICS(jniinvokation());
2156 c = LLNI_classinfo_unwrap(clazz);
2158 /* XXX NPE check? */
2160 uname = utf_new_char((char *) name);
2161 udesc = utf_new_char((char *) sig);
2163 f = class_findfield(c, uname, udesc);
2166 exceptions_throw_nosuchfielderror(c, uname);
2168 return (jfieldID) f;
2172 /* Get<type>Field Routines *****************************************************
2174 This family of accessor routines returns the value of an instance
2175 (nonstatic) field of an object. The field to access is specified by
2176 a field ID obtained by calling GetFieldID().
2178 *******************************************************************************/
2180 #define JNI_GET_FIELD(name, type, intern) \
2181 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2185 STATISTICS(jniinvokation()); \
2187 ret = GET_FIELD(obj, intern, fieldID); \
2189 return (type) ret; \
2192 JNI_GET_FIELD(Boolean, jboolean, s4)
2193 JNI_GET_FIELD(Byte, jbyte, s4)
2194 JNI_GET_FIELD(Char, jchar, s4)
2195 JNI_GET_FIELD(Short, jshort, s4)
2196 JNI_GET_FIELD(Int, jint, s4)
2197 JNI_GET_FIELD(Long, jlong, s8)
2198 JNI_GET_FIELD(Float, jfloat, float)
2199 JNI_GET_FIELD(Double, jdouble, double)
2202 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2206 STATISTICS(jniinvokation());
2208 vm_abort("this needs to be fixed");
2209 o = GET_FIELD(obj, java_handle_t*, fieldID);
2211 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2215 /* Set<type>Field Routines *****************************************************
2217 This family of accessor routines sets the value of an instance
2218 (nonstatic) field of an object. The field to access is specified by
2219 a field ID obtained by calling GetFieldID().
2221 *******************************************************************************/
2223 #define JNI_SET_FIELD(name, type, intern) \
2224 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2227 STATISTICS(jniinvokation()); \
2229 SET_FIELD(obj, intern, fieldID, value); \
2232 JNI_SET_FIELD(Boolean, jboolean, s4)
2233 JNI_SET_FIELD(Byte, jbyte, s4)
2234 JNI_SET_FIELD(Char, jchar, s4)
2235 JNI_SET_FIELD(Short, jshort, s4)
2236 JNI_SET_FIELD(Int, jint, s4)
2237 JNI_SET_FIELD(Long, jlong, s8)
2238 JNI_SET_FIELD(Float, jfloat, float)
2239 JNI_SET_FIELD(Double, jdouble, double)
2242 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2245 STATISTICS(jniinvokation());
2247 vm_abort("this needs to be fixed");
2248 SET_FIELD(obj, java_handle_t*, fieldID, value);
2252 /* Calling Static Methods *****************************************************/
2254 /* GetStaticMethodID ***********************************************************
2256 Returns the method ID for a static method of a class. The method is
2257 specified by its name and signature.
2259 GetStaticMethodID() causes an uninitialized class to be
2262 *******************************************************************************/
2264 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2272 STATISTICS(jniinvokation());
2274 c = LLNI_classinfo_unwrap(clazz);
2279 if (!(c->state & CLASS_INITIALIZED))
2280 if (!initialize_class(c))
2283 /* try to get the static method of the class */
2285 uname = utf_new_char((char *) name);
2286 udesc = utf_new_char((char *) sig);
2288 m = class_resolvemethod(c, uname, udesc);
2290 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2291 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2296 return (jmethodID) m;
2300 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2301 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2302 jmethodID methodID, ...) \
2308 m = (methodinfo *) methodID; \
2310 va_start(ap, methodID); \
2311 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2317 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2318 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2319 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2320 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2321 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2322 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2323 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2324 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2327 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2328 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2329 jmethodID methodID, va_list args) \
2334 m = (methodinfo *) methodID; \
2336 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2341 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2342 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2343 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2344 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2345 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2346 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2347 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2348 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2351 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2352 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2353 jmethodID methodID, const jvalue *args) \
2358 m = (methodinfo *) methodID; \
2360 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2365 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2366 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2367 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2368 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2369 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2370 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2371 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2372 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2375 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2376 jmethodID methodID, ...)
2382 m = (methodinfo *) methodID;
2384 va_start(ap, methodID);
2385 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2388 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2392 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2393 jmethodID methodID, va_list args)
2398 m = (methodinfo *) methodID;
2400 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2402 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2406 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2407 jmethodID methodID, const jvalue *args)
2412 m = (methodinfo *) methodID;
2414 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2416 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2420 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2421 jmethodID methodID, ...)
2426 m = (methodinfo *) methodID;
2428 va_start(ap, methodID);
2429 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2434 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2435 jmethodID methodID, va_list args)
2439 m = (methodinfo *) methodID;
2441 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2445 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2446 jmethodID methodID, const jvalue * args)
2450 m = (methodinfo *) methodID;
2452 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2456 /* Accessing Static Fields ****************************************************/
2458 /* GetStaticFieldID ************************************************************
2460 Returns the field ID for a static field of a class. The field is
2461 specified by its name and signature. The GetStatic<type>Field and
2462 SetStatic<type>Field families of accessor functions use field IDs
2463 to retrieve static fields.
2465 *******************************************************************************/
2467 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2475 STATISTICS(jniinvokation());
2477 c = LLNI_classinfo_unwrap(clazz);
2479 uname = utf_new_char((char *) name);
2480 usig = utf_new_char((char *) sig);
2482 f = class_findfield(c, uname, usig);
2485 exceptions_throw_nosuchfielderror(c, uname);
2487 return (jfieldID) f;
2491 /* GetStatic<type>Field ********************************************************
2493 This family of accessor routines returns the value of a static
2496 *******************************************************************************/
2498 #define JNI_GET_STATIC_FIELD(name, type, field) \
2499 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2505 STATISTICS(jniinvokation()); \
2507 c = LLNI_classinfo_unwrap(clazz); \
2508 f = (fieldinfo *) fieldID; \
2510 if (!(c->state & CLASS_INITIALIZED)) \
2511 if (!initialize_class(c)) \
2514 return f->value->field; \
2517 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2518 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2519 JNI_GET_STATIC_FIELD(Char, jchar, i)
2520 JNI_GET_STATIC_FIELD(Short, jshort, i)
2521 JNI_GET_STATIC_FIELD(Int, jint, i)
2522 JNI_GET_STATIC_FIELD(Long, jlong, l)
2523 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2524 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2527 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2533 STATISTICS(jniinvokation());
2535 c = LLNI_classinfo_unwrap(clazz);
2536 f = (fieldinfo *) fieldID;
2538 if (!(c->state & CLASS_INITIALIZED))
2539 if (!initialize_class(c))
2542 return _Jv_JNI_NewLocalRef(env, f->value->a);
2546 /* SetStatic<type>Field *******************************************************
2548 This family of accessor routines sets the value of a static field
2551 *******************************************************************************/
2553 #define JNI_SET_STATIC_FIELD(name, type, field) \
2554 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2561 STATISTICS(jniinvokation()); \
2563 c = LLNI_classinfo_unwrap(clazz); \
2564 f = (fieldinfo *) fieldID; \
2566 if (!(c->state & CLASS_INITIALIZED)) \
2567 if (!initialize_class(c)) \
2570 f->value->field = value; \
2573 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2574 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2575 JNI_SET_STATIC_FIELD(Char, jchar, i)
2576 JNI_SET_STATIC_FIELD(Short, jshort, i)
2577 JNI_SET_STATIC_FIELD(Int, jint, i)
2578 JNI_SET_STATIC_FIELD(Long, jlong, l)
2579 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2580 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2583 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2589 STATISTICS(jniinvokation());
2591 c = LLNI_classinfo_unwrap(clazz);
2592 f = (fieldinfo *) fieldID;
2594 if (!(c->state & CLASS_INITIALIZED))
2595 if (!initialize_class(c))
2598 f->value->a = value;
2602 /* String Operations **********************************************************/
2604 /* NewString *******************************************************************
2606 Create new java.lang.String object from an array of Unicode
2609 *******************************************************************************/
2611 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2613 java_lang_String *s;
2614 java_handle_chararray_t *a;
2617 STATISTICS(jniinvokation());
2619 s = (java_lang_String *) builtin_new(class_java_lang_String);
2620 a = builtin_newarray_char(len);
2622 /* javastring or characterarray could not be created */
2623 if ((a == NULL) || (s == NULL))
2627 for (i = 0; i < len; i++)
2628 LLNI_array_direct(a, i) = buf[i];
2630 LLNI_field_set_ref(s, value , a);
2631 LLNI_field_set_val(s, offset, 0);
2632 LLNI_field_set_val(s, count , len);
2634 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2638 static jchar emptyStringJ[]={0,0};
2640 /* GetStringLength *************************************************************
2642 Returns the length (the count of Unicode characters) of a Java
2645 *******************************************************************************/
2647 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2649 java_lang_String *s;
2652 TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
2654 s = (java_lang_String *) str;
2656 LLNI_field_get_val(s, count, len);
2662 /******************** convertes javastring to u2-array ****************************/
2664 u2 *javastring_tou2(jstring so)
2666 java_lang_String *s;
2667 java_handle_chararray_t *a;
2673 STATISTICS(jniinvokation());
2675 s = (java_lang_String *) so;
2680 LLNI_field_get_ref(s, value, a);
2685 LLNI_field_get_val(s, count, count);
2686 LLNI_field_get_val(s, offset, offset);
2688 /* allocate memory */
2690 stringbuffer = MNEW(u2, count + 1);
2694 for (i = 0; i < count; i++)
2695 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2697 /* terminate string */
2699 stringbuffer[i] = '\0';
2701 return stringbuffer;
2705 /* GetStringChars **************************************************************
2707 Returns a pointer to the array of Unicode characters of the
2708 string. This pointer is valid until ReleaseStringChars() is called.
2710 *******************************************************************************/
2712 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2716 STATISTICS(jniinvokation());
2718 jc = javastring_tou2(str);
2730 return emptyStringJ;
2734 /* ReleaseStringChars **********************************************************
2736 Informs the VM that the native code no longer needs access to
2737 chars. The chars argument is a pointer obtained from string using
2740 *******************************************************************************/
2742 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2744 java_lang_String *s;
2746 STATISTICS(jniinvokation());
2748 if (chars == emptyStringJ)
2751 s = (java_lang_String *) str;
2753 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2757 /* NewStringUTF ****************************************************************
2759 Constructs a new java.lang.String object from an array of UTF-8
2762 *******************************************************************************/
2764 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2766 java_lang_String *s;
2768 TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
2770 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2772 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2776 /****************** returns the utf8 length in bytes of a string *******************/
2778 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2780 java_lang_String *s;
2783 TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
2785 s = (java_lang_String *) string;
2787 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2793 /* GetStringUTFChars ***********************************************************
2795 Returns a pointer to an array of UTF-8 characters of the
2796 string. This array is valid until it is released by
2797 ReleaseStringUTFChars().
2799 *******************************************************************************/
2801 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2806 STATISTICS(jniinvokation());
2814 u = javastring_toutf((java_handle_t *) string, false);
2823 /* ReleaseStringUTFChars *******************************************************
2825 Informs the VM that the native code no longer needs access to
2826 utf. The utf argument is a pointer derived from string using
2827 GetStringUTFChars().
2829 *******************************************************************************/
2831 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2833 STATISTICS(jniinvokation());
2835 /* XXX we don't release utf chars right now, perhaps that should be done
2836 later. Since there is always one reference the garbage collector will
2841 /* Array Operations ***********************************************************/
2843 /* GetArrayLength **************************************************************
2845 Returns the number of elements in the array.
2847 *******************************************************************************/
2849 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2854 STATISTICS(jniinvokation());
2856 a = (java_handle_t *) array;
2858 size = LLNI_array_size(a);
2864 /* NewObjectArray **************************************************************
2866 Constructs a new array holding objects in class elementClass. All
2867 elements are initially set to initialElement.
2869 *******************************************************************************/
2871 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2872 jclass elementClass, jobject initialElement)
2876 java_handle_objectarray_t *oa;
2879 STATISTICS(jniinvokation());
2881 c = LLNI_classinfo_unwrap(elementClass);
2882 o = (java_handle_t *) initialElement;
2885 exceptions_throw_negativearraysizeexception();
2889 oa = builtin_anewarray(length, c);
2894 /* set all elements to initialElement */
2896 for (i = 0; i < length; i++)
2897 LLNI_objectarray_element_set(oa, i, o);
2899 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2903 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2906 java_handle_objectarray_t *oa;
2909 STATISTICS(jniinvokation());
2911 oa = (java_handle_objectarray_t *) array;
2913 if (index >= LLNI_array_size(oa)) {
2914 exceptions_throw_arrayindexoutofboundsexception();
2918 LLNI_objectarray_element_get(oa, index, o);
2920 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2924 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2925 jsize index, jobject val)
2927 java_handle_objectarray_t *oa;
2930 STATISTICS(jniinvokation());
2932 oa = (java_handle_objectarray_t *) array;
2933 o = (java_handle_t *) val;
2935 if (index >= LLNI_array_size(oa)) {
2936 exceptions_throw_arrayindexoutofboundsexception();
2940 /* check if the class of value is a subclass of the element class
2943 if (!builtin_canstore(LLNI_DIRECT(oa), LLNI_DIRECT(o)))
2946 LLNI_objectarray_element_set(oa, index, o);
2950 #define JNI_NEW_ARRAY(name, type, intern) \
2951 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2953 java_handle_##intern##array_t *a; \
2955 STATISTICS(jniinvokation()); \
2958 exceptions_throw_negativearraysizeexception(); \
2962 a = builtin_newarray_##intern(len); \
2964 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2967 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2968 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2969 JNI_NEW_ARRAY(Char, jcharArray, char)
2970 JNI_NEW_ARRAY(Short, jshortArray, byte)
2971 JNI_NEW_ARRAY(Int, jintArray, int)
2972 JNI_NEW_ARRAY(Long, jlongArray, long)
2973 JNI_NEW_ARRAY(Float, jfloatArray, float)
2974 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2977 /* Get<PrimitiveType>ArrayElements *********************************************
2979 A family of functions that returns the body of the primitive array.
2981 *******************************************************************************/
2983 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2984 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2987 java_handle_##intern##array_t *a; \
2989 STATISTICS(jniinvokation()); \
2991 a = (java_handle_##intern##array_t *) array; \
2994 *isCopy = JNI_FALSE; \
2996 return LLNI_array_data(a); \
2999 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
3000 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
3001 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
3002 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
3003 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
3004 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
3005 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
3006 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
3009 /* Release<PrimitiveType>ArrayElements *****************************************
3011 A family of functions that informs the VM that the native code no
3012 longer needs access to elems. The elems argument is a pointer
3013 derived from array using the corresponding
3014 Get<PrimitiveType>ArrayElements() function. If necessary, this
3015 function copies back all changes made to elems to the original
3018 *******************************************************************************/
3020 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
3021 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
3022 type *elems, jint mode) \
3024 java_handle_##intern##array_t *a; \
3026 STATISTICS(jniinvokation()); \
3028 a = (java_handle_##intern##array_t *) array; \
3030 if (elems != LLNI_array_data(a)) { \
3033 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3036 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3037 /* XXX TWISTI how should it be freed? */ \
3040 /* XXX TWISTI how should it be freed? */ \
3046 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3047 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3048 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3049 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3050 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3051 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3052 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3053 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3056 /* Get<PrimitiveType>ArrayRegion **********************************************
3058 A family of functions that copies a region of a primitive array
3061 *******************************************************************************/
3063 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3064 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3065 jsize start, jsize len, type *buf) \
3067 java_handle_##intern##array_t *a; \
3069 STATISTICS(jniinvokation()); \
3071 a = (java_handle_##intern##array_t *) array; \
3073 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3074 exceptions_throw_arrayindexoutofboundsexception(); \
3076 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3079 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3080 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3081 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3082 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3083 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3084 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3085 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3086 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3089 /* Set<PrimitiveType>ArrayRegion **********************************************
3091 A family of functions that copies back a region of a primitive
3092 array from a buffer.
3094 *******************************************************************************/
3096 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3097 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3098 jsize start, jsize len, const type *buf) \
3100 java_handle_##intern##array_t *a; \
3102 STATISTICS(jniinvokation()); \
3104 a = (java_handle_##intern##array_t *) array; \
3106 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3107 exceptions_throw_arrayindexoutofboundsexception(); \
3109 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3112 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3113 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3114 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3115 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3116 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3117 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3118 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3119 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3122 /* Registering Native Methods *************************************************/
3124 /* RegisterNatives *************************************************************
3126 Registers native methods with the class specified by the clazz
3127 argument. The methods parameter specifies an array of
3128 JNINativeMethod structures that contain the names, signatures, and
3129 function pointers of the native methods. The nMethods parameter
3130 specifies the number of native methods in the array.
3132 *******************************************************************************/
3134 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3135 const JNINativeMethod *methods, jint nMethods)
3139 STATISTICS(jniinvokation());
3141 c = LLNI_classinfo_unwrap(clazz);
3143 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3144 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3147 native_method_register(c->name, methods, nMethods);
3153 /* UnregisterNatives ***********************************************************
3155 Unregisters native methods of a class. The class goes back to the
3156 state before it was linked or registered with its native method
3159 This function should not be used in normal native code. Instead, it
3160 provides special programs a way to reload and relink native
3163 *******************************************************************************/
3165 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3167 STATISTICS(jniinvokation());
3169 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3171 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3177 /* Monitor Operations *********************************************************/
3179 /* MonitorEnter ****************************************************************
3181 Enters the monitor associated with the underlying Java object
3184 *******************************************************************************/
3186 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3188 STATISTICS(jniinvokation());
3191 exceptions_throw_nullpointerexception();
3195 LOCK_MONITOR_ENTER(obj);
3201 /* MonitorExit *****************************************************************
3203 The current thread must be the owner of the monitor associated with
3204 the underlying Java object referred to by obj. The thread
3205 decrements the counter indicating the number of times it has
3206 entered this monitor. If the value of the counter becomes zero, the
3207 current thread releases the monitor.
3209 *******************************************************************************/
3211 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3213 STATISTICS(jniinvokation());
3216 exceptions_throw_nullpointerexception();
3220 LOCK_MONITOR_EXIT(obj);
3226 /* JavaVM Interface ***********************************************************/
3228 /* GetJavaVM *******************************************************************
3230 Returns the Java VM interface (used in the Invocation API)
3231 associated with the current thread. The result is placed at the
3232 location pointed to by the second argument, vm.
3234 *******************************************************************************/
3236 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3238 STATISTICS(jniinvokation());
3240 *vm = (JavaVM *) _Jv_jvm;
3246 /* GetStringRegion *************************************************************
3248 Copies len number of Unicode characters beginning at offset start
3249 to the given buffer buf.
3251 Throws StringIndexOutOfBoundsException on index overflow.
3253 *******************************************************************************/
3255 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3258 java_lang_String *s;
3259 java_handle_chararray_t *ca;
3261 STATISTICS(jniinvokation());
3263 s = (java_lang_String *) str;
3264 LLNI_field_get_ref(s, value, ca);
3266 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3267 (start + len > LLNI_field_direct(s, count))) {
3268 exceptions_throw_stringindexoutofboundsexception();
3272 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3276 /* GetStringUTFRegion **********************************************************
3278 Translates len number of Unicode characters beginning at offset
3279 start into UTF-8 format and place the result in the given buffer
3282 Throws StringIndexOutOfBoundsException on index overflow.
3284 *******************************************************************************/
3286 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3287 jsize len, char *buf)
3289 java_lang_String *s;
3290 java_handle_chararray_t *ca;
3295 TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
3297 s = (java_lang_String *) str;
3298 LLNI_field_get_ref(s, value, ca);
3299 LLNI_field_get_val(s, count, count);
3300 LLNI_field_get_val(s, offset, offset);
3302 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3303 exceptions_throw_stringindexoutofboundsexception();
3307 for (i = 0; i < len; i++)
3308 buf[i] = LLNI_array_direct(ca, offset + start + i);
3314 /* GetPrimitiveArrayCritical ***************************************************
3316 Obtain a direct pointer to array elements.
3318 *******************************************************************************/
3320 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3323 java_handle_bytearray_t *ba;
3326 ba = (java_handle_bytearray_t *) array;
3328 /* do the same as Kaffe does */
3330 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3336 /* ReleasePrimitiveArrayCritical ***********************************************
3338 No specific documentation.
3340 *******************************************************************************/
3342 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3343 void *carray, jint mode)
3345 STATISTICS(jniinvokation());
3347 /* do the same as Kaffe does */
3349 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3354 /* GetStringCritical ***********************************************************
3356 The semantics of these two functions are similar to the existing
3357 Get/ReleaseStringChars functions.
3359 *******************************************************************************/
3361 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3364 STATISTICS(jniinvokation());
3366 return _Jv_JNI_GetStringChars(env, string, isCopy);
3370 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3371 const jchar *cstring)
3373 STATISTICS(jniinvokation());
3375 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3379 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3381 STATISTICS(jniinvokation());
3383 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
3389 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3391 STATISTICS(jniinvokation());
3393 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
3397 /* NewGlobalRef ****************************************************************
3399 Creates a new global reference to the object referred to by the obj
3402 *******************************************************************************/
3404 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3406 hashtable_global_ref_entry *gre;
3407 u4 key; /* hashkey */
3408 u4 slot; /* slot in hashtable */
3411 STATISTICS(jniinvokation());
3413 o = (java_handle_t *) obj;
3415 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3417 LLNI_CRITICAL_START;
3419 /* normally addresses are aligned to 4, 8 or 16 bytes */
3421 #if defined(ENABLE_GC_CACAO)
3422 key = heap_get_hashcode(LLNI_DIRECT(o)) >> 4;
3424 key = ((u4) (ptrint) o) >> 4; /* align to 16-byte boundaries */
3426 slot = key & (hashtable_global_ref->size - 1);
3427 gre = hashtable_global_ref->ptr[slot];
3429 /* search external hash chain for the entry */
3432 if (gre->o == LLNI_DIRECT(o)) {
3433 /* global object found, increment the reference */
3440 gre = gre->hashlink; /* next element in external chain */
3443 /* global ref not found, create a new one */
3446 gre = NEW(hashtable_global_ref_entry);
3448 #if defined(ENABLE_GC_CACAO)
3449 /* register global ref with the GC */
3451 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3454 gre->o = LLNI_DIRECT(o);
3457 /* insert entry into hashtable */
3459 gre->hashlink = hashtable_global_ref->ptr[slot];
3461 hashtable_global_ref->ptr[slot] = gre;
3463 /* update number of hashtable-entries */
3465 hashtable_global_ref->entries++;
3470 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3472 #if defined(ENABLE_HANDLES)
3480 /* DeleteGlobalRef *************************************************************
3482 Deletes the global reference pointed to by globalRef.
3484 *******************************************************************************/
3486 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3488 hashtable_global_ref_entry *gre;
3489 hashtable_global_ref_entry *prevgre;
3490 u4 key; /* hashkey */
3491 u4 slot; /* slot in hashtable */
3494 STATISTICS(jniinvokation());
3496 o = (java_handle_t *) globalRef;
3498 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3500 LLNI_CRITICAL_START;
3502 /* normally addresses are aligned to 4, 8 or 16 bytes */
3504 #if defined(ENABLE_GC_CACAO)
3505 key = heap_get_hashcode(LLNI_DIRECT(o)) >> 4;
3507 key = ((u4) (ptrint) o) >> 4; /* align to 16-byte boundaries */
3509 slot = key & (hashtable_global_ref->size - 1);
3510 gre = hashtable_global_ref->ptr[slot];
3512 /* initialize prevgre */
3516 /* search external hash chain for the entry */
3519 if (gre->o == LLNI_DIRECT(o)) {
3520 /* global object found, decrement the reference count */
3524 /* if reference count is 0, remove the entry */
3526 if (gre->refs == 0) {
3527 /* special handling if it's the first in the chain */
3529 if (prevgre == NULL)
3530 hashtable_global_ref->ptr[slot] = gre->hashlink;
3532 prevgre->hashlink = gre->hashlink;
3534 #if defined(ENABLE_GC_CACAO)
3535 /* unregister global ref with the GC */
3537 gc_reference_unregister(&(gre->o));
3540 FREE(gre, hashtable_global_ref_entry);
3545 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3550 prevgre = gre; /* save current pointer for removal */
3551 gre = gre->hashlink; /* next element in external chain */
3554 log_println("JNI-DeleteGlobalRef: global reference not found");
3558 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3562 /* ExceptionCheck **************************************************************
3564 Returns JNI_TRUE when there is a pending exception; otherwise,
3567 *******************************************************************************/
3569 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3573 STATISTICS(jniinvokation());
3575 o = exceptions_get_exception();
3577 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3581 /* New JNI 1.4 functions ******************************************************/
3583 /* NewDirectByteBuffer *********************************************************
3585 Allocates and returns a direct java.nio.ByteBuffer referring to the
3586 block of memory starting at the memory address address and
3587 extending capacity bytes.
3589 *******************************************************************************/
3591 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3593 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3594 java_handle_t *nbuf;
3596 # if SIZEOF_VOID_P == 8
3597 gnu_classpath_Pointer64 *paddress;
3599 gnu_classpath_Pointer32 *paddress;
3602 STATISTICS(jniinvokation());
3604 /* alocate a gnu.classpath.Pointer{32,64} object */
3606 # if SIZEOF_VOID_P == 8
3607 if (!(paddress = (gnu_classpath_Pointer64 *)
3608 builtin_new(class_gnu_classpath_Pointer64)))
3610 if (!(paddress = (gnu_classpath_Pointer32 *)
3611 builtin_new(class_gnu_classpath_Pointer32)))
3615 /* fill gnu.classpath.Pointer{32,64} with address */
3617 LLNI_field_set_val(paddress, data, (ptrint) address);
3619 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3621 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3622 (jmethodID) dbbirw_init, NULL, paddress,
3623 (jint) capacity, (jint) capacity, (jint) 0);
3625 /* add local reference and return the value */
3627 return _Jv_JNI_NewLocalRef(env, nbuf);
3629 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3631 /* keep compiler happy */
3638 /* GetDirectBufferAddress ******************************************************
3640 Fetches and returns the starting address of the memory region
3641 referenced by the given direct java.nio.Buffer.
3643 *******************************************************************************/
3645 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3647 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3648 java_nio_DirectByteBufferImpl *nbuf;
3649 # if SIZEOF_VOID_P == 8
3650 gnu_classpath_Pointer64 *paddress;
3652 gnu_classpath_Pointer32 *paddress;
3656 STATISTICS(jniinvokation());
3658 if (!builtin_instanceof(buf, class_java_nio_Buffer))
3661 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3663 # if SIZEOF_VOID_P == 8
3664 LLNI_field_get_ref(nbuf, address, paddress);
3665 /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
3667 LLNI_field_get_ref(nbuf, address, paddress);
3668 /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
3671 if (paddress == NULL)
3674 LLNI_field_get_val(paddress, data, address);
3675 /* this was the cast to avaoid warning: (void *) paddress->data */
3679 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3681 /* keep compiler happy */
3688 /* GetDirectBufferCapacity *****************************************************
3690 Fetches and returns the capacity in bytes of the memory region
3691 referenced by the given direct java.nio.Buffer.
3693 *******************************************************************************/
3695 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3697 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3699 java_nio_Buffer *nbuf;
3702 STATISTICS(jniinvokation());
3704 o = (java_handle_t *) buf;
3706 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3709 nbuf = (java_nio_Buffer *) o;
3711 LLNI_field_get_val(nbuf, cap, capacity);
3715 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3717 /* keep compiler happy */
3724 /* DestroyJavaVM ***************************************************************
3726 Unloads a Java VM and reclaims its resources. Only the main thread
3727 can unload the VM. The system waits until the main thread is only
3728 remaining user thread before it destroys the VM.
3730 *******************************************************************************/
3732 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3736 STATISTICS(jniinvokation());
3738 status = vm_destroy(vm);
3744 /* AttachCurrentThread *********************************************************
3746 Attaches the current thread to a Java VM. Returns a JNI interface
3747 pointer in the JNIEnv argument.
3749 Trying to attach a thread that is already attached is a no-op.
3751 A native thread cannot be attached simultaneously to two Java VMs.
3753 When a thread is attached to the VM, the context class loader is
3754 the bootstrap loader.
3756 *******************************************************************************/
3758 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3760 JavaVMAttachArgs *vm_aargs;
3762 #if defined(ENABLE_THREADS)
3763 if (threads_get_current_threadobject() == NULL) {
3764 vm_aargs = (JavaVMAttachArgs *) thr_args;
3766 if (vm_aargs != NULL) {
3767 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3768 (vm_aargs->version != JNI_VERSION_1_4))
3769 return JNI_EVERSION;
3772 if (!threads_attach_current_thread(vm_aargs, false))
3775 if (!localref_table_init())
3786 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3788 STATISTICS(jniinvokation());
3790 return jni_attach_current_thread(p_env, thr_args, false);
3794 /* DetachCurrentThread *********************************************************
3796 Detaches the current thread from a Java VM. All Java monitors held
3797 by this thread are released. All Java threads waiting for this
3798 thread to die are notified.
3800 In JDK 1.1, the main thread cannot be detached from the VM. It must
3801 call DestroyJavaVM to unload the entire VM.
3803 In the JDK, the main thread can be detached from the VM.
3805 The main thread, which is the thread that created the Java VM,
3806 cannot be detached from the VM. Instead, the main thread must call
3807 JNI_DestroyJavaVM() to unload the entire VM.
3809 *******************************************************************************/
3811 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3813 #if defined(ENABLE_THREADS)
3814 threadobject *thread;
3816 STATISTICS(jniinvokation());
3818 thread = threads_get_current_threadobject();
3823 if (!localref_table_destroy())
3826 if (!threads_detach_thread(thread))
3834 /* GetEnv **********************************************************************
3836 If the current thread is not attached to the VM, sets *env to NULL,
3837 and returns JNI_EDETACHED. If the specified version is not
3838 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3839 sets *env to the appropriate interface, and returns JNI_OK.
3841 *******************************************************************************/
3843 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3845 STATISTICS(jniinvokation());
3847 #if defined(ENABLE_THREADS)
3848 if (threads_get_current_threadobject() == NULL) {
3851 return JNI_EDETACHED;
3855 /* check the JNI version */
3858 case JNI_VERSION_1_1:
3859 case JNI_VERSION_1_2:
3860 case JNI_VERSION_1_4:
3868 #if defined(ENABLE_JVMTI)
3869 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3870 == JVMTI_VERSION_INTERFACE_JVMTI) {
3872 *env = (void *) jvmti_new_environment();
3881 return JNI_EVERSION;
3885 /* AttachCurrentThreadAsDaemon *************************************************
3887 Same semantics as AttachCurrentThread, but the newly-created
3888 java.lang.Thread instance is a daemon.
3890 If the thread has already been attached via either
3891 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3892 simply sets the value pointed to by penv to the JNIEnv of the
3893 current thread. In this case neither AttachCurrentThread nor this
3894 routine have any effect on the daemon status of the thread.
3896 *******************************************************************************/
3898 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3900 STATISTICS(jniinvokation());
3902 return jni_attach_current_thread(penv, args, true);
3906 /* JNI invocation table *******************************************************/
3908 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3913 _Jv_JNI_DestroyJavaVM,
3914 _Jv_JNI_AttachCurrentThread,
3915 _Jv_JNI_DetachCurrentThread,
3917 _Jv_JNI_AttachCurrentThreadAsDaemon
3921 /* JNI function table *********************************************************/
3923 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3930 _Jv_JNI_DefineClass,
3932 _Jv_JNI_FromReflectedMethod,
3933 _Jv_JNI_FromReflectedField,
3934 _Jv_JNI_ToReflectedMethod,
3935 _Jv_JNI_GetSuperclass,
3936 _Jv_JNI_IsAssignableFrom,
3937 _Jv_JNI_ToReflectedField,
3941 _Jv_JNI_ExceptionOccurred,
3942 _Jv_JNI_ExceptionDescribe,
3943 _Jv_JNI_ExceptionClear,
3945 _Jv_JNI_PushLocalFrame,
3946 _Jv_JNI_PopLocalFrame,
3948 _Jv_JNI_NewGlobalRef,
3949 _Jv_JNI_DeleteGlobalRef,
3950 _Jv_JNI_DeleteLocalRef,
3951 _Jv_JNI_IsSameObject,
3952 _Jv_JNI_NewLocalRef,
3953 _Jv_JNI_EnsureLocalCapacity,
3955 _Jv_JNI_AllocObject,
3960 _Jv_JNI_GetObjectClass,
3961 _Jv_JNI_IsInstanceOf,
3963 _Jv_JNI_GetMethodID,
3965 _Jv_JNI_CallObjectMethod,
3966 _Jv_JNI_CallObjectMethodV,
3967 _Jv_JNI_CallObjectMethodA,
3968 _Jv_JNI_CallBooleanMethod,
3969 _Jv_JNI_CallBooleanMethodV,
3970 _Jv_JNI_CallBooleanMethodA,
3971 _Jv_JNI_CallByteMethod,
3972 _Jv_JNI_CallByteMethodV,
3973 _Jv_JNI_CallByteMethodA,
3974 _Jv_JNI_CallCharMethod,
3975 _Jv_JNI_CallCharMethodV,
3976 _Jv_JNI_CallCharMethodA,
3977 _Jv_JNI_CallShortMethod,
3978 _Jv_JNI_CallShortMethodV,
3979 _Jv_JNI_CallShortMethodA,
3980 _Jv_JNI_CallIntMethod,
3981 _Jv_JNI_CallIntMethodV,
3982 _Jv_JNI_CallIntMethodA,
3983 _Jv_JNI_CallLongMethod,
3984 _Jv_JNI_CallLongMethodV,
3985 _Jv_JNI_CallLongMethodA,
3986 _Jv_JNI_CallFloatMethod,
3987 _Jv_JNI_CallFloatMethodV,
3988 _Jv_JNI_CallFloatMethodA,
3989 _Jv_JNI_CallDoubleMethod,
3990 _Jv_JNI_CallDoubleMethodV,
3991 _Jv_JNI_CallDoubleMethodA,
3992 _Jv_JNI_CallVoidMethod,
3993 _Jv_JNI_CallVoidMethodV,
3994 _Jv_JNI_CallVoidMethodA,
3996 _Jv_JNI_CallNonvirtualObjectMethod,
3997 _Jv_JNI_CallNonvirtualObjectMethodV,
3998 _Jv_JNI_CallNonvirtualObjectMethodA,
3999 _Jv_JNI_CallNonvirtualBooleanMethod,
4000 _Jv_JNI_CallNonvirtualBooleanMethodV,
4001 _Jv_JNI_CallNonvirtualBooleanMethodA,
4002 _Jv_JNI_CallNonvirtualByteMethod,
4003 _Jv_JNI_CallNonvirtualByteMethodV,
4004 _Jv_JNI_CallNonvirtualByteMethodA,
4005 _Jv_JNI_CallNonvirtualCharMethod,
4006 _Jv_JNI_CallNonvirtualCharMethodV,
4007 _Jv_JNI_CallNonvirtualCharMethodA,
4008 _Jv_JNI_CallNonvirtualShortMethod,
4009 _Jv_JNI_CallNonvirtualShortMethodV,
4010 _Jv_JNI_CallNonvirtualShortMethodA,
4011 _Jv_JNI_CallNonvirtualIntMethod,
4012 _Jv_JNI_CallNonvirtualIntMethodV,
4013 _Jv_JNI_CallNonvirtualIntMethodA,
4014 _Jv_JNI_CallNonvirtualLongMethod,
4015 _Jv_JNI_CallNonvirtualLongMethodV,
4016 _Jv_JNI_CallNonvirtualLongMethodA,
4017 _Jv_JNI_CallNonvirtualFloatMethod,
4018 _Jv_JNI_CallNonvirtualFloatMethodV,
4019 _Jv_JNI_CallNonvirtualFloatMethodA,
4020 _Jv_JNI_CallNonvirtualDoubleMethod,
4021 _Jv_JNI_CallNonvirtualDoubleMethodV,
4022 _Jv_JNI_CallNonvirtualDoubleMethodA,
4023 _Jv_JNI_CallNonvirtualVoidMethod,
4024 _Jv_JNI_CallNonvirtualVoidMethodV,
4025 _Jv_JNI_CallNonvirtualVoidMethodA,
4029 _Jv_JNI_GetObjectField,
4030 _Jv_JNI_GetBooleanField,
4031 _Jv_JNI_GetByteField,
4032 _Jv_JNI_GetCharField,
4033 _Jv_JNI_GetShortField,
4034 _Jv_JNI_GetIntField,
4035 _Jv_JNI_GetLongField,
4036 _Jv_JNI_GetFloatField,
4037 _Jv_JNI_GetDoubleField,
4038 _Jv_JNI_SetObjectField,
4039 _Jv_JNI_SetBooleanField,
4040 _Jv_JNI_SetByteField,
4041 _Jv_JNI_SetCharField,
4042 _Jv_JNI_SetShortField,
4043 _Jv_JNI_SetIntField,
4044 _Jv_JNI_SetLongField,
4045 _Jv_JNI_SetFloatField,
4046 _Jv_JNI_SetDoubleField,
4048 _Jv_JNI_GetStaticMethodID,
4050 _Jv_JNI_CallStaticObjectMethod,
4051 _Jv_JNI_CallStaticObjectMethodV,
4052 _Jv_JNI_CallStaticObjectMethodA,
4053 _Jv_JNI_CallStaticBooleanMethod,
4054 _Jv_JNI_CallStaticBooleanMethodV,
4055 _Jv_JNI_CallStaticBooleanMethodA,
4056 _Jv_JNI_CallStaticByteMethod,
4057 _Jv_JNI_CallStaticByteMethodV,
4058 _Jv_JNI_CallStaticByteMethodA,
4059 _Jv_JNI_CallStaticCharMethod,
4060 _Jv_JNI_CallStaticCharMethodV,
4061 _Jv_JNI_CallStaticCharMethodA,
4062 _Jv_JNI_CallStaticShortMethod,
4063 _Jv_JNI_CallStaticShortMethodV,
4064 _Jv_JNI_CallStaticShortMethodA,
4065 _Jv_JNI_CallStaticIntMethod,
4066 _Jv_JNI_CallStaticIntMethodV,
4067 _Jv_JNI_CallStaticIntMethodA,
4068 _Jv_JNI_CallStaticLongMethod,
4069 _Jv_JNI_CallStaticLongMethodV,
4070 _Jv_JNI_CallStaticLongMethodA,
4071 _Jv_JNI_CallStaticFloatMethod,
4072 _Jv_JNI_CallStaticFloatMethodV,
4073 _Jv_JNI_CallStaticFloatMethodA,
4074 _Jv_JNI_CallStaticDoubleMethod,
4075 _Jv_JNI_CallStaticDoubleMethodV,
4076 _Jv_JNI_CallStaticDoubleMethodA,
4077 _Jv_JNI_CallStaticVoidMethod,
4078 _Jv_JNI_CallStaticVoidMethodV,
4079 _Jv_JNI_CallStaticVoidMethodA,
4081 _Jv_JNI_GetStaticFieldID,
4083 _Jv_JNI_GetStaticObjectField,
4084 _Jv_JNI_GetStaticBooleanField,
4085 _Jv_JNI_GetStaticByteField,
4086 _Jv_JNI_GetStaticCharField,
4087 _Jv_JNI_GetStaticShortField,
4088 _Jv_JNI_GetStaticIntField,
4089 _Jv_JNI_GetStaticLongField,
4090 _Jv_JNI_GetStaticFloatField,
4091 _Jv_JNI_GetStaticDoubleField,
4092 _Jv_JNI_SetStaticObjectField,
4093 _Jv_JNI_SetStaticBooleanField,
4094 _Jv_JNI_SetStaticByteField,
4095 _Jv_JNI_SetStaticCharField,
4096 _Jv_JNI_SetStaticShortField,
4097 _Jv_JNI_SetStaticIntField,
4098 _Jv_JNI_SetStaticLongField,
4099 _Jv_JNI_SetStaticFloatField,
4100 _Jv_JNI_SetStaticDoubleField,
4103 _Jv_JNI_GetStringLength,
4104 _Jv_JNI_GetStringChars,
4105 _Jv_JNI_ReleaseStringChars,
4107 _Jv_JNI_NewStringUTF,
4108 _Jv_JNI_GetStringUTFLength,
4109 _Jv_JNI_GetStringUTFChars,
4110 _Jv_JNI_ReleaseStringUTFChars,
4112 _Jv_JNI_GetArrayLength,
4114 _Jv_JNI_NewObjectArray,
4115 _Jv_JNI_GetObjectArrayElement,
4116 _Jv_JNI_SetObjectArrayElement,
4118 _Jv_JNI_NewBooleanArray,
4119 _Jv_JNI_NewByteArray,
4120 _Jv_JNI_NewCharArray,
4121 _Jv_JNI_NewShortArray,
4122 _Jv_JNI_NewIntArray,
4123 _Jv_JNI_NewLongArray,
4124 _Jv_JNI_NewFloatArray,
4125 _Jv_JNI_NewDoubleArray,
4127 _Jv_JNI_GetBooleanArrayElements,
4128 _Jv_JNI_GetByteArrayElements,
4129 _Jv_JNI_GetCharArrayElements,
4130 _Jv_JNI_GetShortArrayElements,
4131 _Jv_JNI_GetIntArrayElements,
4132 _Jv_JNI_GetLongArrayElements,
4133 _Jv_JNI_GetFloatArrayElements,
4134 _Jv_JNI_GetDoubleArrayElements,
4136 _Jv_JNI_ReleaseBooleanArrayElements,
4137 _Jv_JNI_ReleaseByteArrayElements,
4138 _Jv_JNI_ReleaseCharArrayElements,
4139 _Jv_JNI_ReleaseShortArrayElements,
4140 _Jv_JNI_ReleaseIntArrayElements,
4141 _Jv_JNI_ReleaseLongArrayElements,
4142 _Jv_JNI_ReleaseFloatArrayElements,
4143 _Jv_JNI_ReleaseDoubleArrayElements,
4145 _Jv_JNI_GetBooleanArrayRegion,
4146 _Jv_JNI_GetByteArrayRegion,
4147 _Jv_JNI_GetCharArrayRegion,
4148 _Jv_JNI_GetShortArrayRegion,
4149 _Jv_JNI_GetIntArrayRegion,
4150 _Jv_JNI_GetLongArrayRegion,
4151 _Jv_JNI_GetFloatArrayRegion,
4152 _Jv_JNI_GetDoubleArrayRegion,
4153 _Jv_JNI_SetBooleanArrayRegion,
4154 _Jv_JNI_SetByteArrayRegion,
4155 _Jv_JNI_SetCharArrayRegion,
4156 _Jv_JNI_SetShortArrayRegion,
4157 _Jv_JNI_SetIntArrayRegion,
4158 _Jv_JNI_SetLongArrayRegion,
4159 _Jv_JNI_SetFloatArrayRegion,
4160 _Jv_JNI_SetDoubleArrayRegion,
4162 _Jv_JNI_RegisterNatives,
4163 _Jv_JNI_UnregisterNatives,
4165 _Jv_JNI_MonitorEnter,
4166 _Jv_JNI_MonitorExit,
4170 /* new JNI 1.2 functions */
4172 _Jv_JNI_GetStringRegion,
4173 _Jv_JNI_GetStringUTFRegion,
4175 _Jv_JNI_GetPrimitiveArrayCritical,
4176 _Jv_JNI_ReleasePrimitiveArrayCritical,
4178 _Jv_JNI_GetStringCritical,
4179 _Jv_JNI_ReleaseStringCritical,
4181 _Jv_JNI_NewWeakGlobalRef,
4182 _Jv_JNI_DeleteWeakGlobalRef,
4184 _Jv_JNI_ExceptionCheck,
4186 /* new JNI 1.4 functions */
4188 _Jv_JNI_NewDirectByteBuffer,
4189 _Jv_JNI_GetDirectBufferAddress,
4190 _Jv_JNI_GetDirectBufferCapacity
4194 /* Invocation API Functions ***************************************************/
4196 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4198 Returns a default configuration for the Java VM.
4200 *******************************************************************************/
4202 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4204 JavaVMInitArgs *_vm_args;
4206 _vm_args = (JavaVMInitArgs *) vm_args;
4208 /* GNU classpath currently supports JNI 1.2 */
4210 switch (_vm_args->version) {
4211 case JNI_VERSION_1_1:
4212 _vm_args->version = JNI_VERSION_1_1;
4215 case JNI_VERSION_1_2:
4216 case JNI_VERSION_1_4:
4217 _vm_args->ignoreUnrecognized = JNI_FALSE;
4218 _vm_args->options = NULL;
4219 _vm_args->nOptions = 0;
4230 /* JNI_GetCreatedJavaVMs *******************************************************
4232 Returns all Java VMs that have been created. Pointers to VMs are written in
4233 the buffer vmBuf in the order they are created. At most bufLen number of
4234 entries will be written. The total number of created VMs is returned in
4237 *******************************************************************************/
4239 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4241 TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
4246 /* We currently only support 1 VM running. */
4248 vmBuf[0] = (JavaVM *) _Jv_jvm;
4255 /* JNI_CreateJavaVM ************************************************************
4257 Loads and initializes a Java VM. The current thread becomes the main thread.
4258 Sets the env argument to the JNI interface pointer of the main thread.
4260 *******************************************************************************/
4262 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4264 TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
4266 /* actually create the JVM */
4268 if (!vm_createjvm(p_vm, p_env, vm_args))
4276 * These are local overrides for various environment variables in Emacs.
4277 * Please do not remove this and leave it at the end of the file, where
4278 * Emacs will automagically detect them.
4279 * ---------------------------------------------------------------------
4282 * indent-tabs-mode: t
4286 * vim:noexpandtab:sw=4:ts=4: