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 8388 2007-08-21 16:24:12Z 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)
940 TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d", env, name, loader, buf, bufLen);
942 u = utf_new_char(name);
943 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
945 c = class_define(u, cl, bufLen, (const uint8_t *) buf);
947 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
949 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
951 /* keep compiler happy */
958 /* FindClass *******************************************************************
960 This function loads a locally-defined class. It searches the
961 directories and zip files specified by the CLASSPATH environment
962 variable for the class with the specified name.
964 *******************************************************************************/
966 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
968 #if defined(ENABLE_JAVASE)
973 STATISTICS(jniinvokation());
975 u = utf_new_char_classname((char *) name);
977 /* Check stacktrace for classloader, if one found use it,
978 otherwise use the system classloader. */
980 /* Quote from the JNI documentation:
982 In the Java 2 Platform, FindClass locates the class loader
983 associated with the current native method. If the native code
984 belongs to a system class, no class loader will be
985 involved. Otherwise, the proper class loader will be invoked to
986 load and link the named class. When FindClass is called through
987 the Invocation Interface, there is no current native method or
988 its associated class loader. In that case, the result of
989 ClassLoader.getBaseClassLoader is used." */
991 cc = stacktrace_getCurrentClass();
994 c = load_class_from_sysloader(u);
996 c = load_class_from_classloader(u, cc->classloader);
1004 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1006 vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1008 /* keep compiler happy */
1015 /* GetSuperclass ***************************************************************
1017 If clazz represents any class other than the class Object, then
1018 this function returns the object that represents the superclass of
1019 the class specified by clazz.
1021 *******************************************************************************/
1023 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1028 TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
1030 c = LLNI_classinfo_unwrap(sub);
1035 super = class_get_superclass(c);
1037 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) super);
1041 /* IsAssignableFrom ************************************************************
1043 Determines whether an object of sub can be safely cast to sup.
1045 *******************************************************************************/
1047 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1049 java_lang_Class *csup;
1050 java_lang_Class *csub;
1052 csup = (java_lang_Class *) sup;
1053 csub = (java_lang_Class *) sub;
1055 STATISTICS(jniinvokation());
1057 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1061 /* Throw ***********************************************************************
1063 Causes a java.lang.Throwable object to be thrown.
1065 *******************************************************************************/
1067 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1071 STATISTICS(jniinvokation());
1073 o = (java_handle_t *) obj;
1075 exceptions_set_exception(o);
1081 /* ThrowNew ********************************************************************
1083 Constructs an exception object from the specified class with the
1084 message specified by message and causes that exception to be
1087 *******************************************************************************/
1089 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1095 STATISTICS(jniinvokation());
1097 c = LLNI_classinfo_unwrap(clazz);
1100 s = javastring_new_from_utf_string(msg);
1102 /* instantiate exception object */
1104 o = native_new_and_init_string(c, s);
1109 exceptions_set_exception(o);
1115 /* ExceptionOccurred ***********************************************************
1117 Determines if an exception is being thrown. The exception stays
1118 being thrown until either the native code calls ExceptionClear(),
1119 or the Java code handles the exception.
1121 *******************************************************************************/
1123 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1127 STATISTICS(jniinvokation());
1129 o = exceptions_get_exception();
1131 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1135 /* ExceptionDescribe ***********************************************************
1137 Prints an exception and a backtrace of the stack to a system
1138 error-reporting channel, such as stderr. This is a convenience
1139 routine provided for debugging.
1141 *******************************************************************************/
1143 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1149 STATISTICS(jniinvokation());
1151 o = exceptions_get_exception();
1154 /* clear exception, because we are calling jit code again */
1156 exceptions_clear_exception();
1158 /* get printStackTrace method from exception class */
1160 LLNI_class_get(o, c);
1162 m = class_resolveclassmethod(c,
1163 utf_printStackTrace,
1169 /* XXX what should we do? */
1172 /* print the stacktrace */
1174 (void) vm_call_method(m, o);
1179 /* ExceptionClear **************************************************************
1181 Clears any exception that is currently being thrown. If no
1182 exception is currently being thrown, this routine has no effect.
1184 *******************************************************************************/
1186 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1188 STATISTICS(jniinvokation());
1190 exceptions_clear_exception();
1194 /* FatalError ******************************************************************
1196 Raises a fatal error and does not expect the VM to recover. This
1197 function does not return.
1199 *******************************************************************************/
1201 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1203 STATISTICS(jniinvokation());
1205 /* this seems to be the best way */
1207 vm_abort("JNI Fatal error: %s", msg);
1211 /* PushLocalFrame **************************************************************
1213 Creates a new local reference frame, in which at least a given
1214 number of local references can be created.
1216 *******************************************************************************/
1218 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1220 STATISTICS(jniinvokation());
1225 /* add new local reference frame to current table */
1227 if (!localref_frame_push(capacity))
1234 /* PopLocalFrame ***************************************************************
1236 Pops off the current local reference frame, frees all the local
1237 references, and returns a local reference in the previous local
1238 reference frame for the given result object.
1240 *******************************************************************************/
1242 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1244 STATISTICS(jniinvokation());
1246 /* release all current local frames */
1248 localref_frame_pop_all();
1250 /* add local reference and return the value */
1252 return _Jv_JNI_NewLocalRef(env, result);
1256 /* DeleteLocalRef **************************************************************
1258 Deletes the local reference pointed to by localRef.
1260 *******************************************************************************/
1262 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1265 localref_table *lrt;
1268 STATISTICS(jniinvokation());
1270 o = (java_handle_t *) localRef;
1272 /* get local reference table (thread specific) */
1274 lrt = LOCALREFTABLE;
1276 /* go through all local frames */
1278 for (; lrt != NULL; lrt = lrt->prev) {
1280 /* and try to remove the reference */
1282 for (i = 0; i < lrt->capacity; i++) {
1283 if (lrt->refs[i] == o) {
1284 lrt->refs[i] = NULL;
1292 /* this should not happen */
1294 /* if (opt_checkjni) */
1295 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1296 log_text("JNI-DeleteLocalRef: Local ref passed to JNI not found");
1300 /* IsSameObject ****************************************************************
1302 Tests whether two references refer to the same Java object.
1304 *******************************************************************************/
1306 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1308 STATISTICS(jniinvokation());
1317 /* NewLocalRef *****************************************************************
1319 Creates a new local reference that refers to the same object as ref.
1321 *******************************************************************************/
1323 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1325 java_handle_t *localref;
1327 STATISTICS(jniinvokation());
1332 /* insert the reference */
1334 localref = localref_add(ref);
1340 /* EnsureLocalCapacity *********************************************************
1342 Ensures that at least a given number of local references can be
1343 created in the current thread
1345 *******************************************************************************/
1347 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1349 localref_table *lrt;
1351 STATISTICS(jniinvokation());
1353 /* get local reference table (thread specific) */
1355 lrt = LOCALREFTABLE;
1357 /* check if capacity elements are available in the local references table */
1359 if ((lrt->used + capacity) > lrt->capacity)
1360 return _Jv_JNI_PushLocalFrame(env, capacity);
1366 /* AllocObject *****************************************************************
1368 Allocates a new Java object without invoking any of the
1369 constructors for the object. Returns a reference to the object.
1371 *******************************************************************************/
1373 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1378 STATISTICS(jniinvokation());
1380 c = LLNI_classinfo_unwrap(clazz);
1382 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1383 exceptions_throw_instantiationexception(c);
1389 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1393 /* NewObject *******************************************************************
1395 Programmers place all arguments that are to be passed to the
1396 constructor immediately following the methodID
1397 argument. NewObject() accepts these arguments and passes them to
1398 the Java method that the programmer wishes to invoke.
1400 *******************************************************************************/
1402 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1409 STATISTICS(jniinvokation());
1411 c = LLNI_classinfo_unwrap(clazz);
1412 m = (methodinfo *) methodID;
1421 /* call constructor */
1423 va_start(ap, methodID);
1424 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1427 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1431 /* NewObjectV ******************************************************************
1433 Programmers place all arguments that are to be passed to the
1434 constructor in an args argument of type va_list that immediately
1435 follows the methodID argument. NewObjectV() accepts these
1436 arguments, and, in turn, passes them to the Java method that the
1437 programmer wishes to invoke.
1439 *******************************************************************************/
1441 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1448 STATISTICS(jniinvokation());
1450 c = LLNI_classinfo_unwrap(clazz);
1451 m = (methodinfo *) methodID;
1460 /* call constructor */
1462 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1464 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1468 /* NewObjectA *****************************************************************
1470 Programmers place all arguments that are to be passed to the
1471 constructor in an args array of jvalues that immediately follows
1472 the methodID argument. NewObjectA() accepts the arguments in this
1473 array, and, in turn, passes them to the Java method that the
1474 programmer wishes to invoke.
1476 *******************************************************************************/
1478 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1485 STATISTICS(jniinvokation());
1487 c = LLNI_classinfo_unwrap(clazz);
1488 m = (methodinfo *) methodID;
1497 /* call constructor */
1499 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1501 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1505 /* GetObjectClass **************************************************************
1507 Returns the class of an object.
1509 *******************************************************************************/
1511 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1516 STATISTICS(jniinvokation());
1518 o = (java_handle_t *) obj;
1520 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1523 LLNI_class_get(o, c);
1525 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1529 /* IsInstanceOf ****************************************************************
1531 Tests whether an object is an instance of a class.
1533 *******************************************************************************/
1535 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1538 java_lang_Object *o;
1540 STATISTICS(jniinvokation());
1542 c = (java_lang_Class *) clazz;
1543 o = (java_lang_Object *) obj;
1545 return _Jv_java_lang_Class_isInstance(c, o);
1549 /* Reflection Support *********************************************************/
1551 /* FromReflectedMethod *********************************************************
1553 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1554 object to a method ID.
1556 *******************************************************************************/
1558 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1560 #if defined(ENABLE_JAVASE)
1566 STATISTICS(jniinvokation());
1568 o = (java_handle_t *) method;
1573 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1574 java_lang_reflect_Method *rm;
1576 rm = (java_lang_reflect_Method *) method;
1577 LLNI_field_get_cls(rm, clazz, c);
1578 LLNI_field_get_val(rm, slot , slot);
1580 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1581 java_lang_reflect_Constructor *rc;
1583 rc = (java_lang_reflect_Constructor *) method;
1584 LLNI_field_get_cls(rc, clazz, c);
1585 LLNI_field_get_val(rc, slot , slot);
1590 m = &(c->methods[slot]);
1592 return (jmethodID) m;
1594 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1596 /* keep compiler happy */
1603 /* FromReflectedField **********************************************************
1605 Converts a java.lang.reflect.Field to a field ID.
1607 *******************************************************************************/
1609 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1611 #if defined(ENABLE_JAVASE)
1612 java_lang_reflect_Field *rf;
1617 STATISTICS(jniinvokation());
1619 rf = (java_lang_reflect_Field *) field;
1624 LLNI_field_get_cls(rf, clazz, c);
1625 LLNI_field_get_val(rf, slot , slot);
1626 f = &(c->fields[slot]);
1628 return (jfieldID) f;
1630 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1632 /* keep compiler happy */
1639 /* ToReflectedMethod ***********************************************************
1641 Converts a method ID derived from cls to an instance of the
1642 java.lang.reflect.Method class or to an instance of the
1643 java.lang.reflect.Constructor class.
1645 *******************************************************************************/
1647 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1650 #if defined(ENABLE_JAVASE)
1652 java_lang_reflect_Constructor *rc;
1653 java_lang_reflect_Method *rm;
1655 STATISTICS(jniinvokation());
1657 m = (methodinfo *) methodID;
1659 /* HotSpot does the same assert. */
1661 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1663 if (m->name == utf_init) {
1664 rc = reflect_constructor_new(m);
1666 return (jobject) rc;
1669 rm = reflect_method_new(m);
1671 return (jobject) rm;
1674 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1676 /* keep compiler happy */
1683 /* ToReflectedField ************************************************************
1685 Converts a field ID derived from cls to an instance of the
1686 java.lang.reflect.Field class.
1688 *******************************************************************************/
1690 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1693 STATISTICS(jniinvokation());
1695 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1701 /* Calling Instance Methods ***************************************************/
1703 /* GetMethodID *****************************************************************
1705 Returns the method ID for an instance (nonstatic) method of a class
1706 or interface. The method may be defined in one of the clazz's
1707 superclasses and inherited by clazz. The method is determined by
1708 its name and signature.
1710 GetMethodID() causes an uninitialized class to be initialized.
1712 *******************************************************************************/
1714 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1722 STATISTICS(jniinvokation());
1724 c = LLNI_classinfo_unwrap(clazz);
1729 if (!(c->state & CLASS_INITIALIZED))
1730 if (!initialize_class(c))
1733 /* try to get the method of the class or one of it's superclasses */
1735 uname = utf_new_char((char *) name);
1736 udesc = utf_new_char((char *) sig);
1738 m = class_resolvemethod(c, uname, udesc);
1740 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1741 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1746 return (jmethodID) m;
1750 /* JNI-functions for calling instance methods *********************************/
1752 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1753 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1754 jmethodID methodID, ...) \
1761 o = (java_handle_t *) obj; \
1762 m = (methodinfo *) methodID; \
1764 va_start(ap, methodID); \
1765 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1771 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1772 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1773 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1774 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1775 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1776 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1777 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1778 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1781 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1782 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1783 jmethodID methodID, va_list args) \
1789 o = (java_handle_t *) obj; \
1790 m = (methodinfo *) methodID; \
1792 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1797 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1798 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1799 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1800 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1801 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1802 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1803 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1804 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1807 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1808 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1809 jmethodID methodID, \
1810 const jvalue *args) \
1816 o = (java_handle_t *) obj; \
1817 m = (methodinfo *) methodID; \
1819 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1824 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1825 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1826 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1827 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1828 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1829 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1830 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1831 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1834 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1842 o = (java_handle_t *) obj;
1843 m = (methodinfo *) methodID;
1845 va_start(ap, methodID);
1846 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1849 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1853 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1860 o = (java_handle_t *) obj;
1861 m = (methodinfo *) methodID;
1863 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1865 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1869 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1876 o = (java_handle_t *) obj;
1877 m = (methodinfo *) methodID;
1879 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1881 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1886 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1892 o = (java_handle_t *) obj;
1893 m = (methodinfo *) methodID;
1895 va_start(ap, methodID);
1896 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1901 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1907 o = (java_handle_t *) obj;
1908 m = (methodinfo *) methodID;
1910 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1914 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1920 o = (java_handle_t *) obj;
1921 m = (methodinfo *) methodID;
1923 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1928 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1929 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1930 jclass clazz, jmethodID methodID, \
1939 o = (java_handle_t *) obj; \
1940 c = LLNI_classinfo_unwrap(clazz); \
1941 m = (methodinfo *) methodID; \
1943 va_start(ap, methodID); \
1944 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1950 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1951 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1952 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1953 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1954 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1955 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1956 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1957 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1960 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1961 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1962 jclass clazz, jmethodID methodID, \
1970 o = (java_handle_t *) obj; \
1971 c = LLNI_classinfo_unwrap(clazz); \
1972 m = (methodinfo *) methodID; \
1974 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1979 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1980 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1981 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1982 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1983 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1984 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1985 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1986 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1989 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1990 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1991 jclass clazz, jmethodID methodID, \
1992 const jvalue *args) \
1994 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
1999 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
2000 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
2001 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
2002 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
2003 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
2004 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
2005 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
2006 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
2008 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2009 jclass clazz, jmethodID methodID,
2018 o = (java_handle_t *) obj;
2019 c = LLNI_classinfo_unwrap(clazz);
2020 m = (methodinfo *) methodID;
2022 va_start(ap, methodID);
2023 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2026 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2030 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2031 jclass clazz, jmethodID methodID,
2039 o = (java_handle_t *) obj;
2040 c = LLNI_classinfo_unwrap(clazz);
2041 m = (methodinfo *) methodID;
2043 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2045 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2049 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2050 jclass clazz, jmethodID methodID,
2053 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2055 return _Jv_JNI_NewLocalRef(env, NULL);
2059 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2060 jmethodID methodID, ...)
2067 o = (java_handle_t *) obj;
2068 c = LLNI_classinfo_unwrap(clazz);
2069 m = (methodinfo *) methodID;
2071 va_start(ap, methodID);
2072 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2077 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2078 jmethodID methodID, va_list args)
2084 o = (java_handle_t *) obj;
2085 c = LLNI_classinfo_unwrap(clazz);
2086 m = (methodinfo *) methodID;
2088 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2092 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2093 jmethodID methodID, const jvalue * args)
2099 o = (java_handle_t *) obj;
2100 c = LLNI_classinfo_unwrap(clazz);
2101 m = (methodinfo *) methodID;
2103 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2107 /* Accessing Fields of Objects ************************************************/
2109 /* GetFieldID ******************************************************************
2111 Returns the field ID for an instance (nonstatic) field of a
2112 class. The field is specified by its name and signature. The
2113 Get<type>Field and Set<type>Field families of accessor functions
2114 use field IDs to retrieve object fields.
2116 *******************************************************************************/
2118 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2126 STATISTICS(jniinvokation());
2128 c = LLNI_classinfo_unwrap(clazz);
2130 /* XXX NPE check? */
2132 uname = utf_new_char((char *) name);
2133 udesc = utf_new_char((char *) sig);
2135 f = class_findfield(c, uname, udesc);
2138 exceptions_throw_nosuchfielderror(c, uname);
2140 return (jfieldID) f;
2144 /* Get<type>Field Routines *****************************************************
2146 This family of accessor routines returns the value of an instance
2147 (nonstatic) field of an object. The field to access is specified by
2148 a field ID obtained by calling GetFieldID().
2150 *******************************************************************************/
2152 #define JNI_GET_FIELD(name, type, intern) \
2153 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2157 STATISTICS(jniinvokation()); \
2159 ret = GET_FIELD(obj, intern, fieldID); \
2161 return (type) ret; \
2164 JNI_GET_FIELD(Boolean, jboolean, s4)
2165 JNI_GET_FIELD(Byte, jbyte, s4)
2166 JNI_GET_FIELD(Char, jchar, s4)
2167 JNI_GET_FIELD(Short, jshort, s4)
2168 JNI_GET_FIELD(Int, jint, s4)
2169 JNI_GET_FIELD(Long, jlong, s8)
2170 JNI_GET_FIELD(Float, jfloat, float)
2171 JNI_GET_FIELD(Double, jdouble, double)
2174 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2178 STATISTICS(jniinvokation());
2180 #warning this needs to be fixed
2181 o = GET_FIELD(obj, java_handle_t*, fieldID);
2183 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2187 /* Set<type>Field Routines *****************************************************
2189 This family of accessor routines sets the value of an instance
2190 (nonstatic) field of an object. The field to access is specified by
2191 a field ID obtained by calling GetFieldID().
2193 *******************************************************************************/
2195 #define JNI_SET_FIELD(name, type, intern) \
2196 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2199 STATISTICS(jniinvokation()); \
2201 SET_FIELD(obj, intern, fieldID, value); \
2204 JNI_SET_FIELD(Boolean, jboolean, s4)
2205 JNI_SET_FIELD(Byte, jbyte, s4)
2206 JNI_SET_FIELD(Char, jchar, s4)
2207 JNI_SET_FIELD(Short, jshort, s4)
2208 JNI_SET_FIELD(Int, jint, s4)
2209 JNI_SET_FIELD(Long, jlong, s8)
2210 JNI_SET_FIELD(Float, jfloat, float)
2211 JNI_SET_FIELD(Double, jdouble, double)
2214 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2217 STATISTICS(jniinvokation());
2219 #warning this needs to be fixed
2220 SET_FIELD(obj, java_handle_t*, fieldID, value);
2224 /* Calling Static Methods *****************************************************/
2226 /* GetStaticMethodID ***********************************************************
2228 Returns the method ID for a static method of a class. The method is
2229 specified by its name and signature.
2231 GetStaticMethodID() causes an uninitialized class to be
2234 *******************************************************************************/
2236 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2244 STATISTICS(jniinvokation());
2246 c = LLNI_classinfo_unwrap(clazz);
2251 if (!(c->state & CLASS_INITIALIZED))
2252 if (!initialize_class(c))
2255 /* try to get the static method of the class */
2257 uname = utf_new_char((char *) name);
2258 udesc = utf_new_char((char *) sig);
2260 m = class_resolvemethod(c, uname, udesc);
2262 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2263 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2268 return (jmethodID) m;
2272 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2273 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2274 jmethodID methodID, ...) \
2280 m = (methodinfo *) methodID; \
2282 va_start(ap, methodID); \
2283 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2289 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2290 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2291 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2292 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2293 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2294 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2295 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2296 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2299 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2300 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2301 jmethodID methodID, va_list args) \
2306 m = (methodinfo *) methodID; \
2308 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2313 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2314 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2315 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2316 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2317 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2318 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2319 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2320 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2323 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2324 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2325 jmethodID methodID, const jvalue *args) \
2330 m = (methodinfo *) methodID; \
2332 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2337 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2338 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2339 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2340 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2341 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2342 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2343 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2344 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2347 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2348 jmethodID methodID, ...)
2354 m = (methodinfo *) methodID;
2356 va_start(ap, methodID);
2357 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2360 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2364 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2365 jmethodID methodID, va_list args)
2370 m = (methodinfo *) methodID;
2372 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2374 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2378 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2379 jmethodID methodID, const jvalue *args)
2384 m = (methodinfo *) methodID;
2386 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2388 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2392 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2393 jmethodID methodID, ...)
2398 m = (methodinfo *) methodID;
2400 va_start(ap, methodID);
2401 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2406 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2407 jmethodID methodID, va_list args)
2411 m = (methodinfo *) methodID;
2413 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2417 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2418 jmethodID methodID, const jvalue * args)
2422 m = (methodinfo *) methodID;
2424 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2428 /* Accessing Static Fields ****************************************************/
2430 /* GetStaticFieldID ************************************************************
2432 Returns the field ID for a static field of a class. The field is
2433 specified by its name and signature. The GetStatic<type>Field and
2434 SetStatic<type>Field families of accessor functions use field IDs
2435 to retrieve static fields.
2437 *******************************************************************************/
2439 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2447 STATISTICS(jniinvokation());
2449 c = LLNI_classinfo_unwrap(clazz);
2451 uname = utf_new_char((char *) name);
2452 usig = utf_new_char((char *) sig);
2454 f = class_findfield(c, uname, usig);
2457 exceptions_throw_nosuchfielderror(c, uname);
2459 return (jfieldID) f;
2463 /* GetStatic<type>Field ********************************************************
2465 This family of accessor routines returns the value of a static
2468 *******************************************************************************/
2470 #define JNI_GET_STATIC_FIELD(name, type, field) \
2471 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2477 STATISTICS(jniinvokation()); \
2479 c = LLNI_classinfo_unwrap(clazz); \
2480 f = (fieldinfo *) fieldID; \
2482 if (!(c->state & CLASS_INITIALIZED)) \
2483 if (!initialize_class(c)) \
2486 return f->value->field; \
2489 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2490 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2491 JNI_GET_STATIC_FIELD(Char, jchar, i)
2492 JNI_GET_STATIC_FIELD(Short, jshort, i)
2493 JNI_GET_STATIC_FIELD(Int, jint, i)
2494 JNI_GET_STATIC_FIELD(Long, jlong, l)
2495 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2496 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2499 jobject _Jv_JNI_GetStaticObjectField(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 _Jv_JNI_NewLocalRef(env, f->value->a);
2518 /* SetStatic<type>Field *******************************************************
2520 This family of accessor routines sets the value of a static field
2523 *******************************************************************************/
2525 #define JNI_SET_STATIC_FIELD(name, type, field) \
2526 void _Jv_JNI_SetStatic##name##Field(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 f->value->field = value; \
2545 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2546 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2547 JNI_SET_STATIC_FIELD(Char, jchar, i)
2548 JNI_SET_STATIC_FIELD(Short, jshort, i)
2549 JNI_SET_STATIC_FIELD(Int, jint, i)
2550 JNI_SET_STATIC_FIELD(Long, jlong, l)
2551 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2552 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2555 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
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->a = value;
2574 /* String Operations **********************************************************/
2576 /* NewString *******************************************************************
2578 Create new java.lang.String object from an array of Unicode
2581 *******************************************************************************/
2583 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2585 java_lang_String *s;
2586 java_handle_chararray_t *a;
2589 STATISTICS(jniinvokation());
2591 s = (java_lang_String *) builtin_new(class_java_lang_String);
2592 a = builtin_newarray_char(len);
2594 /* javastring or characterarray could not be created */
2595 if ((a == NULL) || (s == NULL))
2599 for (i = 0; i < len; i++)
2600 LLNI_array_direct(a, i) = buf[i];
2602 LLNI_field_set_ref(s, value , a);
2603 LLNI_field_set_val(s, offset, 0);
2604 LLNI_field_set_val(s, count , len);
2606 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2610 static jchar emptyStringJ[]={0,0};
2612 /* GetStringLength *************************************************************
2614 Returns the length (the count of Unicode characters) of a Java
2617 *******************************************************************************/
2619 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2621 java_lang_String *s;
2624 TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
2626 s = (java_lang_String *) str;
2628 LLNI_field_get_val(s, count, len);
2634 /******************** convertes javastring to u2-array ****************************/
2636 u2 *javastring_tou2(jstring so)
2638 java_lang_String *s;
2639 java_handle_chararray_t *a;
2645 STATISTICS(jniinvokation());
2647 s = (java_lang_String *) so;
2652 LLNI_field_get_ref(s, value, a);
2657 LLNI_field_get_val(s, count, count);
2658 LLNI_field_get_val(s, offset, offset);
2660 /* allocate memory */
2662 stringbuffer = MNEW(u2, count + 1);
2666 for (i = 0; i < count; i++)
2667 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2669 /* terminate string */
2671 stringbuffer[i] = '\0';
2673 return stringbuffer;
2677 /* GetStringChars **************************************************************
2679 Returns a pointer to the array of Unicode characters of the
2680 string. This pointer is valid until ReleaseStringChars() is called.
2682 *******************************************************************************/
2684 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2688 STATISTICS(jniinvokation());
2690 jc = javastring_tou2(str);
2702 return emptyStringJ;
2706 /* ReleaseStringChars **********************************************************
2708 Informs the VM that the native code no longer needs access to
2709 chars. The chars argument is a pointer obtained from string using
2712 *******************************************************************************/
2714 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2716 java_lang_String *s;
2718 STATISTICS(jniinvokation());
2720 if (chars == emptyStringJ)
2723 s = (java_lang_String *) str;
2725 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2729 /* NewStringUTF ****************************************************************
2731 Constructs a new java.lang.String object from an array of UTF-8
2734 *******************************************************************************/
2736 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2738 java_lang_String *s;
2740 TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
2742 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2744 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2748 /****************** returns the utf8 length in bytes of a string *******************/
2750 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2752 java_lang_String *s;
2755 TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
2757 s = (java_lang_String *) string;
2759 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2765 /* GetStringUTFChars ***********************************************************
2767 Returns a pointer to an array of UTF-8 characters of the
2768 string. This array is valid until it is released by
2769 ReleaseStringUTFChars().
2771 *******************************************************************************/
2773 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2778 STATISTICS(jniinvokation());
2786 u = javastring_toutf((java_handle_t *) string, false);
2795 /* ReleaseStringUTFChars *******************************************************
2797 Informs the VM that the native code no longer needs access to
2798 utf. The utf argument is a pointer derived from string using
2799 GetStringUTFChars().
2801 *******************************************************************************/
2803 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2805 STATISTICS(jniinvokation());
2807 /* XXX we don't release utf chars right now, perhaps that should be done
2808 later. Since there is always one reference the garbage collector will
2813 /* Array Operations ***********************************************************/
2815 /* GetArrayLength **************************************************************
2817 Returns the number of elements in the array.
2819 *******************************************************************************/
2821 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2826 STATISTICS(jniinvokation());
2828 a = (java_handle_t *) array;
2830 size = LLNI_array_size(a);
2836 /* NewObjectArray **************************************************************
2838 Constructs a new array holding objects in class elementClass. All
2839 elements are initially set to initialElement.
2841 *******************************************************************************/
2843 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2844 jclass elementClass, jobject initialElement)
2848 java_handle_objectarray_t *oa;
2851 STATISTICS(jniinvokation());
2853 c = LLNI_classinfo_unwrap(elementClass);
2854 o = (java_handle_t *) initialElement;
2857 exceptions_throw_negativearraysizeexception();
2861 oa = builtin_anewarray(length, c);
2866 /* set all elements to initialElement */
2868 for (i = 0; i < length; i++)
2869 LLNI_objectarray_element_set(oa, i, o);
2871 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2875 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2878 java_handle_objectarray_t *oa;
2881 STATISTICS(jniinvokation());
2883 oa = (java_handle_objectarray_t *) array;
2885 if (index >= LLNI_array_size(oa)) {
2886 exceptions_throw_arrayindexoutofboundsexception();
2890 LLNI_objectarray_element_get(oa, index, o);
2892 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2896 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2897 jsize index, jobject val)
2899 java_handle_objectarray_t *oa;
2902 STATISTICS(jniinvokation());
2904 oa = (java_handle_objectarray_t *) array;
2905 o = (java_handle_t *) val;
2907 if (index >= LLNI_array_size(oa)) {
2908 exceptions_throw_arrayindexoutofboundsexception();
2912 /* check if the class of value is a subclass of the element class
2915 if (!builtin_canstore(oa, o))
2918 LLNI_objectarray_element_set(oa, index, o);
2922 #define JNI_NEW_ARRAY(name, type, intern) \
2923 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2925 java_handle_##intern##array_t *a; \
2927 STATISTICS(jniinvokation()); \
2930 exceptions_throw_negativearraysizeexception(); \
2934 a = builtin_newarray_##intern(len); \
2936 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2939 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2940 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2941 JNI_NEW_ARRAY(Char, jcharArray, char)
2942 JNI_NEW_ARRAY(Short, jshortArray, byte)
2943 JNI_NEW_ARRAY(Int, jintArray, int)
2944 JNI_NEW_ARRAY(Long, jlongArray, long)
2945 JNI_NEW_ARRAY(Float, jfloatArray, float)
2946 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2949 /* Get<PrimitiveType>ArrayElements *********************************************
2951 A family of functions that returns the body of the primitive array.
2953 *******************************************************************************/
2955 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2956 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2959 java_handle_##intern##array_t *a; \
2961 STATISTICS(jniinvokation()); \
2963 a = (java_handle_##intern##array_t *) array; \
2966 *isCopy = JNI_FALSE; \
2968 return LLNI_array_data(a); \
2971 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2972 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2973 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2974 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2975 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2976 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2977 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2978 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
2981 /* Release<PrimitiveType>ArrayElements *****************************************
2983 A family of functions that informs the VM that the native code no
2984 longer needs access to elems. The elems argument is a pointer
2985 derived from array using the corresponding
2986 Get<PrimitiveType>ArrayElements() function. If necessary, this
2987 function copies back all changes made to elems to the original
2990 *******************************************************************************/
2992 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
2993 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
2994 type *elems, jint mode) \
2996 java_handle_##intern##array_t *a; \
2998 STATISTICS(jniinvokation()); \
3000 a = (java_handle_##intern##array_t *) array; \
3002 if (elems != LLNI_array_data(a)) { \
3005 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3008 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3009 /* XXX TWISTI how should it be freed? */ \
3012 /* XXX TWISTI how should it be freed? */ \
3018 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3019 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3020 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3021 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3022 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3023 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3024 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3025 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3028 /* Get<PrimitiveType>ArrayRegion **********************************************
3030 A family of functions that copies a region of a primitive array
3033 *******************************************************************************/
3035 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3036 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3037 jsize start, jsize len, type *buf) \
3039 java_handle_##intern##array_t *a; \
3041 STATISTICS(jniinvokation()); \
3043 a = (java_handle_##intern##array_t *) array; \
3045 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3046 exceptions_throw_arrayindexoutofboundsexception(); \
3048 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3051 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3052 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3053 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3054 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3055 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3056 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3057 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3058 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3061 /* Set<PrimitiveType>ArrayRegion **********************************************
3063 A family of functions that copies back a region of a primitive
3064 array from a buffer.
3066 *******************************************************************************/
3068 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3069 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3070 jsize start, jsize len, const type *buf) \
3072 java_handle_##intern##array_t *a; \
3074 STATISTICS(jniinvokation()); \
3076 a = (java_handle_##intern##array_t *) array; \
3078 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3079 exceptions_throw_arrayindexoutofboundsexception(); \
3081 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3084 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3085 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3086 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3087 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3088 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3089 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3090 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3091 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3094 /* Registering Native Methods *************************************************/
3096 /* RegisterNatives *************************************************************
3098 Registers native methods with the class specified by the clazz
3099 argument. The methods parameter specifies an array of
3100 JNINativeMethod structures that contain the names, signatures, and
3101 function pointers of the native methods. The nMethods parameter
3102 specifies the number of native methods in the array.
3104 *******************************************************************************/
3106 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3107 const JNINativeMethod *methods, jint nMethods)
3111 STATISTICS(jniinvokation());
3113 c = LLNI_classinfo_unwrap(clazz);
3115 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3116 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3119 native_method_register(c->name, methods, nMethods);
3125 /* UnregisterNatives ***********************************************************
3127 Unregisters native methods of a class. The class goes back to the
3128 state before it was linked or registered with its native method
3131 This function should not be used in normal native code. Instead, it
3132 provides special programs a way to reload and relink native
3135 *******************************************************************************/
3137 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3139 STATISTICS(jniinvokation());
3141 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3143 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3149 /* Monitor Operations *********************************************************/
3151 /* MonitorEnter ****************************************************************
3153 Enters the monitor associated with the underlying Java object
3156 *******************************************************************************/
3158 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3160 STATISTICS(jniinvokation());
3163 exceptions_throw_nullpointerexception();
3167 LOCK_MONITOR_ENTER(obj);
3173 /* MonitorExit *****************************************************************
3175 The current thread must be the owner of the monitor associated with
3176 the underlying Java object referred to by obj. The thread
3177 decrements the counter indicating the number of times it has
3178 entered this monitor. If the value of the counter becomes zero, the
3179 current thread releases the monitor.
3181 *******************************************************************************/
3183 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3185 STATISTICS(jniinvokation());
3188 exceptions_throw_nullpointerexception();
3192 LOCK_MONITOR_EXIT(obj);
3198 /* JavaVM Interface ***********************************************************/
3200 /* GetJavaVM *******************************************************************
3202 Returns the Java VM interface (used in the Invocation API)
3203 associated with the current thread. The result is placed at the
3204 location pointed to by the second argument, vm.
3206 *******************************************************************************/
3208 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3210 STATISTICS(jniinvokation());
3212 *vm = (JavaVM *) _Jv_jvm;
3218 /* GetStringRegion *************************************************************
3220 Copies len number of Unicode characters beginning at offset start
3221 to the given buffer buf.
3223 Throws StringIndexOutOfBoundsException on index overflow.
3225 *******************************************************************************/
3227 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3230 java_lang_String *s;
3231 java_handle_chararray_t *ca;
3233 STATISTICS(jniinvokation());
3235 s = (java_lang_String *) str;
3236 LLNI_field_get_ref(s, value, ca);
3238 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3239 (start + len > LLNI_field_direct(s, count))) {
3240 exceptions_throw_stringindexoutofboundsexception();
3244 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3248 /* GetStringUTFRegion **********************************************************
3250 Translates len number of Unicode characters beginning at offset
3251 start into UTF-8 format and place the result in the given buffer
3254 Throws StringIndexOutOfBoundsException on index overflow.
3256 *******************************************************************************/
3258 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3259 jsize len, char *buf)
3261 java_lang_String *s;
3262 java_handle_chararray_t *ca;
3267 TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
3269 s = (java_lang_String *) str;
3270 LLNI_field_get_ref(s, value, ca);
3271 LLNI_field_get_val(s, count, count);
3272 LLNI_field_get_val(s, offset, offset);
3274 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3275 exceptions_throw_stringindexoutofboundsexception();
3279 for (i = 0; i < len; i++)
3280 buf[i] = LLNI_array_direct(ca, offset + start + i);
3286 /* GetPrimitiveArrayCritical ***************************************************
3288 Obtain a direct pointer to array elements.
3290 *******************************************************************************/
3292 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3295 java_handle_bytearray_t *ba;
3298 ba = (java_handle_bytearray_t *) array;
3300 /* do the same as Kaffe does */
3302 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3308 /* ReleasePrimitiveArrayCritical ***********************************************
3310 No specific documentation.
3312 *******************************************************************************/
3314 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3315 void *carray, jint mode)
3317 STATISTICS(jniinvokation());
3319 /* do the same as Kaffe does */
3321 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3326 /* GetStringCritical ***********************************************************
3328 The semantics of these two functions are similar to the existing
3329 Get/ReleaseStringChars functions.
3331 *******************************************************************************/
3333 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3336 STATISTICS(jniinvokation());
3338 return _Jv_JNI_GetStringChars(env, string, isCopy);
3342 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3343 const jchar *cstring)
3345 STATISTICS(jniinvokation());
3347 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3351 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3353 STATISTICS(jniinvokation());
3355 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
3361 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3363 STATISTICS(jniinvokation());
3365 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
3369 /* NewGlobalRef ****************************************************************
3371 Creates a new global reference to the object referred to by the obj
3374 *******************************************************************************/
3376 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3378 hashtable_global_ref_entry *gre;
3379 u4 key; /* hashkey */
3380 u4 slot; /* slot in hashtable */
3383 STATISTICS(jniinvokation());
3385 o = (java_handle_t *) obj;
3387 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3389 /* normally addresses are aligned to 4, 8 or 16 bytes */
3391 key = ((u4) (ptrint) obj) >> 4; /* align to 16-byte boundaries */
3392 slot = key & (hashtable_global_ref->size - 1);
3393 gre = hashtable_global_ref->ptr[slot];
3395 /* search external hash chain for the entry */
3399 /* global object found, increment the reference */
3403 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3408 gre = gre->hashlink; /* next element in external chain */
3411 /* global ref not found, create a new one */
3413 gre = NEW(hashtable_global_ref_entry);
3415 #if defined(ENABLE_GC_CACAO)
3416 /* register global ref with the GC */
3418 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3424 /* insert entry into hashtable */
3426 gre->hashlink = hashtable_global_ref->ptr[slot];
3428 hashtable_global_ref->ptr[slot] = gre;
3430 /* update number of hashtable-entries */
3432 hashtable_global_ref->entries++;
3434 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3440 /* DeleteGlobalRef *************************************************************
3442 Deletes the global reference pointed to by globalRef.
3444 *******************************************************************************/
3446 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3448 hashtable_global_ref_entry *gre;
3449 hashtable_global_ref_entry *prevgre;
3450 u4 key; /* hashkey */
3451 u4 slot; /* slot in hashtable */
3454 STATISTICS(jniinvokation());
3456 o = (java_handle_t *) globalRef;
3458 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3460 /* normally addresses are aligned to 4, 8 or 16 bytes */
3462 key = ((u4) (ptrint) globalRef) >> 4; /* align to 16-byte boundaries */
3463 slot = key & (hashtable_global_ref->size - 1);
3464 gre = hashtable_global_ref->ptr[slot];
3466 /* initialize prevgre */
3470 /* search external hash chain for the entry */
3474 /* global object found, decrement the reference count */
3478 /* if reference count is 0, remove the entry */
3480 if (gre->refs == 0) {
3481 /* special handling if it's the first in the chain */
3483 if (prevgre == NULL)
3484 hashtable_global_ref->ptr[slot] = gre->hashlink;
3486 prevgre->hashlink = gre->hashlink;
3488 #if defined(ENABLE_GC_CACAO)
3489 /* unregister global ref with the GC */
3491 gc_reference_unregister(&(gre->o));
3494 FREE(gre, hashtable_global_ref_entry);
3497 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3502 prevgre = gre; /* save current pointer for removal */
3503 gre = gre->hashlink; /* next element in external chain */
3506 log_println("JNI-DeleteGlobalRef: global reference not found");
3508 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3512 /* ExceptionCheck **************************************************************
3514 Returns JNI_TRUE when there is a pending exception; otherwise,
3517 *******************************************************************************/
3519 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3523 STATISTICS(jniinvokation());
3525 o = exceptions_get_exception();
3527 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3531 /* New JNI 1.4 functions ******************************************************/
3533 /* NewDirectByteBuffer *********************************************************
3535 Allocates and returns a direct java.nio.ByteBuffer referring to the
3536 block of memory starting at the memory address address and
3537 extending capacity bytes.
3539 *******************************************************************************/
3541 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3543 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3544 java_handle_t *nbuf;
3546 # if SIZEOF_VOID_P == 8
3547 gnu_classpath_Pointer64 *paddress;
3549 gnu_classpath_Pointer32 *paddress;
3552 STATISTICS(jniinvokation());
3554 /* alocate a gnu.classpath.Pointer{32,64} object */
3556 # if SIZEOF_VOID_P == 8
3557 if (!(paddress = (gnu_classpath_Pointer64 *)
3558 builtin_new(class_gnu_classpath_Pointer64)))
3560 if (!(paddress = (gnu_classpath_Pointer32 *)
3561 builtin_new(class_gnu_classpath_Pointer32)))
3565 /* fill gnu.classpath.Pointer{32,64} with address */
3567 LLNI_field_set_val(paddress, data, (ptrint) address);
3569 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3571 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3572 (jmethodID) dbbirw_init, NULL, paddress,
3573 (jint) capacity, (jint) capacity, (jint) 0);
3575 /* add local reference and return the value */
3577 return _Jv_JNI_NewLocalRef(env, nbuf);
3579 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3581 /* keep compiler happy */
3588 /* GetDirectBufferAddress ******************************************************
3590 Fetches and returns the starting address of the memory region
3591 referenced by the given direct java.nio.Buffer.
3593 *******************************************************************************/
3595 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3597 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3598 java_nio_DirectByteBufferImpl *nbuf;
3599 # if SIZEOF_VOID_P == 8
3600 gnu_classpath_Pointer64 *paddress;
3602 gnu_classpath_Pointer32 *paddress;
3606 STATISTICS(jniinvokation());
3608 if (!builtin_instanceof(buf, class_java_nio_Buffer))
3611 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3613 # if SIZEOF_VOID_P == 8
3614 LLNI_field_get_ref(nbuf, address, paddress);
3615 /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
3617 LLNI_field_get_ref(nbuf, address, paddress);
3618 /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
3621 if (paddress == NULL)
3624 LLNI_field_get_val(paddress, data, address);
3625 /* this was the cast to avaoid warning: (void *) paddress->data */
3629 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3631 /* keep compiler happy */
3638 /* GetDirectBufferCapacity *****************************************************
3640 Fetches and returns the capacity in bytes of the memory region
3641 referenced by the given direct java.nio.Buffer.
3643 *******************************************************************************/
3645 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3647 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3649 java_nio_Buffer *nbuf;
3652 STATISTICS(jniinvokation());
3654 o = (java_handle_t *) buf;
3656 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3659 nbuf = (java_nio_Buffer *) o;
3661 LLNI_field_get_val(nbuf, cap, capacity);
3665 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3667 /* keep compiler happy */
3674 /* DestroyJavaVM ***************************************************************
3676 Unloads a Java VM and reclaims its resources. Only the main thread
3677 can unload the VM. The system waits until the main thread is only
3678 remaining user thread before it destroys the VM.
3680 *******************************************************************************/
3682 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3686 STATISTICS(jniinvokation());
3688 status = vm_destroy(vm);
3694 /* AttachCurrentThread *********************************************************
3696 Attaches the current thread to a Java VM. Returns a JNI interface
3697 pointer in the JNIEnv argument.
3699 Trying to attach a thread that is already attached is a no-op.
3701 A native thread cannot be attached simultaneously to two Java VMs.
3703 When a thread is attached to the VM, the context class loader is
3704 the bootstrap loader.
3706 *******************************************************************************/
3708 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3710 JavaVMAttachArgs *vm_aargs;
3712 #if defined(ENABLE_THREADS)
3713 if (threads_get_current_threadobject() == NULL) {
3714 vm_aargs = (JavaVMAttachArgs *) thr_args;
3716 if (vm_aargs != NULL) {
3717 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3718 (vm_aargs->version != JNI_VERSION_1_4))
3719 return JNI_EVERSION;
3722 if (!threads_attach_current_thread(vm_aargs, false))
3725 if (!localref_table_init())
3736 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3738 STATISTICS(jniinvokation());
3740 return jni_attach_current_thread(p_env, thr_args, false);
3744 /* DetachCurrentThread *********************************************************
3746 Detaches the current thread from a Java VM. All Java monitors held
3747 by this thread are released. All Java threads waiting for this
3748 thread to die are notified.
3750 In JDK 1.1, the main thread cannot be detached from the VM. It must
3751 call DestroyJavaVM to unload the entire VM.
3753 In the JDK, the main thread can be detached from the VM.
3755 The main thread, which is the thread that created the Java VM,
3756 cannot be detached from the VM. Instead, the main thread must call
3757 JNI_DestroyJavaVM() to unload the entire VM.
3759 *******************************************************************************/
3761 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3763 #if defined(ENABLE_THREADS)
3764 threadobject *thread;
3766 STATISTICS(jniinvokation());
3768 thread = threads_get_current_threadobject();
3773 if (!localref_table_destroy())
3776 if (!threads_detach_thread(thread))
3784 /* GetEnv **********************************************************************
3786 If the current thread is not attached to the VM, sets *env to NULL,
3787 and returns JNI_EDETACHED. If the specified version is not
3788 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3789 sets *env to the appropriate interface, and returns JNI_OK.
3791 *******************************************************************************/
3793 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3795 STATISTICS(jniinvokation());
3797 #if defined(ENABLE_THREADS)
3798 if (threads_get_current_threadobject() == NULL) {
3801 return JNI_EDETACHED;
3805 /* check the JNI version */
3808 case JNI_VERSION_1_1:
3809 case JNI_VERSION_1_2:
3810 case JNI_VERSION_1_4:
3818 #if defined(ENABLE_JVMTI)
3819 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3820 == JVMTI_VERSION_INTERFACE_JVMTI) {
3822 *env = (void *) jvmti_new_environment();
3831 return JNI_EVERSION;
3835 /* AttachCurrentThreadAsDaemon *************************************************
3837 Same semantics as AttachCurrentThread, but the newly-created
3838 java.lang.Thread instance is a daemon.
3840 If the thread has already been attached via either
3841 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3842 simply sets the value pointed to by penv to the JNIEnv of the
3843 current thread. In this case neither AttachCurrentThread nor this
3844 routine have any effect on the daemon status of the thread.
3846 *******************************************************************************/
3848 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3850 STATISTICS(jniinvokation());
3852 return jni_attach_current_thread(penv, args, true);
3856 /* JNI invocation table *******************************************************/
3858 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3863 _Jv_JNI_DestroyJavaVM,
3864 _Jv_JNI_AttachCurrentThread,
3865 _Jv_JNI_DetachCurrentThread,
3867 _Jv_JNI_AttachCurrentThreadAsDaemon
3871 /* JNI function table *********************************************************/
3873 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3880 _Jv_JNI_DefineClass,
3882 _Jv_JNI_FromReflectedMethod,
3883 _Jv_JNI_FromReflectedField,
3884 _Jv_JNI_ToReflectedMethod,
3885 _Jv_JNI_GetSuperclass,
3886 _Jv_JNI_IsAssignableFrom,
3887 _Jv_JNI_ToReflectedField,
3891 _Jv_JNI_ExceptionOccurred,
3892 _Jv_JNI_ExceptionDescribe,
3893 _Jv_JNI_ExceptionClear,
3895 _Jv_JNI_PushLocalFrame,
3896 _Jv_JNI_PopLocalFrame,
3898 _Jv_JNI_NewGlobalRef,
3899 _Jv_JNI_DeleteGlobalRef,
3900 _Jv_JNI_DeleteLocalRef,
3901 _Jv_JNI_IsSameObject,
3902 _Jv_JNI_NewLocalRef,
3903 _Jv_JNI_EnsureLocalCapacity,
3905 _Jv_JNI_AllocObject,
3910 _Jv_JNI_GetObjectClass,
3911 _Jv_JNI_IsInstanceOf,
3913 _Jv_JNI_GetMethodID,
3915 _Jv_JNI_CallObjectMethod,
3916 _Jv_JNI_CallObjectMethodV,
3917 _Jv_JNI_CallObjectMethodA,
3918 _Jv_JNI_CallBooleanMethod,
3919 _Jv_JNI_CallBooleanMethodV,
3920 _Jv_JNI_CallBooleanMethodA,
3921 _Jv_JNI_CallByteMethod,
3922 _Jv_JNI_CallByteMethodV,
3923 _Jv_JNI_CallByteMethodA,
3924 _Jv_JNI_CallCharMethod,
3925 _Jv_JNI_CallCharMethodV,
3926 _Jv_JNI_CallCharMethodA,
3927 _Jv_JNI_CallShortMethod,
3928 _Jv_JNI_CallShortMethodV,
3929 _Jv_JNI_CallShortMethodA,
3930 _Jv_JNI_CallIntMethod,
3931 _Jv_JNI_CallIntMethodV,
3932 _Jv_JNI_CallIntMethodA,
3933 _Jv_JNI_CallLongMethod,
3934 _Jv_JNI_CallLongMethodV,
3935 _Jv_JNI_CallLongMethodA,
3936 _Jv_JNI_CallFloatMethod,
3937 _Jv_JNI_CallFloatMethodV,
3938 _Jv_JNI_CallFloatMethodA,
3939 _Jv_JNI_CallDoubleMethod,
3940 _Jv_JNI_CallDoubleMethodV,
3941 _Jv_JNI_CallDoubleMethodA,
3942 _Jv_JNI_CallVoidMethod,
3943 _Jv_JNI_CallVoidMethodV,
3944 _Jv_JNI_CallVoidMethodA,
3946 _Jv_JNI_CallNonvirtualObjectMethod,
3947 _Jv_JNI_CallNonvirtualObjectMethodV,
3948 _Jv_JNI_CallNonvirtualObjectMethodA,
3949 _Jv_JNI_CallNonvirtualBooleanMethod,
3950 _Jv_JNI_CallNonvirtualBooleanMethodV,
3951 _Jv_JNI_CallNonvirtualBooleanMethodA,
3952 _Jv_JNI_CallNonvirtualByteMethod,
3953 _Jv_JNI_CallNonvirtualByteMethodV,
3954 _Jv_JNI_CallNonvirtualByteMethodA,
3955 _Jv_JNI_CallNonvirtualCharMethod,
3956 _Jv_JNI_CallNonvirtualCharMethodV,
3957 _Jv_JNI_CallNonvirtualCharMethodA,
3958 _Jv_JNI_CallNonvirtualShortMethod,
3959 _Jv_JNI_CallNonvirtualShortMethodV,
3960 _Jv_JNI_CallNonvirtualShortMethodA,
3961 _Jv_JNI_CallNonvirtualIntMethod,
3962 _Jv_JNI_CallNonvirtualIntMethodV,
3963 _Jv_JNI_CallNonvirtualIntMethodA,
3964 _Jv_JNI_CallNonvirtualLongMethod,
3965 _Jv_JNI_CallNonvirtualLongMethodV,
3966 _Jv_JNI_CallNonvirtualLongMethodA,
3967 _Jv_JNI_CallNonvirtualFloatMethod,
3968 _Jv_JNI_CallNonvirtualFloatMethodV,
3969 _Jv_JNI_CallNonvirtualFloatMethodA,
3970 _Jv_JNI_CallNonvirtualDoubleMethod,
3971 _Jv_JNI_CallNonvirtualDoubleMethodV,
3972 _Jv_JNI_CallNonvirtualDoubleMethodA,
3973 _Jv_JNI_CallNonvirtualVoidMethod,
3974 _Jv_JNI_CallNonvirtualVoidMethodV,
3975 _Jv_JNI_CallNonvirtualVoidMethodA,
3979 _Jv_JNI_GetObjectField,
3980 _Jv_JNI_GetBooleanField,
3981 _Jv_JNI_GetByteField,
3982 _Jv_JNI_GetCharField,
3983 _Jv_JNI_GetShortField,
3984 _Jv_JNI_GetIntField,
3985 _Jv_JNI_GetLongField,
3986 _Jv_JNI_GetFloatField,
3987 _Jv_JNI_GetDoubleField,
3988 _Jv_JNI_SetObjectField,
3989 _Jv_JNI_SetBooleanField,
3990 _Jv_JNI_SetByteField,
3991 _Jv_JNI_SetCharField,
3992 _Jv_JNI_SetShortField,
3993 _Jv_JNI_SetIntField,
3994 _Jv_JNI_SetLongField,
3995 _Jv_JNI_SetFloatField,
3996 _Jv_JNI_SetDoubleField,
3998 _Jv_JNI_GetStaticMethodID,
4000 _Jv_JNI_CallStaticObjectMethod,
4001 _Jv_JNI_CallStaticObjectMethodV,
4002 _Jv_JNI_CallStaticObjectMethodA,
4003 _Jv_JNI_CallStaticBooleanMethod,
4004 _Jv_JNI_CallStaticBooleanMethodV,
4005 _Jv_JNI_CallStaticBooleanMethodA,
4006 _Jv_JNI_CallStaticByteMethod,
4007 _Jv_JNI_CallStaticByteMethodV,
4008 _Jv_JNI_CallStaticByteMethodA,
4009 _Jv_JNI_CallStaticCharMethod,
4010 _Jv_JNI_CallStaticCharMethodV,
4011 _Jv_JNI_CallStaticCharMethodA,
4012 _Jv_JNI_CallStaticShortMethod,
4013 _Jv_JNI_CallStaticShortMethodV,
4014 _Jv_JNI_CallStaticShortMethodA,
4015 _Jv_JNI_CallStaticIntMethod,
4016 _Jv_JNI_CallStaticIntMethodV,
4017 _Jv_JNI_CallStaticIntMethodA,
4018 _Jv_JNI_CallStaticLongMethod,
4019 _Jv_JNI_CallStaticLongMethodV,
4020 _Jv_JNI_CallStaticLongMethodA,
4021 _Jv_JNI_CallStaticFloatMethod,
4022 _Jv_JNI_CallStaticFloatMethodV,
4023 _Jv_JNI_CallStaticFloatMethodA,
4024 _Jv_JNI_CallStaticDoubleMethod,
4025 _Jv_JNI_CallStaticDoubleMethodV,
4026 _Jv_JNI_CallStaticDoubleMethodA,
4027 _Jv_JNI_CallStaticVoidMethod,
4028 _Jv_JNI_CallStaticVoidMethodV,
4029 _Jv_JNI_CallStaticVoidMethodA,
4031 _Jv_JNI_GetStaticFieldID,
4033 _Jv_JNI_GetStaticObjectField,
4034 _Jv_JNI_GetStaticBooleanField,
4035 _Jv_JNI_GetStaticByteField,
4036 _Jv_JNI_GetStaticCharField,
4037 _Jv_JNI_GetStaticShortField,
4038 _Jv_JNI_GetStaticIntField,
4039 _Jv_JNI_GetStaticLongField,
4040 _Jv_JNI_GetStaticFloatField,
4041 _Jv_JNI_GetStaticDoubleField,
4042 _Jv_JNI_SetStaticObjectField,
4043 _Jv_JNI_SetStaticBooleanField,
4044 _Jv_JNI_SetStaticByteField,
4045 _Jv_JNI_SetStaticCharField,
4046 _Jv_JNI_SetStaticShortField,
4047 _Jv_JNI_SetStaticIntField,
4048 _Jv_JNI_SetStaticLongField,
4049 _Jv_JNI_SetStaticFloatField,
4050 _Jv_JNI_SetStaticDoubleField,
4053 _Jv_JNI_GetStringLength,
4054 _Jv_JNI_GetStringChars,
4055 _Jv_JNI_ReleaseStringChars,
4057 _Jv_JNI_NewStringUTF,
4058 _Jv_JNI_GetStringUTFLength,
4059 _Jv_JNI_GetStringUTFChars,
4060 _Jv_JNI_ReleaseStringUTFChars,
4062 _Jv_JNI_GetArrayLength,
4064 _Jv_JNI_NewObjectArray,
4065 _Jv_JNI_GetObjectArrayElement,
4066 _Jv_JNI_SetObjectArrayElement,
4068 _Jv_JNI_NewBooleanArray,
4069 _Jv_JNI_NewByteArray,
4070 _Jv_JNI_NewCharArray,
4071 _Jv_JNI_NewShortArray,
4072 _Jv_JNI_NewIntArray,
4073 _Jv_JNI_NewLongArray,
4074 _Jv_JNI_NewFloatArray,
4075 _Jv_JNI_NewDoubleArray,
4077 _Jv_JNI_GetBooleanArrayElements,
4078 _Jv_JNI_GetByteArrayElements,
4079 _Jv_JNI_GetCharArrayElements,
4080 _Jv_JNI_GetShortArrayElements,
4081 _Jv_JNI_GetIntArrayElements,
4082 _Jv_JNI_GetLongArrayElements,
4083 _Jv_JNI_GetFloatArrayElements,
4084 _Jv_JNI_GetDoubleArrayElements,
4086 _Jv_JNI_ReleaseBooleanArrayElements,
4087 _Jv_JNI_ReleaseByteArrayElements,
4088 _Jv_JNI_ReleaseCharArrayElements,
4089 _Jv_JNI_ReleaseShortArrayElements,
4090 _Jv_JNI_ReleaseIntArrayElements,
4091 _Jv_JNI_ReleaseLongArrayElements,
4092 _Jv_JNI_ReleaseFloatArrayElements,
4093 _Jv_JNI_ReleaseDoubleArrayElements,
4095 _Jv_JNI_GetBooleanArrayRegion,
4096 _Jv_JNI_GetByteArrayRegion,
4097 _Jv_JNI_GetCharArrayRegion,
4098 _Jv_JNI_GetShortArrayRegion,
4099 _Jv_JNI_GetIntArrayRegion,
4100 _Jv_JNI_GetLongArrayRegion,
4101 _Jv_JNI_GetFloatArrayRegion,
4102 _Jv_JNI_GetDoubleArrayRegion,
4103 _Jv_JNI_SetBooleanArrayRegion,
4104 _Jv_JNI_SetByteArrayRegion,
4105 _Jv_JNI_SetCharArrayRegion,
4106 _Jv_JNI_SetShortArrayRegion,
4107 _Jv_JNI_SetIntArrayRegion,
4108 _Jv_JNI_SetLongArrayRegion,
4109 _Jv_JNI_SetFloatArrayRegion,
4110 _Jv_JNI_SetDoubleArrayRegion,
4112 _Jv_JNI_RegisterNatives,
4113 _Jv_JNI_UnregisterNatives,
4115 _Jv_JNI_MonitorEnter,
4116 _Jv_JNI_MonitorExit,
4120 /* new JNI 1.2 functions */
4122 _Jv_JNI_GetStringRegion,
4123 _Jv_JNI_GetStringUTFRegion,
4125 _Jv_JNI_GetPrimitiveArrayCritical,
4126 _Jv_JNI_ReleasePrimitiveArrayCritical,
4128 _Jv_JNI_GetStringCritical,
4129 _Jv_JNI_ReleaseStringCritical,
4131 _Jv_JNI_NewWeakGlobalRef,
4132 _Jv_JNI_DeleteWeakGlobalRef,
4134 _Jv_JNI_ExceptionCheck,
4136 /* new JNI 1.4 functions */
4138 _Jv_JNI_NewDirectByteBuffer,
4139 _Jv_JNI_GetDirectBufferAddress,
4140 _Jv_JNI_GetDirectBufferCapacity
4144 /* Invocation API Functions ***************************************************/
4146 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4148 Returns a default configuration for the Java VM.
4150 *******************************************************************************/
4152 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4154 JavaVMInitArgs *_vm_args;
4156 _vm_args = (JavaVMInitArgs *) vm_args;
4158 /* GNU classpath currently supports JNI 1.2 */
4160 switch (_vm_args->version) {
4161 case JNI_VERSION_1_1:
4162 _vm_args->version = JNI_VERSION_1_1;
4165 case JNI_VERSION_1_2:
4166 case JNI_VERSION_1_4:
4167 _vm_args->ignoreUnrecognized = JNI_FALSE;
4168 _vm_args->options = NULL;
4169 _vm_args->nOptions = 0;
4180 /* JNI_GetCreatedJavaVMs *******************************************************
4182 Returns all Java VMs that have been created. Pointers to VMs are written in
4183 the buffer vmBuf in the order they are created. At most bufLen number of
4184 entries will be written. The total number of created VMs is returned in
4187 *******************************************************************************/
4189 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4191 TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
4196 /* We currently only support 1 VM running. */
4198 vmBuf[0] = (JavaVM *) _Jv_jvm;
4205 /* JNI_CreateJavaVM ************************************************************
4207 Loads and initializes a Java VM. The current thread becomes the main thread.
4208 Sets the env argument to the JNI interface pointer of the main thread.
4210 *******************************************************************************/
4212 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4214 TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
4216 /* actually create the JVM */
4218 if (!vm_createjvm(p_vm, p_env, vm_args))
4226 * These are local overrides for various environment variables in Emacs.
4227 * Please do not remove this and leave it at the end of the file, where
4228 * Emacs will automagically detect them.
4229 * ---------------------------------------------------------------------
4232 * indent-tabs-mode: t
4236 * vim:noexpandtab:sw=4:ts=4: