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 8387 2007-08-21 15:37:47Z twisti $
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);
178 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity);
181 /* jni_init ********************************************************************
183 Initialize the JNI subsystem.
185 *******************************************************************************/
189 /* create global ref hashtable */
191 hashtable_global_ref = NEW(hashtable);
193 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
196 #if defined(ENABLE_JAVASE)
197 /* direct buffer stuff */
199 if (!(class_java_nio_Buffer =
200 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
201 !link_class(class_java_nio_Buffer))
204 # if defined(WITH_CLASSPATH_GNU)
205 if (!(class_java_nio_DirectByteBufferImpl =
206 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
207 !link_class(class_java_nio_DirectByteBufferImpl))
210 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
211 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
212 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
216 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
218 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
221 # if SIZEOF_VOID_P == 8
222 if (!(class_gnu_classpath_Pointer64 =
223 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
224 !link_class(class_gnu_classpath_Pointer64))
227 if (!(class_gnu_classpath_Pointer32 =
228 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
229 !link_class(class_gnu_classpath_Pointer32))
233 #endif /* defined(ENABLE_JAVASE) */
239 /* _Jv_jni_CallObjectMethod ****************************************************
241 Internal function to call Java Object methods.
243 *******************************************************************************/
245 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
247 methodinfo *m, va_list ap)
252 STATISTICS(jniinvokation());
255 exceptions_throw_nullpointerexception();
259 /* Class initialization is done by the JIT compiler. This is ok
260 since a static method always belongs to the declaring class. */
262 if (m->flags & ACC_STATIC) {
263 /* For static methods we reset the object. */
268 /* for convenience */
273 /* For instance methods we make a virtual function table lookup. */
275 resm = method_vftbl_lookup(vftbl, m);
278 STATISTICS(jnicallXmethodnvokation());
280 ro = vm_call_method_valist(resm, o, ap);
286 /* _Jv_jni_CallObjectMethodA ***************************************************
288 Internal function to call Java Object methods.
290 *******************************************************************************/
292 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
300 STATISTICS(jniinvokation());
303 exceptions_throw_nullpointerexception();
307 /* Class initialization is done by the JIT compiler. This is ok
308 since a static method always belongs to the declaring class. */
310 if (m->flags & ACC_STATIC) {
311 /* For static methods we reset the object. */
316 /* for convenience */
321 /* For instance methods we make a virtual function table lookup. */
323 resm = method_vftbl_lookup(vftbl, m);
326 STATISTICS(jnicallXmethodnvokation());
328 ro = vm_call_method_jvalue(resm, o, args);
334 /* _Jv_jni_CallIntMethod *******************************************************
336 Internal function to call Java integer class methods (boolean,
337 byte, char, short, int).
339 *******************************************************************************/
341 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
342 methodinfo *m, va_list ap)
347 STATISTICS(jniinvokation());
350 exceptions_throw_nullpointerexception();
354 /* Class initialization is done by the JIT compiler. This is ok
355 since a static method always belongs to the declaring class. */
357 if (m->flags & ACC_STATIC) {
358 /* For static methods we reset the object. */
363 /* for convenience */
368 /* For instance methods we make a virtual function table lookup. */
370 resm = method_vftbl_lookup(vftbl, m);
373 STATISTICS(jnicallXmethodnvokation());
375 i = vm_call_method_int_valist(resm, o, ap);
381 /* _Jv_jni_CallIntMethodA ******************************************************
383 Internal function to call Java integer class methods (boolean,
384 byte, char, short, int).
386 *******************************************************************************/
388 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
389 methodinfo *m, const jvalue *args)
394 STATISTICS(jniinvokation());
397 exceptions_throw_nullpointerexception();
401 /* Class initialization is done by the JIT compiler. This is ok
402 since a static method always belongs to the declaring class. */
404 if (m->flags & ACC_STATIC) {
405 /* For static methods we reset the object. */
410 /* for convenience */
415 /* For instance methods we make a virtual function table lookup. */
417 resm = method_vftbl_lookup(vftbl, m);
420 STATISTICS(jnicallXmethodnvokation());
422 i = vm_call_method_int_jvalue(resm, o, args);
428 /* _Jv_jni_CallLongMethod ******************************************************
430 Internal function to call Java long methods.
432 *******************************************************************************/
434 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
435 methodinfo *m, va_list ap)
440 STATISTICS(jniinvokation());
443 exceptions_throw_nullpointerexception();
447 /* Class initialization is done by the JIT compiler. This is ok
448 since a static method always belongs to the declaring class. */
450 if (m->flags & ACC_STATIC) {
451 /* For static methods we reset the object. */
456 /* for convenience */
461 /* For instance methods we make a virtual function table lookup. */
463 resm = method_vftbl_lookup(vftbl, m);
466 STATISTICS(jnicallXmethodnvokation());
468 l = vm_call_method_long_valist(resm, o, ap);
474 /* _Jv_jni_CallLongMethodA *****************************************************
476 Internal function to call Java long methods.
478 *******************************************************************************/
480 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
481 methodinfo *m, const jvalue *args)
486 STATISTICS(jniinvokation());
489 exceptions_throw_nullpointerexception();
493 /* Class initialization is done by the JIT compiler. This is ok
494 since a static method always belongs to the declaring class. */
496 if (m->flags & ACC_STATIC) {
497 /* For static methods we reset the object. */
502 /* for convenience */
507 /* For instance methods we make a virtual function table lookup. */
509 resm = method_vftbl_lookup(vftbl, m);
512 STATISTICS(jnicallXmethodnvokation());
514 l = vm_call_method_long_jvalue(resm, o, args);
520 /* _Jv_jni_CallFloatMethod *****************************************************
522 Internal function to call Java float methods.
524 *******************************************************************************/
526 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
527 methodinfo *m, va_list ap)
532 /* Class initialization is done by the JIT compiler. This is ok
533 since a static method always belongs to the declaring class. */
535 if (m->flags & ACC_STATIC) {
536 /* For static methods we reset the object. */
541 /* for convenience */
546 /* For instance methods we make a virtual function table lookup. */
548 resm = method_vftbl_lookup(vftbl, m);
551 STATISTICS(jnicallXmethodnvokation());
553 f = vm_call_method_float_valist(resm, o, ap);
559 /* _Jv_jni_CallFloatMethodA ****************************************************
561 Internal function to call Java float methods.
563 *******************************************************************************/
565 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
566 methodinfo *m, const jvalue *args)
571 /* Class initialization is done by the JIT compiler. This is ok
572 since a static method always belongs to the declaring class. */
574 if (m->flags & ACC_STATIC) {
575 /* For static methods we reset the object. */
580 /* for convenience */
585 /* For instance methods we make a virtual function table lookup. */
587 resm = method_vftbl_lookup(vftbl, m);
590 STATISTICS(jnicallXmethodnvokation());
592 f = vm_call_method_float_jvalue(resm, o, args);
598 /* _Jv_jni_CallDoubleMethod ****************************************************
600 Internal function to call Java double methods.
602 *******************************************************************************/
604 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
605 methodinfo *m, va_list ap)
610 /* Class initialization is done by the JIT compiler. This is ok
611 since a static method always belongs to the declaring class. */
613 if (m->flags & ACC_STATIC) {
614 /* For static methods we reset the object. */
619 /* for convenience */
624 /* For instance methods we make a virtual function table lookup. */
626 resm = method_vftbl_lookup(vftbl, m);
629 d = vm_call_method_double_valist(resm, o, ap);
635 /* _Jv_jni_CallDoubleMethodA ***************************************************
637 Internal function to call Java double methods.
639 *******************************************************************************/
641 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
642 methodinfo *m, const jvalue *args)
647 /* Class initialization is done by the JIT compiler. This is ok
648 since a static method always belongs to the declaring class. */
650 if (m->flags & ACC_STATIC) {
651 /* For static methods we reset the object. */
656 /* for convenience */
661 /* For instance methods we make a virtual function table lookup. */
663 resm = method_vftbl_lookup(vftbl, m);
666 d = vm_call_method_double_jvalue(resm, o, args);
672 /* _Jv_jni_CallVoidMethod ******************************************************
674 Internal function to call Java void methods.
676 *******************************************************************************/
678 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
679 methodinfo *m, va_list ap)
684 exceptions_throw_nullpointerexception();
688 /* Class initialization is done by the JIT compiler. This is ok
689 since a static method always belongs to the declaring class. */
691 if (m->flags & ACC_STATIC) {
692 /* For static methods we reset the object. */
697 /* for convenience */
702 /* For instance methods we make a virtual function table lookup. */
704 resm = method_vftbl_lookup(vftbl, m);
707 STATISTICS(jnicallXmethodnvokation());
709 (void) vm_call_method_valist(resm, o, ap);
713 /* _Jv_jni_CallVoidMethodA *****************************************************
715 Internal function to call Java void methods.
717 *******************************************************************************/
719 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
720 methodinfo *m, const jvalue *args)
725 exceptions_throw_nullpointerexception();
729 /* Class initialization is done by the JIT compiler. This is ok
730 since a static method always belongs to the declaring class. */
732 if (m->flags & ACC_STATIC) {
733 /* For static methods we reset the object. */
738 /* for convenience */
743 /* For instance methods we make a virtual function table lookup. */
745 resm = method_vftbl_lookup(vftbl, m);
748 STATISTICS(jnicallXmethodnvokation());
750 (void) vm_call_method_jvalue(resm, o, args);
754 /* _Jv_jni_invokeNative ********************************************************
756 Invoke a method on the given object with the given arguments.
758 For instance methods OBJ must be != NULL and the method is looked up
759 in the vftbl of the object.
761 For static methods, OBJ is ignored.
763 *******************************************************************************/
765 java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
766 java_handle_objectarray_t *params)
778 exceptions_throw_nullpointerexception();
782 argcount = m->parseddesc->paramcount;
783 paramcount = argcount;
785 /* if method is non-static, remove the `this' pointer */
787 if (!(m->flags & ACC_STATIC))
790 /* For instance methods the object has to be an instance of the
791 class the method belongs to. For static methods the obj
792 parameter is ignored. */
794 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
795 exceptions_throw_illegalargumentexception();
799 /* check if we got the right number of arguments */
801 if (((params == NULL) && (paramcount != 0)) ||
802 (params && (LLNI_array_size(params) != paramcount)))
804 exceptions_throw_illegalargumentexception();
808 /* for instance methods we need an object */
810 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
811 /* XXX not sure if that is the correct exception */
812 exceptions_throw_nullpointerexception();
816 /* for static methods, zero object to make subsequent code simpler */
817 if (m->flags & ACC_STATIC)
821 /* for instance methods we must do a vftbl lookup */
822 resm = method_vftbl_lookup(o->vftbl, m);
825 /* for static methods, just for convenience */
829 /* mark start of dump memory area */
831 dumpsize = dump_size();
833 /* Fill the argument array from a object-array. */
835 array = vm_array_from_objectarray(resm, o, params);
837 /* The array can be NULL if we don't have any arguments to pass
838 and the architecture does not have any argument registers
839 (e.g. i386). In that case we additionally check for an
842 if ((array == NULL) && (exceptions_get_exception() != NULL)) {
843 /* release dump area */
845 dump_release(dumpsize);
850 switch (resm->parseddesc->returntype.decltype) {
852 (void) vm_call_array(resm, array);
856 case PRIMITIVETYPE_BOOLEAN:
857 case PRIMITIVETYPE_BYTE:
858 case PRIMITIVETYPE_CHAR:
859 case PRIMITIVETYPE_SHORT:
860 case PRIMITIVETYPE_INT:
861 value.i = vm_call_int_array(resm, array);
862 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
865 case PRIMITIVETYPE_LONG:
866 value.l = vm_call_long_array(resm, array);
867 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
870 case PRIMITIVETYPE_FLOAT:
871 value.f = vm_call_float_array(resm, array);
872 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
875 case PRIMITIVETYPE_DOUBLE:
876 value.d = vm_call_double_array(resm, array);
877 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
881 ro = vm_call_array(resm, array);
885 vm_abort("_Jv_jni_invokeNative: invalid return type %d", resm->parseddesc->returntype.decltype);
888 xptr = exceptions_get_exception();
891 /* clear exception pointer, we are calling JIT code again */
893 exceptions_clear_exception();
895 exceptions_throw_invocationtargetexception(xptr);
898 /* release dump area */
900 dump_release(dumpsize);
906 /* GetVersion ******************************************************************
908 Returns the major version number in the higher 16 bits and the
909 minor version number in the lower 16 bits.
911 *******************************************************************************/
913 jint _Jv_JNI_GetVersion(JNIEnv *env)
915 STATISTICS(jniinvokation());
917 /* we support JNI 1.4 */
919 return JNI_VERSION_1_4;
923 /* Class Operations ***********************************************************/
925 /* DefineClass *****************************************************************
927 Loads a class from a buffer of raw class data. The buffer
928 containing the raw class data is not referenced by the VM after the
929 DefineClass call returns, and it may be discarded if desired.
931 *******************************************************************************/
933 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
934 const jbyte *buf, jsize bufLen)
936 #if defined(ENABLE_JAVASE)
941 TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen);
943 u = utf_new_char(name);
944 cl = (classloader *) loader;
946 c = class_define(u, cl, bufLen, (const uint8_t *) buf, NULL);
948 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
950 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
952 /* keep compiler happy */
959 /* FindClass *******************************************************************
961 This function loads a locally-defined class. It searches the
962 directories and zip files specified by the CLASSPATH environment
963 variable for the class with the specified name.
965 *******************************************************************************/
967 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
969 #if defined(ENABLE_JAVASE)
974 STATISTICS(jniinvokation());
976 u = utf_new_char_classname((char *) name);
978 /* Check stacktrace for classloader, if one found use it,
979 otherwise use the system classloader. */
981 /* Quote from the JNI documentation:
983 In the Java 2 Platform, FindClass locates the class loader
984 associated with the current native method. If the native code
985 belongs to a system class, no class loader will be
986 involved. Otherwise, the proper class loader will be invoked to
987 load and link the named class. When FindClass is called through
988 the Invocation Interface, there is no current native method or
989 its associated class loader. In that case, the result of
990 ClassLoader.getBaseClassLoader is used." */
992 cc = stacktrace_getCurrentClass();
995 c = load_class_from_sysloader(u);
997 c = load_class_from_classloader(u, cc->classloader);
1005 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1007 vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1009 /* keep compiler happy */
1016 /* GetSuperclass ***************************************************************
1018 If clazz represents any class other than the class Object, then
1019 this function returns the object that represents the superclass of
1020 the class specified by clazz.
1022 *******************************************************************************/
1024 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1029 TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
1031 c = LLNI_classinfo_unwrap(sub);
1036 super = class_get_superclass(c);
1038 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) super);
1042 /* IsAssignableFrom ************************************************************
1044 Determines whether an object of sub can be safely cast to sup.
1046 *******************************************************************************/
1048 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1050 java_lang_Class *csup;
1051 java_lang_Class *csub;
1053 csup = (java_lang_Class *) sup;
1054 csub = (java_lang_Class *) sub;
1056 STATISTICS(jniinvokation());
1058 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1062 /* Throw ***********************************************************************
1064 Causes a java.lang.Throwable object to be thrown.
1066 *******************************************************************************/
1068 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1072 STATISTICS(jniinvokation());
1074 o = (java_handle_t *) obj;
1076 exceptions_set_exception(o);
1082 /* ThrowNew ********************************************************************
1084 Constructs an exception object from the specified class with the
1085 message specified by message and causes that exception to be
1088 *******************************************************************************/
1090 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1096 STATISTICS(jniinvokation());
1098 c = LLNI_classinfo_unwrap(clazz);
1101 s = javastring_new_from_utf_string(msg);
1103 /* instantiate exception object */
1105 o = native_new_and_init_string(c, s);
1110 exceptions_set_exception(o);
1116 /* ExceptionOccurred ***********************************************************
1118 Determines if an exception is being thrown. The exception stays
1119 being thrown until either the native code calls ExceptionClear(),
1120 or the Java code handles the exception.
1122 *******************************************************************************/
1124 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1128 STATISTICS(jniinvokation());
1130 o = exceptions_get_exception();
1132 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1136 /* ExceptionDescribe ***********************************************************
1138 Prints an exception and a backtrace of the stack to a system
1139 error-reporting channel, such as stderr. This is a convenience
1140 routine provided for debugging.
1142 *******************************************************************************/
1144 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 m = class_resolveclassmethod(o->vftbl->class,
1161 utf_printStackTrace,
1167 /* XXX what should we do? */
1170 /* print the stacktrace */
1172 (void) vm_call_method(m, o);
1177 /* ExceptionClear **************************************************************
1179 Clears any exception that is currently being thrown. If no
1180 exception is currently being thrown, this routine has no effect.
1182 *******************************************************************************/
1184 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1186 STATISTICS(jniinvokation());
1188 exceptions_clear_exception();
1192 /* FatalError ******************************************************************
1194 Raises a fatal error and does not expect the VM to recover. This
1195 function does not return.
1197 *******************************************************************************/
1199 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1201 STATISTICS(jniinvokation());
1203 /* this seems to be the best way */
1205 vm_abort("JNI Fatal error: %s", msg);
1209 /* PushLocalFrame **************************************************************
1211 Creates a new local reference frame, in which at least a given
1212 number of local references can be created.
1214 *******************************************************************************/
1216 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1218 STATISTICS(jniinvokation());
1223 /* add new local reference frame to current table */
1225 if (!localref_frame_push(capacity))
1232 /* PopLocalFrame ***************************************************************
1234 Pops off the current local reference frame, frees all the local
1235 references, and returns a local reference in the previous local
1236 reference frame for the given result object.
1238 *******************************************************************************/
1240 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1242 STATISTICS(jniinvokation());
1244 /* release all current local frames */
1246 localref_frame_pop_all();
1248 /* add local reference and return the value */
1250 return _Jv_JNI_NewLocalRef(env, result);
1254 /* DeleteLocalRef **************************************************************
1256 Deletes the local reference pointed to by localRef.
1258 *******************************************************************************/
1260 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1263 localref_table *lrt;
1266 STATISTICS(jniinvokation());
1268 o = (java_handle_t *) localRef;
1270 /* get local reference table (thread specific) */
1272 lrt = LOCALREFTABLE;
1274 /* go through all local frames */
1276 for (; lrt != NULL; lrt = lrt->prev) {
1278 /* and try to remove the reference */
1280 for (i = 0; i < lrt->capacity; i++) {
1281 if (lrt->refs[i] == o) {
1282 lrt->refs[i] = NULL;
1290 /* this should not happen */
1292 /* if (opt_checkjni) */
1293 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1294 log_text("JNI-DeleteLocalRef: Local ref passed to JNI not found");
1298 /* IsSameObject ****************************************************************
1300 Tests whether two references refer to the same Java object.
1302 *******************************************************************************/
1304 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1306 STATISTICS(jniinvokation());
1315 /* NewLocalRef *****************************************************************
1317 Creates a new local reference that refers to the same object as ref.
1319 *******************************************************************************/
1321 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1323 localref_table *lrt;
1326 STATISTICS(jniinvokation());
1331 /* get local reference table (thread specific) */
1333 lrt = LOCALREFTABLE;
1335 /* Check if we have space for the requested reference? No,
1336 allocate a new frame. This is actually not what the spec says,
1337 but for compatibility reasons... */
1339 if (lrt->used == lrt->capacity) {
1340 if (_Jv_JNI_EnsureLocalCapacity(env, 16) != 0)
1343 /* get the new local reference table */
1345 lrt = LOCALREFTABLE;
1348 /* insert the reference */
1350 for (i = 0; i < lrt->capacity; i++) {
1351 if (lrt->refs[i] == NULL) {
1352 lrt->refs[i] = (java_handle_t *) ref;
1359 /* should not happen, just to be sure */
1363 /* keep compiler happy */
1369 /* EnsureLocalCapacity *********************************************************
1371 Ensures that at least a given number of local references can be
1372 created in the current thread
1374 *******************************************************************************/
1376 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1378 localref_table *lrt;
1380 STATISTICS(jniinvokation());
1382 /* get local reference table (thread specific) */
1384 lrt = LOCALREFTABLE;
1386 /* check if capacity elements are available in the local references table */
1388 if ((lrt->used + capacity) > lrt->capacity)
1389 return _Jv_JNI_PushLocalFrame(env, capacity);
1395 /* AllocObject *****************************************************************
1397 Allocates a new Java object without invoking any of the
1398 constructors for the object. Returns a reference to the object.
1400 *******************************************************************************/
1402 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1407 STATISTICS(jniinvokation());
1409 c = LLNI_classinfo_unwrap(clazz);
1411 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1412 exceptions_throw_instantiationexception(c);
1418 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1422 /* NewObject *******************************************************************
1424 Programmers place all arguments that are to be passed to the
1425 constructor immediately following the methodID
1426 argument. NewObject() accepts these arguments and passes them to
1427 the Java method that the programmer wishes to invoke.
1429 *******************************************************************************/
1431 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1438 STATISTICS(jniinvokation());
1440 c = LLNI_classinfo_unwrap(clazz);
1441 m = (methodinfo *) methodID;
1450 /* call constructor */
1452 va_start(ap, methodID);
1453 _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
1456 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1460 /* NewObjectV ******************************************************************
1462 Programmers place all arguments that are to be passed to the
1463 constructor in an args argument of type va_list that immediately
1464 follows the methodID argument. NewObjectV() accepts these
1465 arguments, and, in turn, passes them to the Java method that the
1466 programmer wishes to invoke.
1468 *******************************************************************************/
1470 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1477 STATISTICS(jniinvokation());
1479 c = LLNI_classinfo_unwrap(clazz);
1480 m = (methodinfo *) methodID;
1489 /* call constructor */
1491 _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
1493 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1497 /* NewObjectA *****************************************************************
1499 Programmers place all arguments that are to be passed to the
1500 constructor in an args array of jvalues that immediately follows
1501 the methodID argument. NewObjectA() accepts the arguments in this
1502 array, and, in turn, passes them to the Java method that the
1503 programmer wishes to invoke.
1505 *******************************************************************************/
1507 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1514 STATISTICS(jniinvokation());
1516 c = LLNI_classinfo_unwrap(clazz);
1517 m = (methodinfo *) methodID;
1526 /* call constructor */
1528 _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
1530 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1534 /* GetObjectClass **************************************************************
1536 Returns the class of an object.
1538 *******************************************************************************/
1540 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1545 STATISTICS(jniinvokation());
1547 o = (java_handle_t *) obj;
1549 if ((o == NULL) || (o->vftbl == NULL))
1552 c = o->vftbl->class;
1554 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1558 /* IsInstanceOf ****************************************************************
1560 Tests whether an object is an instance of a class.
1562 *******************************************************************************/
1564 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1567 java_lang_Object *o;
1569 STATISTICS(jniinvokation());
1571 c = (java_lang_Class *) clazz;
1572 o = (java_lang_Object *) obj;
1574 return _Jv_java_lang_Class_isInstance(c, o);
1578 /* Reflection Support *********************************************************/
1580 /* FromReflectedMethod *********************************************************
1582 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1583 object to a method ID.
1585 *******************************************************************************/
1587 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1589 #if defined(ENABLE_JAVASE)
1595 STATISTICS(jniinvokation());
1597 o = (java_handle_t *) method;
1602 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1603 java_lang_reflect_Method *rm;
1605 rm = (java_lang_reflect_Method *) method;
1606 LLNI_field_get_cls(rm, clazz, c);
1607 LLNI_field_get_val(rm, slot , slot);
1609 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1610 java_lang_reflect_Constructor *rc;
1612 rc = (java_lang_reflect_Constructor *) method;
1613 LLNI_field_get_cls(rc, clazz, c);
1614 LLNI_field_get_val(rc, slot , slot);
1619 m = &(c->methods[slot]);
1621 return (jmethodID) m;
1623 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1625 /* keep compiler happy */
1632 /* FromReflectedField **********************************************************
1634 Converts a java.lang.reflect.Field to a field ID.
1636 *******************************************************************************/
1638 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1640 #if defined(ENABLE_JAVASE)
1641 java_lang_reflect_Field *rf;
1646 STATISTICS(jniinvokation());
1648 rf = (java_lang_reflect_Field *) field;
1653 LLNI_field_get_cls(rf, clazz, c);
1654 LLNI_field_get_val(rf, slot , slot);
1655 f = &(c->fields[slot]);
1657 return (jfieldID) f;
1659 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1661 /* keep compiler happy */
1668 /* ToReflectedMethod ***********************************************************
1670 Converts a method ID derived from cls to an instance of the
1671 java.lang.reflect.Method class or to an instance of the
1672 java.lang.reflect.Constructor class.
1674 *******************************************************************************/
1676 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1679 #if defined(ENABLE_JAVASE)
1681 java_lang_reflect_Constructor *rc;
1682 java_lang_reflect_Method *rm;
1684 STATISTICS(jniinvokation());
1686 m = (methodinfo *) methodID;
1688 /* HotSpot does the same assert. */
1690 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1692 if (m->name == utf_init) {
1693 rc = reflect_constructor_new(m);
1695 return (jobject) rc;
1698 rm = reflect_method_new(m);
1700 return (jobject) rm;
1703 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1705 /* keep compiler happy */
1712 /* ToReflectedField ************************************************************
1714 Converts a field ID derived from cls to an instance of the
1715 java.lang.reflect.Field class.
1717 *******************************************************************************/
1719 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1722 STATISTICS(jniinvokation());
1724 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1730 /* Calling Instance Methods ***************************************************/
1732 /* GetMethodID *****************************************************************
1734 Returns the method ID for an instance (nonstatic) method of a class
1735 or interface. The method may be defined in one of the clazz's
1736 superclasses and inherited by clazz. The method is determined by
1737 its name and signature.
1739 GetMethodID() causes an uninitialized class to be initialized.
1741 *******************************************************************************/
1743 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1751 STATISTICS(jniinvokation());
1753 c = LLNI_classinfo_unwrap(clazz);
1758 if (!(c->state & CLASS_INITIALIZED))
1759 if (!initialize_class(c))
1762 /* try to get the method of the class or one of it's superclasses */
1764 uname = utf_new_char((char *) name);
1765 udesc = utf_new_char((char *) sig);
1767 m = class_resolvemethod(c, uname, udesc);
1769 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1770 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1775 return (jmethodID) m;
1779 /* JNI-functions for calling instance methods *********************************/
1781 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1782 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1783 jmethodID methodID, ...) \
1790 o = (java_handle_t *) obj; \
1791 m = (methodinfo *) methodID; \
1793 va_start(ap, methodID); \
1794 ret = _Jv_jni_Call##intern##Method(o, o->vftbl, m, ap); \
1800 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1801 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1802 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1803 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1804 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1805 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1806 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1807 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1810 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1811 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1812 jmethodID methodID, va_list args) \
1818 o = (java_handle_t *) obj; \
1819 m = (methodinfo *) methodID; \
1821 ret = _Jv_jni_Call##intern##Method(o, o->vftbl, m, args); \
1826 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1827 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1828 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1829 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1830 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1831 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1832 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1833 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1836 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1837 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1838 jmethodID methodID, \
1839 const jvalue *args) \
1845 o = (java_handle_t *) obj; \
1846 m = (methodinfo *) methodID; \
1848 ret = _Jv_jni_Call##intern##MethodA(o, o->vftbl, m, args); \
1853 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1854 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1855 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1856 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1857 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1858 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1859 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1860 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1863 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1871 o = (java_handle_t *) obj;
1872 m = (methodinfo *) methodID;
1874 va_start(ap, methodID);
1875 ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, ap);
1878 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1882 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1889 o = (java_handle_t *) obj;
1890 m = (methodinfo *) methodID;
1892 ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, args);
1894 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1898 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1905 o = (java_handle_t *) obj;
1906 m = (methodinfo *) methodID;
1908 ret = _Jv_jni_CallObjectMethodA(o, o->vftbl, m, args);
1910 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1915 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1921 o = (java_handle_t *) obj;
1922 m = (methodinfo *) methodID;
1924 va_start(ap, methodID);
1925 _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
1930 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1936 o = (java_handle_t *) obj;
1937 m = (methodinfo *) methodID;
1939 _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
1943 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1949 o = (java_handle_t *) obj;
1950 m = (methodinfo *) methodID;
1952 _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
1957 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1958 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1959 jclass clazz, jmethodID methodID, \
1968 o = (java_handle_t *) obj; \
1969 c = LLNI_classinfo_unwrap(clazz); \
1970 m = (methodinfo *) methodID; \
1972 va_start(ap, methodID); \
1973 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1979 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1980 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1981 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1982 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1983 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1984 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1985 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1986 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1989 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1990 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1991 jclass clazz, jmethodID methodID, \
1999 o = (java_handle_t *) obj; \
2000 c = LLNI_classinfo_unwrap(clazz); \
2001 m = (methodinfo *) methodID; \
2003 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
2008 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
2009 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
2010 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
2011 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
2012 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
2013 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
2014 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
2015 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
2018 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
2019 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
2020 jclass clazz, jmethodID methodID, \
2021 const jvalue *args) \
2023 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
2028 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
2029 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
2030 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
2031 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
2032 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
2033 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
2034 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
2035 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
2037 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2038 jclass clazz, jmethodID methodID,
2047 o = (java_handle_t *) obj;
2048 c = LLNI_classinfo_unwrap(clazz);
2049 m = (methodinfo *) methodID;
2051 va_start(ap, methodID);
2052 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2055 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2059 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2060 jclass clazz, jmethodID methodID,
2068 o = (java_handle_t *) obj;
2069 c = LLNI_classinfo_unwrap(clazz);
2070 m = (methodinfo *) methodID;
2072 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2074 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2078 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2079 jclass clazz, jmethodID methodID,
2082 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2084 return _Jv_JNI_NewLocalRef(env, NULL);
2088 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2089 jmethodID methodID, ...)
2096 o = (java_handle_t *) obj;
2097 c = LLNI_classinfo_unwrap(clazz);
2098 m = (methodinfo *) methodID;
2100 va_start(ap, methodID);
2101 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2106 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2107 jmethodID methodID, va_list args)
2113 o = (java_handle_t *) obj;
2114 c = LLNI_classinfo_unwrap(clazz);
2115 m = (methodinfo *) methodID;
2117 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2121 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2122 jmethodID methodID, const jvalue * args)
2128 o = (java_handle_t *) obj;
2129 c = LLNI_classinfo_unwrap(clazz);
2130 m = (methodinfo *) methodID;
2132 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2136 /* Accessing Fields of Objects ************************************************/
2138 /* GetFieldID ******************************************************************
2140 Returns the field ID for an instance (nonstatic) field of a
2141 class. The field is specified by its name and signature. The
2142 Get<type>Field and Set<type>Field families of accessor functions
2143 use field IDs to retrieve object fields.
2145 *******************************************************************************/
2147 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2155 STATISTICS(jniinvokation());
2157 c = LLNI_classinfo_unwrap(clazz);
2159 /* XXX NPE check? */
2161 uname = utf_new_char((char *) name);
2162 udesc = utf_new_char((char *) sig);
2164 f = class_findfield(c, uname, udesc);
2167 exceptions_throw_nosuchfielderror(c, uname);
2169 return (jfieldID) f;
2173 /* Get<type>Field Routines *****************************************************
2175 This family of accessor routines returns the value of an instance
2176 (nonstatic) field of an object. The field to access is specified by
2177 a field ID obtained by calling GetFieldID().
2179 *******************************************************************************/
2181 #define JNI_GET_FIELD(name, type, intern) \
2182 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2186 STATISTICS(jniinvokation()); \
2188 ret = GET_FIELD(obj, intern, fieldID); \
2190 return (type) ret; \
2193 JNI_GET_FIELD(Boolean, jboolean, s4)
2194 JNI_GET_FIELD(Byte, jbyte, s4)
2195 JNI_GET_FIELD(Char, jchar, s4)
2196 JNI_GET_FIELD(Short, jshort, s4)
2197 JNI_GET_FIELD(Int, jint, s4)
2198 JNI_GET_FIELD(Long, jlong, s8)
2199 JNI_GET_FIELD(Float, jfloat, float)
2200 JNI_GET_FIELD(Double, jdouble, double)
2203 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2207 STATISTICS(jniinvokation());
2209 #warning this needs to be fixed
2210 o = GET_FIELD(obj, java_handle_t*, fieldID);
2212 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2216 /* Set<type>Field Routines *****************************************************
2218 This family of accessor routines sets the value of an instance
2219 (nonstatic) field of an object. The field to access is specified by
2220 a field ID obtained by calling GetFieldID().
2222 *******************************************************************************/
2224 #define JNI_SET_FIELD(name, type, intern) \
2225 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2228 STATISTICS(jniinvokation()); \
2230 SET_FIELD(obj, intern, fieldID, value); \
2233 JNI_SET_FIELD(Boolean, jboolean, s4)
2234 JNI_SET_FIELD(Byte, jbyte, s4)
2235 JNI_SET_FIELD(Char, jchar, s4)
2236 JNI_SET_FIELD(Short, jshort, s4)
2237 JNI_SET_FIELD(Int, jint, s4)
2238 JNI_SET_FIELD(Long, jlong, s8)
2239 JNI_SET_FIELD(Float, jfloat, float)
2240 JNI_SET_FIELD(Double, jdouble, double)
2243 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2246 STATISTICS(jniinvokation());
2248 #warning this needs to be fixed
2249 SET_FIELD(obj, java_handle_t*, fieldID, value);
2253 /* Calling Static Methods *****************************************************/
2255 /* GetStaticMethodID ***********************************************************
2257 Returns the method ID for a static method of a class. The method is
2258 specified by its name and signature.
2260 GetStaticMethodID() causes an uninitialized class to be
2263 *******************************************************************************/
2265 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2273 STATISTICS(jniinvokation());
2275 c = LLNI_classinfo_unwrap(clazz);
2280 if (!(c->state & CLASS_INITIALIZED))
2281 if (!initialize_class(c))
2284 /* try to get the static method of the class */
2286 uname = utf_new_char((char *) name);
2287 udesc = utf_new_char((char *) sig);
2289 m = class_resolvemethod(c, uname, udesc);
2291 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2292 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2297 return (jmethodID) m;
2301 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2302 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2303 jmethodID methodID, ...) \
2309 m = (methodinfo *) methodID; \
2311 va_start(ap, methodID); \
2312 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2318 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2319 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2320 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2321 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2322 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2323 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2324 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2325 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2328 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2329 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2330 jmethodID methodID, va_list args) \
2335 m = (methodinfo *) methodID; \
2337 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2342 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2343 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2344 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2345 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2346 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2347 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2348 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2349 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2352 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2353 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2354 jmethodID methodID, const jvalue *args) \
2359 m = (methodinfo *) methodID; \
2361 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2366 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2367 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2368 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2369 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2370 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2371 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2372 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2373 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2376 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2377 jmethodID methodID, ...)
2383 m = (methodinfo *) methodID;
2385 va_start(ap, methodID);
2386 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2389 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2393 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2394 jmethodID methodID, va_list args)
2399 m = (methodinfo *) methodID;
2401 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2403 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2407 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2408 jmethodID methodID, const jvalue *args)
2413 m = (methodinfo *) methodID;
2415 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2417 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2421 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2422 jmethodID methodID, ...)
2427 m = (methodinfo *) methodID;
2429 va_start(ap, methodID);
2430 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2435 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2436 jmethodID methodID, va_list args)
2440 m = (methodinfo *) methodID;
2442 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2446 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2447 jmethodID methodID, const jvalue * args)
2451 m = (methodinfo *) methodID;
2453 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2457 /* Accessing Static Fields ****************************************************/
2459 /* GetStaticFieldID ************************************************************
2461 Returns the field ID for a static field of a class. The field is
2462 specified by its name and signature. The GetStatic<type>Field and
2463 SetStatic<type>Field families of accessor functions use field IDs
2464 to retrieve static fields.
2466 *******************************************************************************/
2468 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2476 STATISTICS(jniinvokation());
2478 c = LLNI_classinfo_unwrap(clazz);
2480 uname = utf_new_char((char *) name);
2481 usig = utf_new_char((char *) sig);
2483 f = class_findfield(c, uname, usig);
2486 exceptions_throw_nosuchfielderror(c, uname);
2488 return (jfieldID) f;
2492 /* GetStatic<type>Field ********************************************************
2494 This family of accessor routines returns the value of a static
2497 *******************************************************************************/
2499 #define JNI_GET_STATIC_FIELD(name, type, field) \
2500 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2506 STATISTICS(jniinvokation()); \
2508 c = LLNI_classinfo_unwrap(clazz); \
2509 f = (fieldinfo *) fieldID; \
2511 if (!(c->state & CLASS_INITIALIZED)) \
2512 if (!initialize_class(c)) \
2515 return f->value->field; \
2518 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2519 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2520 JNI_GET_STATIC_FIELD(Char, jchar, i)
2521 JNI_GET_STATIC_FIELD(Short, jshort, i)
2522 JNI_GET_STATIC_FIELD(Int, jint, i)
2523 JNI_GET_STATIC_FIELD(Long, jlong, l)
2524 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2525 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2528 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2534 STATISTICS(jniinvokation());
2536 c = LLNI_classinfo_unwrap(clazz);
2537 f = (fieldinfo *) fieldID;
2539 if (!(c->state & CLASS_INITIALIZED))
2540 if (!initialize_class(c))
2543 return _Jv_JNI_NewLocalRef(env, f->value->a);
2547 /* SetStatic<type>Field *******************************************************
2549 This family of accessor routines sets the value of a static field
2552 *******************************************************************************/
2554 #define JNI_SET_STATIC_FIELD(name, type, field) \
2555 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2562 STATISTICS(jniinvokation()); \
2564 c = LLNI_classinfo_unwrap(clazz); \
2565 f = (fieldinfo *) fieldID; \
2567 if (!(c->state & CLASS_INITIALIZED)) \
2568 if (!initialize_class(c)) \
2571 f->value->field = value; \
2574 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2575 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2576 JNI_SET_STATIC_FIELD(Char, jchar, i)
2577 JNI_SET_STATIC_FIELD(Short, jshort, i)
2578 JNI_SET_STATIC_FIELD(Int, jint, i)
2579 JNI_SET_STATIC_FIELD(Long, jlong, l)
2580 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2581 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2584 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2590 STATISTICS(jniinvokation());
2592 c = LLNI_classinfo_unwrap(clazz);
2593 f = (fieldinfo *) fieldID;
2595 if (!(c->state & CLASS_INITIALIZED))
2596 if (!initialize_class(c))
2599 f->value->a = value;
2603 /* String Operations **********************************************************/
2605 /* NewString *******************************************************************
2607 Create new java.lang.String object from an array of Unicode
2610 *******************************************************************************/
2612 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2614 java_lang_String *s;
2615 java_handle_chararray_t *a;
2618 STATISTICS(jniinvokation());
2620 s = (java_lang_String *) builtin_new(class_java_lang_String);
2621 a = builtin_newarray_char(len);
2623 /* javastring or characterarray could not be created */
2624 if ((a == NULL) || (s == NULL))
2628 for (i = 0; i < len; i++)
2629 LLNI_array_direct(a, i) = buf[i];
2631 LLNI_field_set_ref(s, value , a);
2632 LLNI_field_set_val(s, offset, 0);
2633 LLNI_field_set_val(s, count , len);
2635 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2639 static jchar emptyStringJ[]={0,0};
2641 /* GetStringLength *************************************************************
2643 Returns the length (the count of Unicode characters) of a Java
2646 *******************************************************************************/
2648 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2650 java_lang_String *s;
2653 TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
2655 s = (java_lang_String *) str;
2657 LLNI_field_get_val(s, count, len);
2663 /******************** convertes javastring to u2-array ****************************/
2665 u2 *javastring_tou2(jstring so)
2667 java_lang_String *s;
2668 java_handle_chararray_t *a;
2674 STATISTICS(jniinvokation());
2676 s = (java_lang_String *) so;
2681 LLNI_field_get_ref(s, value, a);
2686 LLNI_field_get_val(s, count, count);
2687 LLNI_field_get_val(s, offset, offset);
2689 /* allocate memory */
2691 stringbuffer = MNEW(u2, count + 1);
2695 for (i = 0; i < count; i++)
2696 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2698 /* terminate string */
2700 stringbuffer[i] = '\0';
2702 return stringbuffer;
2706 /* GetStringChars **************************************************************
2708 Returns a pointer to the array of Unicode characters of the
2709 string. This pointer is valid until ReleaseStringChars() is called.
2711 *******************************************************************************/
2713 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2717 STATISTICS(jniinvokation());
2719 jc = javastring_tou2(str);
2731 return emptyStringJ;
2735 /* ReleaseStringChars **********************************************************
2737 Informs the VM that the native code no longer needs access to
2738 chars. The chars argument is a pointer obtained from string using
2741 *******************************************************************************/
2743 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2745 java_lang_String *s;
2747 STATISTICS(jniinvokation());
2749 if (chars == emptyStringJ)
2752 s = (java_lang_String *) str;
2754 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2758 /* NewStringUTF ****************************************************************
2760 Constructs a new java.lang.String object from an array of UTF-8
2763 *******************************************************************************/
2765 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2767 java_lang_String *s;
2769 TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
2771 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2773 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2777 /****************** returns the utf8 length in bytes of a string *******************/
2779 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2781 java_lang_String *s;
2784 TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
2786 s = (java_lang_String *) string;
2788 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2794 /* GetStringUTFChars ***********************************************************
2796 Returns a pointer to an array of UTF-8 characters of the
2797 string. This array is valid until it is released by
2798 ReleaseStringUTFChars().
2800 *******************************************************************************/
2802 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2807 STATISTICS(jniinvokation());
2815 u = javastring_toutf((java_handle_t *) string, false);
2824 /* ReleaseStringUTFChars *******************************************************
2826 Informs the VM that the native code no longer needs access to
2827 utf. The utf argument is a pointer derived from string using
2828 GetStringUTFChars().
2830 *******************************************************************************/
2832 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2834 STATISTICS(jniinvokation());
2836 /* XXX we don't release utf chars right now, perhaps that should be done
2837 later. Since there is always one reference the garbage collector will
2842 /* Array Operations ***********************************************************/
2844 /* GetArrayLength **************************************************************
2846 Returns the number of elements in the array.
2848 *******************************************************************************/
2850 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2855 STATISTICS(jniinvokation());
2857 a = (java_handle_t *) array;
2859 size = LLNI_array_size(a);
2865 /* NewObjectArray **************************************************************
2867 Constructs a new array holding objects in class elementClass. All
2868 elements are initially set to initialElement.
2870 *******************************************************************************/
2872 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2873 jclass elementClass, jobject initialElement)
2877 java_handle_objectarray_t *oa;
2880 STATISTICS(jniinvokation());
2882 c = LLNI_classinfo_unwrap(elementClass);
2883 o = (java_handle_t *) initialElement;
2886 exceptions_throw_negativearraysizeexception();
2890 oa = builtin_anewarray(length, c);
2895 /* set all elements to initialElement */
2897 for (i = 0; i < length; i++)
2898 LLNI_objectarray_element_set(oa, i, o);
2900 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2904 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2907 java_handle_objectarray_t *oa;
2910 STATISTICS(jniinvokation());
2912 oa = (java_handle_objectarray_t *) array;
2914 if (index >= LLNI_array_size(oa)) {
2915 exceptions_throw_arrayindexoutofboundsexception();
2919 LLNI_objectarray_element_get(oa, index, o);
2921 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2925 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2926 jsize index, jobject val)
2928 java_handle_objectarray_t *oa;
2931 STATISTICS(jniinvokation());
2933 oa = (java_handle_objectarray_t *) array;
2934 o = (java_handle_t *) val;
2936 if (index >= LLNI_array_size(oa)) {
2937 exceptions_throw_arrayindexoutofboundsexception();
2941 /* check if the class of value is a subclass of the element class
2944 if (!builtin_canstore(oa, o))
2947 LLNI_objectarray_element_set(oa, index, o);
2951 #define JNI_NEW_ARRAY(name, type, intern) \
2952 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2954 java_handle_##intern##array_t *a; \
2956 STATISTICS(jniinvokation()); \
2959 exceptions_throw_negativearraysizeexception(); \
2963 a = builtin_newarray_##intern(len); \
2965 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2968 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2969 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2970 JNI_NEW_ARRAY(Char, jcharArray, char)
2971 JNI_NEW_ARRAY(Short, jshortArray, byte)
2972 JNI_NEW_ARRAY(Int, jintArray, int)
2973 JNI_NEW_ARRAY(Long, jlongArray, long)
2974 JNI_NEW_ARRAY(Float, jfloatArray, float)
2975 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2978 /* Get<PrimitiveType>ArrayElements *********************************************
2980 A family of functions that returns the body of the primitive array.
2982 *******************************************************************************/
2984 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2985 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2988 java_handle_##intern##array_t *a; \
2990 STATISTICS(jniinvokation()); \
2992 a = (java_handle_##intern##array_t *) array; \
2995 *isCopy = JNI_FALSE; \
2997 return LLNI_array_data(a); \
3000 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
3001 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
3002 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
3003 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
3004 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
3005 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
3006 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
3007 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
3010 /* Release<PrimitiveType>ArrayElements *****************************************
3012 A family of functions that informs the VM that the native code no
3013 longer needs access to elems. The elems argument is a pointer
3014 derived from array using the corresponding
3015 Get<PrimitiveType>ArrayElements() function. If necessary, this
3016 function copies back all changes made to elems to the original
3019 *******************************************************************************/
3021 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
3022 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
3023 type *elems, jint mode) \
3025 java_handle_##intern##array_t *a; \
3027 STATISTICS(jniinvokation()); \
3029 a = (java_handle_##intern##array_t *) array; \
3031 if (elems != LLNI_array_data(a)) { \
3034 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3037 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3038 /* XXX TWISTI how should it be freed? */ \
3041 /* XXX TWISTI how should it be freed? */ \
3047 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3048 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3049 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3050 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3051 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3052 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3053 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3054 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3057 /* Get<PrimitiveType>ArrayRegion **********************************************
3059 A family of functions that copies a region of a primitive array
3062 *******************************************************************************/
3064 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3065 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3066 jsize start, jsize len, type *buf) \
3068 java_handle_##intern##array_t *a; \
3070 STATISTICS(jniinvokation()); \
3072 a = (java_handle_##intern##array_t *) array; \
3074 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3075 exceptions_throw_arrayindexoutofboundsexception(); \
3077 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3080 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3081 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3082 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3083 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3084 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3085 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3086 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3087 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3090 /* Set<PrimitiveType>ArrayRegion **********************************************
3092 A family of functions that copies back a region of a primitive
3093 array from a buffer.
3095 *******************************************************************************/
3097 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3098 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3099 jsize start, jsize len, const type *buf) \
3101 java_handle_##intern##array_t *a; \
3103 STATISTICS(jniinvokation()); \
3105 a = (java_handle_##intern##array_t *) array; \
3107 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3108 exceptions_throw_arrayindexoutofboundsexception(); \
3110 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3113 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3114 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3115 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3116 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3117 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3118 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3119 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3120 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3123 /* Registering Native Methods *************************************************/
3125 /* RegisterNatives *************************************************************
3127 Registers native methods with the class specified by the clazz
3128 argument. The methods parameter specifies an array of
3129 JNINativeMethod structures that contain the names, signatures, and
3130 function pointers of the native methods. The nMethods parameter
3131 specifies the number of native methods in the array.
3133 *******************************************************************************/
3135 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3136 const JNINativeMethod *methods, jint nMethods)
3140 STATISTICS(jniinvokation());
3142 c = LLNI_classinfo_unwrap(clazz);
3144 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3145 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3148 native_method_register(c->name, methods, nMethods);
3154 /* UnregisterNatives ***********************************************************
3156 Unregisters native methods of a class. The class goes back to the
3157 state before it was linked or registered with its native method
3160 This function should not be used in normal native code. Instead, it
3161 provides special programs a way to reload and relink native
3164 *******************************************************************************/
3166 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3168 STATISTICS(jniinvokation());
3170 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3172 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3178 /* Monitor Operations *********************************************************/
3180 /* MonitorEnter ****************************************************************
3182 Enters the monitor associated with the underlying Java object
3185 *******************************************************************************/
3187 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3189 STATISTICS(jniinvokation());
3192 exceptions_throw_nullpointerexception();
3196 LOCK_MONITOR_ENTER(obj);
3202 /* MonitorExit *****************************************************************
3204 The current thread must be the owner of the monitor associated with
3205 the underlying Java object referred to by obj. The thread
3206 decrements the counter indicating the number of times it has
3207 entered this monitor. If the value of the counter becomes zero, the
3208 current thread releases the monitor.
3210 *******************************************************************************/
3212 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3214 STATISTICS(jniinvokation());
3217 exceptions_throw_nullpointerexception();
3221 LOCK_MONITOR_EXIT(obj);
3227 /* JavaVM Interface ***********************************************************/
3229 /* GetJavaVM *******************************************************************
3231 Returns the Java VM interface (used in the Invocation API)
3232 associated with the current thread. The result is placed at the
3233 location pointed to by the second argument, vm.
3235 *******************************************************************************/
3237 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3239 STATISTICS(jniinvokation());
3241 *vm = (JavaVM *) _Jv_jvm;
3247 /* GetStringRegion *************************************************************
3249 Copies len number of Unicode characters beginning at offset start
3250 to the given buffer buf.
3252 Throws StringIndexOutOfBoundsException on index overflow.
3254 *******************************************************************************/
3256 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3259 java_lang_String *s;
3260 java_handle_chararray_t *ca;
3262 STATISTICS(jniinvokation());
3264 s = (java_lang_String *) str;
3265 LLNI_field_get_ref(s, value, ca);
3267 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3268 (start + len > LLNI_field_direct(s, count))) {
3269 exceptions_throw_stringindexoutofboundsexception();
3273 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3277 /* GetStringUTFRegion **********************************************************
3279 Translates len number of Unicode characters beginning at offset
3280 start into UTF-8 format and place the result in the given buffer
3283 Throws StringIndexOutOfBoundsException on index overflow.
3285 *******************************************************************************/
3287 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3288 jsize len, char *buf)
3290 java_lang_String *s;
3291 java_handle_chararray_t *ca;
3296 TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
3298 s = (java_lang_String *) str;
3299 LLNI_field_get_ref(s, value, ca);
3300 LLNI_field_get_val(s, count, count);
3301 LLNI_field_get_val(s, offset, offset);
3303 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3304 exceptions_throw_stringindexoutofboundsexception();
3308 for (i = 0; i < len; i++)
3309 buf[i] = LLNI_array_direct(ca, offset + start + i);
3315 /* GetPrimitiveArrayCritical ***************************************************
3317 Obtain a direct pointer to array elements.
3319 *******************************************************************************/
3321 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3324 java_handle_bytearray_t *ba;
3327 ba = (java_handle_bytearray_t *) array;
3329 /* do the same as Kaffe does */
3331 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3337 /* ReleasePrimitiveArrayCritical ***********************************************
3339 No specific documentation.
3341 *******************************************************************************/
3343 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3344 void *carray, jint mode)
3346 STATISTICS(jniinvokation());
3348 /* do the same as Kaffe does */
3350 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3355 /* GetStringCritical ***********************************************************
3357 The semantics of these two functions are similar to the existing
3358 Get/ReleaseStringChars functions.
3360 *******************************************************************************/
3362 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3365 STATISTICS(jniinvokation());
3367 return _Jv_JNI_GetStringChars(env, string, isCopy);
3371 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3372 const jchar *cstring)
3374 STATISTICS(jniinvokation());
3376 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3380 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3382 STATISTICS(jniinvokation());
3384 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
3390 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3392 STATISTICS(jniinvokation());
3394 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
3398 /* NewGlobalRef ****************************************************************
3400 Creates a new global reference to the object referred to by the obj
3403 *******************************************************************************/
3405 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3407 hashtable_global_ref_entry *gre;
3408 u4 key; /* hashkey */
3409 u4 slot; /* slot in hashtable */
3412 STATISTICS(jniinvokation());
3414 o = (java_handle_t *) obj;
3416 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3418 /* normally addresses are aligned to 4, 8 or 16 bytes */
3420 key = ((u4) (ptrint) obj) >> 4; /* align to 16-byte boundaries */
3421 slot = key & (hashtable_global_ref->size - 1);
3422 gre = hashtable_global_ref->ptr[slot];
3424 /* search external hash chain for the entry */
3428 /* global object found, increment the reference */
3432 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3437 gre = gre->hashlink; /* next element in external chain */
3440 /* global ref not found, create a new one */
3442 gre = NEW(hashtable_global_ref_entry);
3447 /* insert entry into hashtable */
3449 gre->hashlink = hashtable_global_ref->ptr[slot];
3451 hashtable_global_ref->ptr[slot] = gre;
3453 /* update number of hashtable-entries */
3455 hashtable_global_ref->entries++;
3457 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3463 /* DeleteGlobalRef *************************************************************
3465 Deletes the global reference pointed to by globalRef.
3467 *******************************************************************************/
3469 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3471 hashtable_global_ref_entry *gre;
3472 hashtable_global_ref_entry *prevgre;
3473 u4 key; /* hashkey */
3474 u4 slot; /* slot in hashtable */
3477 STATISTICS(jniinvokation());
3479 o = (java_handle_t *) globalRef;
3481 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3483 /* normally addresses are aligned to 4, 8 or 16 bytes */
3485 key = ((u4) (ptrint) globalRef) >> 4; /* align to 16-byte boundaries */
3486 slot = key & (hashtable_global_ref->size - 1);
3487 gre = hashtable_global_ref->ptr[slot];
3489 /* initialize prevgre */
3493 /* search external hash chain for the entry */
3497 /* global object found, decrement the reference count */
3501 /* if reference count is 0, remove the entry */
3503 if (gre->refs == 0) {
3504 /* special handling if it's the first in the chain */
3506 if (prevgre == NULL)
3507 hashtable_global_ref->ptr[slot] = gre->hashlink;
3509 prevgre->hashlink = gre->hashlink;
3511 FREE(gre, hashtable_global_ref_entry);
3514 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3519 prevgre = gre; /* save current pointer for removal */
3520 gre = gre->hashlink; /* next element in external chain */
3523 log_println("JNI-DeleteGlobalRef: global reference not found");
3525 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3529 /* ExceptionCheck **************************************************************
3531 Returns JNI_TRUE when there is a pending exception; otherwise,
3534 *******************************************************************************/
3536 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3540 STATISTICS(jniinvokation());
3542 o = exceptions_get_exception();
3544 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3548 /* New JNI 1.4 functions ******************************************************/
3550 /* NewDirectByteBuffer *********************************************************
3552 Allocates and returns a direct java.nio.ByteBuffer referring to the
3553 block of memory starting at the memory address address and
3554 extending capacity bytes.
3556 *******************************************************************************/
3558 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3560 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3561 java_handle_t *nbuf;
3563 # if SIZEOF_VOID_P == 8
3564 gnu_classpath_Pointer64 *paddress;
3566 gnu_classpath_Pointer32 *paddress;
3569 STATISTICS(jniinvokation());
3571 /* alocate a gnu.classpath.Pointer{32,64} object */
3573 # if SIZEOF_VOID_P == 8
3574 if (!(paddress = (gnu_classpath_Pointer64 *)
3575 builtin_new(class_gnu_classpath_Pointer64)))
3577 if (!(paddress = (gnu_classpath_Pointer32 *)
3578 builtin_new(class_gnu_classpath_Pointer32)))
3582 /* fill gnu.classpath.Pointer{32,64} with address */
3584 LLNI_field_set_val(paddress, data, (ptrint) address);
3586 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3588 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3589 (jmethodID) dbbirw_init, NULL, paddress,
3590 (jint) capacity, (jint) capacity, (jint) 0);
3592 /* add local reference and return the value */
3594 return _Jv_JNI_NewLocalRef(env, nbuf);
3596 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3598 /* keep compiler happy */
3605 /* GetDirectBufferAddress ******************************************************
3607 Fetches and returns the starting address of the memory region
3608 referenced by the given direct java.nio.Buffer.
3610 *******************************************************************************/
3612 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3614 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3615 java_nio_DirectByteBufferImpl *nbuf;
3616 # if SIZEOF_VOID_P == 8
3617 gnu_classpath_Pointer64 *paddress;
3619 gnu_classpath_Pointer32 *paddress;
3623 STATISTICS(jniinvokation());
3625 if (!builtin_instanceof(buf, class_java_nio_Buffer))
3628 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3630 # if SIZEOF_VOID_P == 8
3631 LLNI_field_get_ref(nbuf, address, paddress);
3632 /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
3634 LLNI_field_get_ref(nbuf, address, paddress);
3635 /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
3638 if (paddress == NULL)
3641 LLNI_field_get_val(paddress, data, address);
3642 /* this was the cast to avaoid warning: (void *) paddress->data */
3646 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3648 /* keep compiler happy */
3655 /* GetDirectBufferCapacity *****************************************************
3657 Fetches and returns the capacity in bytes of the memory region
3658 referenced by the given direct java.nio.Buffer.
3660 *******************************************************************************/
3662 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3664 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3666 java_nio_Buffer *nbuf;
3669 STATISTICS(jniinvokation());
3671 o = (java_handle_t *) buf;
3673 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3676 nbuf = (java_nio_Buffer *) o;
3678 LLNI_field_get_val(nbuf, cap, capacity);
3682 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3684 /* keep compiler happy */
3691 /* DestroyJavaVM ***************************************************************
3693 Unloads a Java VM and reclaims its resources. Only the main thread
3694 can unload the VM. The system waits until the main thread is only
3695 remaining user thread before it destroys the VM.
3697 *******************************************************************************/
3699 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3703 STATISTICS(jniinvokation());
3705 status = vm_destroy(vm);
3711 /* AttachCurrentThread *********************************************************
3713 Attaches the current thread to a Java VM. Returns a JNI interface
3714 pointer in the JNIEnv argument.
3716 Trying to attach a thread that is already attached is a no-op.
3718 A native thread cannot be attached simultaneously to two Java VMs.
3720 When a thread is attached to the VM, the context class loader is
3721 the bootstrap loader.
3723 *******************************************************************************/
3725 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3727 JavaVMAttachArgs *vm_aargs;
3729 #if defined(ENABLE_THREADS)
3730 if (threads_get_current_threadobject() == NULL) {
3731 vm_aargs = (JavaVMAttachArgs *) thr_args;
3733 if (vm_aargs != NULL) {
3734 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3735 (vm_aargs->version != JNI_VERSION_1_4))
3736 return JNI_EVERSION;
3739 if (!threads_attach_current_thread(vm_aargs, false))
3742 if (!localref_table_init())
3753 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3755 STATISTICS(jniinvokation());
3757 return jni_attach_current_thread(p_env, thr_args, false);
3761 /* DetachCurrentThread *********************************************************
3763 Detaches the current thread from a Java VM. All Java monitors held
3764 by this thread are released. All Java threads waiting for this
3765 thread to die are notified.
3767 In JDK 1.1, the main thread cannot be detached from the VM. It must
3768 call DestroyJavaVM to unload the entire VM.
3770 In the JDK, the main thread can be detached from the VM.
3772 The main thread, which is the thread that created the Java VM,
3773 cannot be detached from the VM. Instead, the main thread must call
3774 JNI_DestroyJavaVM() to unload the entire VM.
3776 *******************************************************************************/
3778 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3780 #if defined(ENABLE_THREADS)
3781 threadobject *thread;
3783 STATISTICS(jniinvokation());
3785 thread = threads_get_current_threadobject();
3790 if (!threads_detach_thread(thread))
3798 /* GetEnv **********************************************************************
3800 If the current thread is not attached to the VM, sets *env to NULL,
3801 and returns JNI_EDETACHED. If the specified version is not
3802 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3803 sets *env to the appropriate interface, and returns JNI_OK.
3805 *******************************************************************************/
3807 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3809 STATISTICS(jniinvokation());
3811 #if defined(ENABLE_THREADS)
3812 if (threads_get_current_threadobject() == NULL) {
3815 return JNI_EDETACHED;
3819 /* check the JNI version */
3822 case JNI_VERSION_1_1:
3823 case JNI_VERSION_1_2:
3824 case JNI_VERSION_1_4:
3832 #if defined(ENABLE_JVMTI)
3833 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3834 == JVMTI_VERSION_INTERFACE_JVMTI) {
3836 *env = (void *) jvmti_new_environment();
3845 return JNI_EVERSION;
3849 /* AttachCurrentThreadAsDaemon *************************************************
3851 Same semantics as AttachCurrentThread, but the newly-created
3852 java.lang.Thread instance is a daemon.
3854 If the thread has already been attached via either
3855 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3856 simply sets the value pointed to by penv to the JNIEnv of the
3857 current thread. In this case neither AttachCurrentThread nor this
3858 routine have any effect on the daemon status of the thread.
3860 *******************************************************************************/
3862 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3864 STATISTICS(jniinvokation());
3866 return jni_attach_current_thread(penv, args, true);
3870 /* JNI invocation table *******************************************************/
3872 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3877 _Jv_JNI_DestroyJavaVM,
3878 _Jv_JNI_AttachCurrentThread,
3879 _Jv_JNI_DetachCurrentThread,
3881 _Jv_JNI_AttachCurrentThreadAsDaemon
3885 /* JNI function table *********************************************************/
3887 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3894 _Jv_JNI_DefineClass,
3896 _Jv_JNI_FromReflectedMethod,
3897 _Jv_JNI_FromReflectedField,
3898 _Jv_JNI_ToReflectedMethod,
3899 _Jv_JNI_GetSuperclass,
3900 _Jv_JNI_IsAssignableFrom,
3901 _Jv_JNI_ToReflectedField,
3905 _Jv_JNI_ExceptionOccurred,
3906 _Jv_JNI_ExceptionDescribe,
3907 _Jv_JNI_ExceptionClear,
3909 _Jv_JNI_PushLocalFrame,
3910 _Jv_JNI_PopLocalFrame,
3912 _Jv_JNI_NewGlobalRef,
3913 _Jv_JNI_DeleteGlobalRef,
3914 _Jv_JNI_DeleteLocalRef,
3915 _Jv_JNI_IsSameObject,
3916 _Jv_JNI_NewLocalRef,
3917 _Jv_JNI_EnsureLocalCapacity,
3919 _Jv_JNI_AllocObject,
3924 _Jv_JNI_GetObjectClass,
3925 _Jv_JNI_IsInstanceOf,
3927 _Jv_JNI_GetMethodID,
3929 _Jv_JNI_CallObjectMethod,
3930 _Jv_JNI_CallObjectMethodV,
3931 _Jv_JNI_CallObjectMethodA,
3932 _Jv_JNI_CallBooleanMethod,
3933 _Jv_JNI_CallBooleanMethodV,
3934 _Jv_JNI_CallBooleanMethodA,
3935 _Jv_JNI_CallByteMethod,
3936 _Jv_JNI_CallByteMethodV,
3937 _Jv_JNI_CallByteMethodA,
3938 _Jv_JNI_CallCharMethod,
3939 _Jv_JNI_CallCharMethodV,
3940 _Jv_JNI_CallCharMethodA,
3941 _Jv_JNI_CallShortMethod,
3942 _Jv_JNI_CallShortMethodV,
3943 _Jv_JNI_CallShortMethodA,
3944 _Jv_JNI_CallIntMethod,
3945 _Jv_JNI_CallIntMethodV,
3946 _Jv_JNI_CallIntMethodA,
3947 _Jv_JNI_CallLongMethod,
3948 _Jv_JNI_CallLongMethodV,
3949 _Jv_JNI_CallLongMethodA,
3950 _Jv_JNI_CallFloatMethod,
3951 _Jv_JNI_CallFloatMethodV,
3952 _Jv_JNI_CallFloatMethodA,
3953 _Jv_JNI_CallDoubleMethod,
3954 _Jv_JNI_CallDoubleMethodV,
3955 _Jv_JNI_CallDoubleMethodA,
3956 _Jv_JNI_CallVoidMethod,
3957 _Jv_JNI_CallVoidMethodV,
3958 _Jv_JNI_CallVoidMethodA,
3960 _Jv_JNI_CallNonvirtualObjectMethod,
3961 _Jv_JNI_CallNonvirtualObjectMethodV,
3962 _Jv_JNI_CallNonvirtualObjectMethodA,
3963 _Jv_JNI_CallNonvirtualBooleanMethod,
3964 _Jv_JNI_CallNonvirtualBooleanMethodV,
3965 _Jv_JNI_CallNonvirtualBooleanMethodA,
3966 _Jv_JNI_CallNonvirtualByteMethod,
3967 _Jv_JNI_CallNonvirtualByteMethodV,
3968 _Jv_JNI_CallNonvirtualByteMethodA,
3969 _Jv_JNI_CallNonvirtualCharMethod,
3970 _Jv_JNI_CallNonvirtualCharMethodV,
3971 _Jv_JNI_CallNonvirtualCharMethodA,
3972 _Jv_JNI_CallNonvirtualShortMethod,
3973 _Jv_JNI_CallNonvirtualShortMethodV,
3974 _Jv_JNI_CallNonvirtualShortMethodA,
3975 _Jv_JNI_CallNonvirtualIntMethod,
3976 _Jv_JNI_CallNonvirtualIntMethodV,
3977 _Jv_JNI_CallNonvirtualIntMethodA,
3978 _Jv_JNI_CallNonvirtualLongMethod,
3979 _Jv_JNI_CallNonvirtualLongMethodV,
3980 _Jv_JNI_CallNonvirtualLongMethodA,
3981 _Jv_JNI_CallNonvirtualFloatMethod,
3982 _Jv_JNI_CallNonvirtualFloatMethodV,
3983 _Jv_JNI_CallNonvirtualFloatMethodA,
3984 _Jv_JNI_CallNonvirtualDoubleMethod,
3985 _Jv_JNI_CallNonvirtualDoubleMethodV,
3986 _Jv_JNI_CallNonvirtualDoubleMethodA,
3987 _Jv_JNI_CallNonvirtualVoidMethod,
3988 _Jv_JNI_CallNonvirtualVoidMethodV,
3989 _Jv_JNI_CallNonvirtualVoidMethodA,
3993 _Jv_JNI_GetObjectField,
3994 _Jv_JNI_GetBooleanField,
3995 _Jv_JNI_GetByteField,
3996 _Jv_JNI_GetCharField,
3997 _Jv_JNI_GetShortField,
3998 _Jv_JNI_GetIntField,
3999 _Jv_JNI_GetLongField,
4000 _Jv_JNI_GetFloatField,
4001 _Jv_JNI_GetDoubleField,
4002 _Jv_JNI_SetObjectField,
4003 _Jv_JNI_SetBooleanField,
4004 _Jv_JNI_SetByteField,
4005 _Jv_JNI_SetCharField,
4006 _Jv_JNI_SetShortField,
4007 _Jv_JNI_SetIntField,
4008 _Jv_JNI_SetLongField,
4009 _Jv_JNI_SetFloatField,
4010 _Jv_JNI_SetDoubleField,
4012 _Jv_JNI_GetStaticMethodID,
4014 _Jv_JNI_CallStaticObjectMethod,
4015 _Jv_JNI_CallStaticObjectMethodV,
4016 _Jv_JNI_CallStaticObjectMethodA,
4017 _Jv_JNI_CallStaticBooleanMethod,
4018 _Jv_JNI_CallStaticBooleanMethodV,
4019 _Jv_JNI_CallStaticBooleanMethodA,
4020 _Jv_JNI_CallStaticByteMethod,
4021 _Jv_JNI_CallStaticByteMethodV,
4022 _Jv_JNI_CallStaticByteMethodA,
4023 _Jv_JNI_CallStaticCharMethod,
4024 _Jv_JNI_CallStaticCharMethodV,
4025 _Jv_JNI_CallStaticCharMethodA,
4026 _Jv_JNI_CallStaticShortMethod,
4027 _Jv_JNI_CallStaticShortMethodV,
4028 _Jv_JNI_CallStaticShortMethodA,
4029 _Jv_JNI_CallStaticIntMethod,
4030 _Jv_JNI_CallStaticIntMethodV,
4031 _Jv_JNI_CallStaticIntMethodA,
4032 _Jv_JNI_CallStaticLongMethod,
4033 _Jv_JNI_CallStaticLongMethodV,
4034 _Jv_JNI_CallStaticLongMethodA,
4035 _Jv_JNI_CallStaticFloatMethod,
4036 _Jv_JNI_CallStaticFloatMethodV,
4037 _Jv_JNI_CallStaticFloatMethodA,
4038 _Jv_JNI_CallStaticDoubleMethod,
4039 _Jv_JNI_CallStaticDoubleMethodV,
4040 _Jv_JNI_CallStaticDoubleMethodA,
4041 _Jv_JNI_CallStaticVoidMethod,
4042 _Jv_JNI_CallStaticVoidMethodV,
4043 _Jv_JNI_CallStaticVoidMethodA,
4045 _Jv_JNI_GetStaticFieldID,
4047 _Jv_JNI_GetStaticObjectField,
4048 _Jv_JNI_GetStaticBooleanField,
4049 _Jv_JNI_GetStaticByteField,
4050 _Jv_JNI_GetStaticCharField,
4051 _Jv_JNI_GetStaticShortField,
4052 _Jv_JNI_GetStaticIntField,
4053 _Jv_JNI_GetStaticLongField,
4054 _Jv_JNI_GetStaticFloatField,
4055 _Jv_JNI_GetStaticDoubleField,
4056 _Jv_JNI_SetStaticObjectField,
4057 _Jv_JNI_SetStaticBooleanField,
4058 _Jv_JNI_SetStaticByteField,
4059 _Jv_JNI_SetStaticCharField,
4060 _Jv_JNI_SetStaticShortField,
4061 _Jv_JNI_SetStaticIntField,
4062 _Jv_JNI_SetStaticLongField,
4063 _Jv_JNI_SetStaticFloatField,
4064 _Jv_JNI_SetStaticDoubleField,
4067 _Jv_JNI_GetStringLength,
4068 _Jv_JNI_GetStringChars,
4069 _Jv_JNI_ReleaseStringChars,
4071 _Jv_JNI_NewStringUTF,
4072 _Jv_JNI_GetStringUTFLength,
4073 _Jv_JNI_GetStringUTFChars,
4074 _Jv_JNI_ReleaseStringUTFChars,
4076 _Jv_JNI_GetArrayLength,
4078 _Jv_JNI_NewObjectArray,
4079 _Jv_JNI_GetObjectArrayElement,
4080 _Jv_JNI_SetObjectArrayElement,
4082 _Jv_JNI_NewBooleanArray,
4083 _Jv_JNI_NewByteArray,
4084 _Jv_JNI_NewCharArray,
4085 _Jv_JNI_NewShortArray,
4086 _Jv_JNI_NewIntArray,
4087 _Jv_JNI_NewLongArray,
4088 _Jv_JNI_NewFloatArray,
4089 _Jv_JNI_NewDoubleArray,
4091 _Jv_JNI_GetBooleanArrayElements,
4092 _Jv_JNI_GetByteArrayElements,
4093 _Jv_JNI_GetCharArrayElements,
4094 _Jv_JNI_GetShortArrayElements,
4095 _Jv_JNI_GetIntArrayElements,
4096 _Jv_JNI_GetLongArrayElements,
4097 _Jv_JNI_GetFloatArrayElements,
4098 _Jv_JNI_GetDoubleArrayElements,
4100 _Jv_JNI_ReleaseBooleanArrayElements,
4101 _Jv_JNI_ReleaseByteArrayElements,
4102 _Jv_JNI_ReleaseCharArrayElements,
4103 _Jv_JNI_ReleaseShortArrayElements,
4104 _Jv_JNI_ReleaseIntArrayElements,
4105 _Jv_JNI_ReleaseLongArrayElements,
4106 _Jv_JNI_ReleaseFloatArrayElements,
4107 _Jv_JNI_ReleaseDoubleArrayElements,
4109 _Jv_JNI_GetBooleanArrayRegion,
4110 _Jv_JNI_GetByteArrayRegion,
4111 _Jv_JNI_GetCharArrayRegion,
4112 _Jv_JNI_GetShortArrayRegion,
4113 _Jv_JNI_GetIntArrayRegion,
4114 _Jv_JNI_GetLongArrayRegion,
4115 _Jv_JNI_GetFloatArrayRegion,
4116 _Jv_JNI_GetDoubleArrayRegion,
4117 _Jv_JNI_SetBooleanArrayRegion,
4118 _Jv_JNI_SetByteArrayRegion,
4119 _Jv_JNI_SetCharArrayRegion,
4120 _Jv_JNI_SetShortArrayRegion,
4121 _Jv_JNI_SetIntArrayRegion,
4122 _Jv_JNI_SetLongArrayRegion,
4123 _Jv_JNI_SetFloatArrayRegion,
4124 _Jv_JNI_SetDoubleArrayRegion,
4126 _Jv_JNI_RegisterNatives,
4127 _Jv_JNI_UnregisterNatives,
4129 _Jv_JNI_MonitorEnter,
4130 _Jv_JNI_MonitorExit,
4134 /* new JNI 1.2 functions */
4136 _Jv_JNI_GetStringRegion,
4137 _Jv_JNI_GetStringUTFRegion,
4139 _Jv_JNI_GetPrimitiveArrayCritical,
4140 _Jv_JNI_ReleasePrimitiveArrayCritical,
4142 _Jv_JNI_GetStringCritical,
4143 _Jv_JNI_ReleaseStringCritical,
4145 _Jv_JNI_NewWeakGlobalRef,
4146 _Jv_JNI_DeleteWeakGlobalRef,
4148 _Jv_JNI_ExceptionCheck,
4150 /* new JNI 1.4 functions */
4152 _Jv_JNI_NewDirectByteBuffer,
4153 _Jv_JNI_GetDirectBufferAddress,
4154 _Jv_JNI_GetDirectBufferCapacity
4158 /* Invocation API Functions ***************************************************/
4160 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4162 Returns a default configuration for the Java VM.
4164 *******************************************************************************/
4166 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4168 JavaVMInitArgs *_vm_args;
4170 _vm_args = (JavaVMInitArgs *) vm_args;
4172 /* GNU classpath currently supports JNI 1.2 */
4174 switch (_vm_args->version) {
4175 case JNI_VERSION_1_1:
4176 _vm_args->version = JNI_VERSION_1_1;
4179 case JNI_VERSION_1_2:
4180 case JNI_VERSION_1_4:
4181 _vm_args->ignoreUnrecognized = JNI_FALSE;
4182 _vm_args->options = NULL;
4183 _vm_args->nOptions = 0;
4194 /* JNI_GetCreatedJavaVMs *******************************************************
4196 Returns all Java VMs that have been created. Pointers to VMs are written in
4197 the buffer vmBuf in the order they are created. At most bufLen number of
4198 entries will be written. The total number of created VMs is returned in
4201 *******************************************************************************/
4203 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4205 TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
4210 /* We currently only support 1 VM running. */
4212 vmBuf[0] = (JavaVM *) _Jv_jvm;
4219 /* JNI_CreateJavaVM ************************************************************
4221 Loads and initializes a Java VM. The current thread becomes the main thread.
4222 Sets the env argument to the JNI interface pointer of the main thread.
4224 *******************************************************************************/
4226 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4228 TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
4230 /* actually create the JVM */
4232 if (!vm_createjvm(p_vm, p_env, vm_args))
4240 * These are local overrides for various environment variables in Emacs.
4241 * Please do not remove this and leave it at the end of the file, where
4242 * Emacs will automagically detect them.
4243 * ---------------------------------------------------------------------
4246 * indent-tabs-mode: t
4250 * vim:noexpandtab:sw=4:ts=4: