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 8297 2007-08-12 00:02:48Z michi $
38 #include "mm/gc-common.h"
39 #include "mm/memory.h"
40 #include "native/jni.h"
41 #include "native/llni.h"
42 #include "native/native.h"
44 #if defined(ENABLE_JAVASE)
45 # if defined(WITH_CLASSPATH_GNU)
46 # include "native/include/gnu_classpath_Pointer.h"
48 # if SIZEOF_VOID_P == 8
49 # include "native/include/gnu_classpath_Pointer64.h"
51 # include "native/include/gnu_classpath_Pointer32.h"
56 #include "native/include/java_lang_Object.h"
57 #include "native/include/java_lang_Byte.h"
58 #include "native/include/java_lang_Character.h"
59 #include "native/include/java_lang_Short.h"
60 #include "native/include/java_lang_Integer.h"
61 #include "native/include/java_lang_Boolean.h"
62 #include "native/include/java_lang_Long.h"
63 #include "native/include/java_lang_Float.h"
64 #include "native/include/java_lang_Double.h"
65 #include "native/include/java_lang_String.h"
66 #include "native/include/java_lang_Throwable.h"
68 #if defined(ENABLE_JAVASE)
69 # if defined(WITH_CLASSPATH_SUN)
70 # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
73 # include "native/include/java_lang_ClassLoader.h"
75 # include "native/include/java_lang_reflect_Constructor.h"
76 # include "native/include/java_lang_reflect_Field.h"
77 # include "native/include/java_lang_reflect_Method.h"
79 # include "native/include/java_nio_Buffer.h"
81 # if defined(WITH_CLASSPATH_GNU)
82 # include "native/include/java_nio_DirectByteBufferImpl.h"
86 #if defined(ENABLE_JVMTI)
87 # include "native/jvmti/cacaodbg.h"
90 #include "native/vm/java_lang_Class.h"
92 #if defined(ENABLE_JAVASE)
93 # include "native/vm/java_lang_ClassLoader.h"
94 # include "native/vm/reflect.h"
97 #include "threads/lock-common.h"
98 #include "threads/threads-common.h"
100 #include "toolbox/logging.h"
102 #include "vm/builtin.h"
103 #include "vm/exceptions.h"
104 #include "vm/global.h"
105 #include "vm/initialize.h"
106 #include "vm/primitive.h"
107 #include "vm/resolve.h"
108 #include "vm/stringlocal.h"
111 #include "vm/jit/asmpart.h"
112 #include "vm/jit/jit.h"
113 #include "vm/jit/stacktrace.h"
115 #include "vmcore/loader.h"
116 #include "vmcore/options.h"
117 #include "vmcore/statistics.h"
120 /* debug **********************************************************************/
123 # define TRACEJNICALLS(format, ...) \
125 if (opt_TraceJNICalls) { \
126 log_println((format), __VA_ARGS__); \
130 # define TRACEJNICALLS(format, ...)
134 /* global variables ***********************************************************/
136 /* global reference table *****************************************************/
138 /* hashsize must be power of 2 */
140 #define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
142 static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
145 /* direct buffer stuff ********************************************************/
147 #if defined(ENABLE_JAVASE)
148 static classinfo *class_java_nio_Buffer;
149 static classinfo *class_java_nio_DirectByteBufferImpl;
150 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
152 # if defined(WITH_CLASSPATH_GNU)
153 # if SIZEOF_VOID_P == 8
154 static classinfo *class_gnu_classpath_Pointer64;
156 static classinfo *class_gnu_classpath_Pointer32;
160 static methodinfo *dbbirw_init;
164 /* accessing instance fields macros *******************************************/
166 #define SET_FIELD(o,type,f,value) \
167 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
169 #define GET_FIELD(o,type,f) \
170 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
173 /* some forward declarations **************************************************/
175 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
176 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity);
179 /* jni_init ********************************************************************
181 Initialize the JNI subsystem.
183 *******************************************************************************/
187 /* create global ref hashtable */
189 hashtable_global_ref = NEW(hashtable);
191 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
194 #if defined(ENABLE_JAVASE)
195 /* direct buffer stuff */
197 if (!(class_java_nio_Buffer =
198 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
199 !link_class(class_java_nio_Buffer))
202 # if defined(WITH_CLASSPATH_GNU)
203 if (!(class_java_nio_DirectByteBufferImpl =
204 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
205 !link_class(class_java_nio_DirectByteBufferImpl))
208 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
209 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
210 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
214 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
216 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
219 # if SIZEOF_VOID_P == 8
220 if (!(class_gnu_classpath_Pointer64 =
221 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
222 !link_class(class_gnu_classpath_Pointer64))
225 if (!(class_gnu_classpath_Pointer32 =
226 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
227 !link_class(class_gnu_classpath_Pointer32))
231 #endif /* defined(ENABLE_JAVASE) */
237 /* _Jv_jni_CallObjectMethod ****************************************************
239 Internal function to call Java Object methods.
241 *******************************************************************************/
243 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
245 methodinfo *m, va_list ap)
250 STATISTICS(jniinvokation());
253 exceptions_throw_nullpointerexception();
257 /* Class initialization is done by the JIT compiler. This is ok
258 since a static method always belongs to the declaring class. */
260 if (m->flags & ACC_STATIC) {
261 /* For static methods we reset the object. */
266 /* for convenience */
271 /* For instance methods we make a virtual function table lookup. */
273 resm = method_vftbl_lookup(vftbl, m);
276 STATISTICS(jnicallXmethodnvokation());
278 ro = vm_call_method_valist(resm, o, ap);
284 /* _Jv_jni_CallObjectMethodA ***************************************************
286 Internal function to call Java Object methods.
288 *******************************************************************************/
290 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
298 STATISTICS(jniinvokation());
301 exceptions_throw_nullpointerexception();
305 /* Class initialization is done by the JIT compiler. This is ok
306 since a static method always belongs to the declaring class. */
308 if (m->flags & ACC_STATIC) {
309 /* For static methods we reset the object. */
314 /* for convenience */
319 /* For instance methods we make a virtual function table lookup. */
321 resm = method_vftbl_lookup(vftbl, m);
324 STATISTICS(jnicallXmethodnvokation());
326 ro = vm_call_method_jvalue(resm, o, args);
332 /* _Jv_jni_CallIntMethod *******************************************************
334 Internal function to call Java integer class methods (boolean,
335 byte, char, short, int).
337 *******************************************************************************/
339 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
340 methodinfo *m, va_list ap)
345 STATISTICS(jniinvokation());
348 exceptions_throw_nullpointerexception();
352 /* Class initialization is done by the JIT compiler. This is ok
353 since a static method always belongs to the declaring class. */
355 if (m->flags & ACC_STATIC) {
356 /* For static methods we reset the object. */
361 /* for convenience */
366 /* For instance methods we make a virtual function table lookup. */
368 resm = method_vftbl_lookup(vftbl, m);
371 STATISTICS(jnicallXmethodnvokation());
373 i = vm_call_method_int_valist(resm, o, ap);
379 /* _Jv_jni_CallIntMethodA ******************************************************
381 Internal function to call Java integer class methods (boolean,
382 byte, char, short, int).
384 *******************************************************************************/
386 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
387 methodinfo *m, const jvalue *args)
392 STATISTICS(jniinvokation());
395 exceptions_throw_nullpointerexception();
399 /* Class initialization is done by the JIT compiler. This is ok
400 since a static method always belongs to the declaring class. */
402 if (m->flags & ACC_STATIC) {
403 /* For static methods we reset the object. */
408 /* for convenience */
413 /* For instance methods we make a virtual function table lookup. */
415 resm = method_vftbl_lookup(vftbl, m);
418 STATISTICS(jnicallXmethodnvokation());
420 i = vm_call_method_int_jvalue(resm, o, args);
426 /* _Jv_jni_CallLongMethod ******************************************************
428 Internal function to call Java long methods.
430 *******************************************************************************/
432 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
433 methodinfo *m, va_list ap)
438 STATISTICS(jniinvokation());
441 exceptions_throw_nullpointerexception();
445 /* Class initialization is done by the JIT compiler. This is ok
446 since a static method always belongs to the declaring class. */
448 if (m->flags & ACC_STATIC) {
449 /* For static methods we reset the object. */
454 /* for convenience */
459 /* For instance methods we make a virtual function table lookup. */
461 resm = method_vftbl_lookup(vftbl, m);
464 STATISTICS(jnicallXmethodnvokation());
466 l = vm_call_method_long_valist(resm, o, ap);
472 /* _Jv_jni_CallLongMethodA *****************************************************
474 Internal function to call Java long methods.
476 *******************************************************************************/
478 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
479 methodinfo *m, const jvalue *args)
484 STATISTICS(jniinvokation());
487 exceptions_throw_nullpointerexception();
491 /* Class initialization is done by the JIT compiler. This is ok
492 since a static method always belongs to the declaring class. */
494 if (m->flags & ACC_STATIC) {
495 /* For static methods we reset the object. */
500 /* for convenience */
505 /* For instance methods we make a virtual function table lookup. */
507 resm = method_vftbl_lookup(vftbl, m);
510 STATISTICS(jnicallXmethodnvokation());
512 l = vm_call_method_long_jvalue(resm, o, args);
518 /* _Jv_jni_CallFloatMethod *****************************************************
520 Internal function to call Java float methods.
522 *******************************************************************************/
524 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
525 methodinfo *m, va_list ap)
530 /* Class initialization is done by the JIT compiler. This is ok
531 since a static method always belongs to the declaring class. */
533 if (m->flags & ACC_STATIC) {
534 /* For static methods we reset the object. */
539 /* for convenience */
544 /* For instance methods we make a virtual function table lookup. */
546 resm = method_vftbl_lookup(vftbl, m);
549 STATISTICS(jnicallXmethodnvokation());
551 f = vm_call_method_float_valist(resm, o, ap);
557 /* _Jv_jni_CallFloatMethodA ****************************************************
559 Internal function to call Java float methods.
561 *******************************************************************************/
563 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
564 methodinfo *m, const jvalue *args)
569 /* Class initialization is done by the JIT compiler. This is ok
570 since a static method always belongs to the declaring class. */
572 if (m->flags & ACC_STATIC) {
573 /* For static methods we reset the object. */
578 /* for convenience */
583 /* For instance methods we make a virtual function table lookup. */
585 resm = method_vftbl_lookup(vftbl, m);
588 STATISTICS(jnicallXmethodnvokation());
590 f = vm_call_method_float_jvalue(resm, o, args);
596 /* _Jv_jni_CallDoubleMethod ****************************************************
598 Internal function to call Java double methods.
600 *******************************************************************************/
602 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
603 methodinfo *m, va_list ap)
608 /* Class initialization is done by the JIT compiler. This is ok
609 since a static method always belongs to the declaring class. */
611 if (m->flags & ACC_STATIC) {
612 /* For static methods we reset the object. */
617 /* for convenience */
622 /* For instance methods we make a virtual function table lookup. */
624 resm = method_vftbl_lookup(vftbl, m);
627 d = vm_call_method_double_valist(resm, o, ap);
633 /* _Jv_jni_CallDoubleMethodA ***************************************************
635 Internal function to call Java double methods.
637 *******************************************************************************/
639 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
640 methodinfo *m, const jvalue *args)
645 /* Class initialization is done by the JIT compiler. This is ok
646 since a static method always belongs to the declaring class. */
648 if (m->flags & ACC_STATIC) {
649 /* For static methods we reset the object. */
654 /* for convenience */
659 /* For instance methods we make a virtual function table lookup. */
661 resm = method_vftbl_lookup(vftbl, m);
664 d = vm_call_method_double_jvalue(resm, o, args);
670 /* _Jv_jni_CallVoidMethod ******************************************************
672 Internal function to call Java void methods.
674 *******************************************************************************/
676 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
677 methodinfo *m, va_list ap)
682 exceptions_throw_nullpointerexception();
686 /* Class initialization is done by the JIT compiler. This is ok
687 since a static method always belongs to the declaring class. */
689 if (m->flags & ACC_STATIC) {
690 /* For static methods we reset the object. */
695 /* for convenience */
700 /* For instance methods we make a virtual function table lookup. */
702 resm = method_vftbl_lookup(vftbl, m);
705 STATISTICS(jnicallXmethodnvokation());
707 (void) vm_call_method_valist(resm, o, ap);
711 /* _Jv_jni_CallVoidMethodA *****************************************************
713 Internal function to call Java void methods.
715 *******************************************************************************/
717 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
718 methodinfo *m, const jvalue *args)
723 exceptions_throw_nullpointerexception();
727 /* Class initialization is done by the JIT compiler. This is ok
728 since a static method always belongs to the declaring class. */
730 if (m->flags & ACC_STATIC) {
731 /* For static methods we reset the object. */
736 /* for convenience */
741 /* For instance methods we make a virtual function table lookup. */
743 resm = method_vftbl_lookup(vftbl, m);
746 STATISTICS(jnicallXmethodnvokation());
748 (void) vm_call_method_jvalue(resm, o, args);
752 /* _Jv_jni_invokeNative ********************************************************
754 Invoke a method on the given object with the given arguments.
756 For instance methods OBJ must be != NULL and the method is looked up
757 in the vftbl of the object.
759 For static methods, OBJ is ignored.
761 *******************************************************************************/
763 java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
764 java_objectarray *params)
776 exceptions_throw_nullpointerexception();
780 argcount = m->parseddesc->paramcount;
781 paramcount = argcount;
783 /* if method is non-static, remove the `this' pointer */
785 if (!(m->flags & ACC_STATIC))
788 /* For instance methods the object has to be an instance of the
789 class the method belongs to. For static methods the obj
790 parameter is ignored. */
792 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
793 exceptions_throw_illegalargumentexception();
797 /* check if we got the right number of arguments */
799 if (((params == NULL) && (paramcount != 0)) ||
800 (params && (params->header.size != paramcount)))
802 exceptions_throw_illegalargumentexception();
806 /* for instance methods we need an object */
808 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
809 /* XXX not sure if that is the correct exception */
810 exceptions_throw_nullpointerexception();
814 /* for static methods, zero object to make subsequent code simpler */
815 if (m->flags & ACC_STATIC)
819 /* for instance methods we must do a vftbl lookup */
820 resm = method_vftbl_lookup(o->vftbl, m);
823 /* for static methods, just for convenience */
827 /* mark start of dump memory area */
829 dumpsize = dump_size();
831 /* Fill the argument array from a object-array. */
833 array = vm_array_from_objectarray(resm, o, params);
835 /* The array can be NULL if we don't have any arguments to pass
836 and the architecture does not have any argument registers
837 (e.g. i386). In that case we additionally check for an
840 if ((array == NULL) && (exceptions_get_exception() != NULL)) {
841 /* release dump area */
843 dump_release(dumpsize);
848 switch (resm->parseddesc->returntype.decltype) {
850 (void) vm_call_array(resm, array);
854 case PRIMITIVETYPE_BOOLEAN:
855 case PRIMITIVETYPE_BYTE:
856 case PRIMITIVETYPE_CHAR:
857 case PRIMITIVETYPE_SHORT:
858 case PRIMITIVETYPE_INT:
859 value.i = vm_call_int_array(resm, array);
860 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
863 case PRIMITIVETYPE_LONG:
864 value.l = vm_call_long_array(resm, array);
865 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
868 case PRIMITIVETYPE_FLOAT:
869 value.f = vm_call_float_array(resm, array);
870 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
873 case PRIMITIVETYPE_DOUBLE:
874 value.d = vm_call_double_array(resm, array);
875 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
879 ro = vm_call_array(resm, array);
883 vm_abort("_Jv_jni_invokeNative: invalid return type %d", resm->parseddesc->returntype.decltype);
886 xptr = exceptions_get_exception();
889 /* clear exception pointer, we are calling JIT code again */
891 exceptions_clear_exception();
893 exceptions_throw_invocationtargetexception(xptr);
896 /* release dump area */
898 dump_release(dumpsize);
904 /* GetVersion ******************************************************************
906 Returns the major version number in the higher 16 bits and the
907 minor version number in the lower 16 bits.
909 *******************************************************************************/
911 jint _Jv_JNI_GetVersion(JNIEnv *env)
913 STATISTICS(jniinvokation());
915 /* we support JNI 1.4 */
917 return JNI_VERSION_1_4;
921 /* Class Operations ***********************************************************/
923 /* DefineClass *****************************************************************
925 Loads a class from a buffer of raw class data. The buffer
926 containing the raw class data is not referenced by the VM after the
927 DefineClass call returns, and it may be discarded if desired.
929 *******************************************************************************/
931 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
932 const jbyte *buf, jsize bufLen)
934 #if defined(ENABLE_JAVASE)
939 TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d", env, name, loader, buf, bufLen);
941 u = utf_new_char(name);
942 cl = (classloader *) loader;
944 c = class_define(u, cl, bufLen, (const uint8_t *) buf);
946 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
948 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
950 /* keep compiler happy */
957 /* FindClass *******************************************************************
959 This function loads a locally-defined class. It searches the
960 directories and zip files specified by the CLASSPATH environment
961 variable for the class with the specified name.
963 *******************************************************************************/
965 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
967 #if defined(ENABLE_JAVASE)
972 STATISTICS(jniinvokation());
974 u = utf_new_char_classname((char *) name);
976 /* Check stacktrace for classloader, if one found use it,
977 otherwise use the system classloader. */
979 /* Quote from the JNI documentation:
981 In the Java 2 Platform, FindClass locates the class loader
982 associated with the current native method. If the native code
983 belongs to a system class, no class loader will be
984 involved. Otherwise, the proper class loader will be invoked to
985 load and link the named class. When FindClass is called through
986 the Invocation Interface, there is no current native method or
987 its associated class loader. In that case, the result of
988 ClassLoader.getBaseClassLoader is used." */
990 cc = stacktrace_getCurrentClass();
993 c = load_class_from_sysloader(u);
995 c = load_class_from_classloader(u, cc->classloader);
1003 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1005 vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1007 /* keep compiler happy */
1014 /* GetSuperclass ***************************************************************
1016 If clazz represents any class other than the class Object, then
1017 this function returns the object that represents the superclass of
1018 the class specified by clazz.
1020 *******************************************************************************/
1022 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1027 TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
1029 c = (classinfo *) sub;
1034 super = class_get_superclass(c);
1036 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) super);
1040 /* IsAssignableFrom ************************************************************
1042 Determines whether an object of sub can be safely cast to sup.
1044 *******************************************************************************/
1046 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1048 java_lang_Class *csup;
1049 java_lang_Class *csub;
1051 csup = (java_lang_Class *) sup;
1052 csub = (java_lang_Class *) sub;
1054 STATISTICS(jniinvokation());
1056 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1060 /* Throw ***********************************************************************
1062 Causes a java.lang.Throwable object to be thrown.
1064 *******************************************************************************/
1066 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1070 STATISTICS(jniinvokation());
1072 o = (java_handle_t *) obj;
1074 exceptions_set_exception(o);
1080 /* ThrowNew ********************************************************************
1082 Constructs an exception object from the specified class with the
1083 message specified by message and causes that exception to be
1086 *******************************************************************************/
1088 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1094 STATISTICS(jniinvokation());
1096 c = (classinfo *) clazz;
1099 s = javastring_new_from_utf_string(msg);
1101 /* instantiate exception object */
1103 o = native_new_and_init_string(c, s);
1108 exceptions_set_exception(o);
1114 /* ExceptionOccurred ***********************************************************
1116 Determines if an exception is being thrown. The exception stays
1117 being thrown until either the native code calls ExceptionClear(),
1118 or the Java code handles the exception.
1120 *******************************************************************************/
1122 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1126 STATISTICS(jniinvokation());
1128 o = exceptions_get_exception();
1130 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1134 /* ExceptionDescribe ***********************************************************
1136 Prints an exception and a backtrace of the stack to a system
1137 error-reporting channel, such as stderr. This is a convenience
1138 routine provided for debugging.
1140 *******************************************************************************/
1142 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1147 STATISTICS(jniinvokation());
1149 o = exceptions_get_exception();
1152 /* clear exception, because we are calling jit code again */
1154 exceptions_clear_exception();
1156 /* get printStackTrace method from exception class */
1158 m = class_resolveclassmethod(o->vftbl->class,
1159 utf_printStackTrace,
1165 /* XXX what should we do? */
1168 /* print the stacktrace */
1170 (void) vm_call_method(m, o);
1175 /* ExceptionClear **************************************************************
1177 Clears any exception that is currently being thrown. If no
1178 exception is currently being thrown, this routine has no effect.
1180 *******************************************************************************/
1182 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1184 STATISTICS(jniinvokation());
1186 exceptions_clear_exception();
1190 /* FatalError ******************************************************************
1192 Raises a fatal error and does not expect the VM to recover. This
1193 function does not return.
1195 *******************************************************************************/
1197 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1199 STATISTICS(jniinvokation());
1201 /* this seems to be the best way */
1203 vm_abort("JNI Fatal error: %s", msg);
1207 /* PushLocalFrame **************************************************************
1209 Creates a new local reference frame, in which at least a given
1210 number of local references can be created.
1212 *******************************************************************************/
1214 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1216 STATISTICS(jniinvokation());
1221 /* add new local reference frame to current table */
1223 if (!localref_frame_push(capacity))
1230 /* PopLocalFrame ***************************************************************
1232 Pops off the current local reference frame, frees all the local
1233 references, and returns a local reference in the previous local
1234 reference frame for the given result object.
1236 *******************************************************************************/
1238 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1240 STATISTICS(jniinvokation());
1242 /* release all current local frames */
1244 localref_frame_pop_all();
1246 /* add local reference and return the value */
1248 return _Jv_JNI_NewLocalRef(env, result);
1252 /* DeleteLocalRef **************************************************************
1254 Deletes the local reference pointed to by localRef.
1256 *******************************************************************************/
1258 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1261 localref_table *lrt;
1264 STATISTICS(jniinvokation());
1266 o = (java_handle_t *) localRef;
1268 /* get local reference table (thread specific) */
1270 lrt = LOCALREFTABLE;
1272 /* go through all local frames */
1274 for (; lrt != NULL; lrt = lrt->prev) {
1276 /* and try to remove the reference */
1278 for (i = 0; i < lrt->capacity; i++) {
1279 if (lrt->refs[i] == o) {
1280 lrt->refs[i] = NULL;
1288 /* this should not happen */
1290 /* if (opt_checkjni) */
1291 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1292 log_text("JNI-DeleteLocalRef: Local ref passed to JNI not found");
1296 /* IsSameObject ****************************************************************
1298 Tests whether two references refer to the same Java object.
1300 *******************************************************************************/
1302 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1304 STATISTICS(jniinvokation());
1313 /* NewLocalRef *****************************************************************
1315 Creates a new local reference that refers to the same object as ref.
1317 *******************************************************************************/
1319 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1321 localref_table *lrt;
1324 STATISTICS(jniinvokation());
1329 /* get local reference table (thread specific) */
1331 lrt = LOCALREFTABLE;
1333 /* Check if we have space for the requested reference? No,
1334 allocate a new frame. This is actually not what the spec says,
1335 but for compatibility reasons... */
1337 if (lrt->used == lrt->capacity) {
1338 if (_Jv_JNI_EnsureLocalCapacity(env, 16) != 0)
1341 /* get the new local reference table */
1343 lrt = LOCALREFTABLE;
1346 /* insert the reference */
1348 for (i = 0; i < lrt->capacity; i++) {
1349 if (lrt->refs[i] == NULL) {
1350 lrt->refs[i] = (java_handle_t *) ref;
1357 /* should not happen, just to be sure */
1361 /* keep compiler happy */
1367 /* EnsureLocalCapacity *********************************************************
1369 Ensures that at least a given number of local references can be
1370 created in the current thread
1372 *******************************************************************************/
1374 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1376 localref_table *lrt;
1378 STATISTICS(jniinvokation());
1380 /* get local reference table (thread specific) */
1382 lrt = LOCALREFTABLE;
1384 /* check if capacity elements are available in the local references table */
1386 if ((lrt->used + capacity) > lrt->capacity)
1387 return _Jv_JNI_PushLocalFrame(env, capacity);
1393 /* AllocObject *****************************************************************
1395 Allocates a new Java object without invoking any of the
1396 constructors for the object. Returns a reference to the object.
1398 *******************************************************************************/
1400 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1405 STATISTICS(jniinvokation());
1407 c = (classinfo *) clazz;
1409 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1410 exceptions_throw_instantiationexception(c);
1416 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1420 /* NewObject *******************************************************************
1422 Programmers place all arguments that are to be passed to the
1423 constructor immediately following the methodID
1424 argument. NewObject() accepts these arguments and passes them to
1425 the Java method that the programmer wishes to invoke.
1427 *******************************************************************************/
1429 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1436 STATISTICS(jniinvokation());
1438 c = (classinfo *) clazz;
1439 m = (methodinfo *) methodID;
1448 /* call constructor */
1450 va_start(ap, methodID);
1451 _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
1454 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1458 /* NewObjectV ******************************************************************
1460 Programmers place all arguments that are to be passed to the
1461 constructor in an args argument of type va_list that immediately
1462 follows the methodID argument. NewObjectV() accepts these
1463 arguments, and, in turn, passes them to the Java method that the
1464 programmer wishes to invoke.
1466 *******************************************************************************/
1468 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1475 STATISTICS(jniinvokation());
1477 c = (classinfo *) clazz;
1478 m = (methodinfo *) methodID;
1487 /* call constructor */
1489 _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
1491 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1495 /* NewObjectA *****************************************************************
1497 Programmers place all arguments that are to be passed to the
1498 constructor in an args array of jvalues that immediately follows
1499 the methodID argument. NewObjectA() accepts the arguments in this
1500 array, and, in turn, passes them to the Java method that the
1501 programmer wishes to invoke.
1503 *******************************************************************************/
1505 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1512 STATISTICS(jniinvokation());
1514 c = (classinfo *) clazz;
1515 m = (methodinfo *) methodID;
1524 /* call constructor */
1526 _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
1528 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1532 /* GetObjectClass **************************************************************
1534 Returns the class of an object.
1536 *******************************************************************************/
1538 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1543 STATISTICS(jniinvokation());
1545 o = (java_handle_t *) obj;
1547 if ((o == NULL) || (o->vftbl == NULL))
1550 c = o->vftbl->class;
1552 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1556 /* IsInstanceOf ****************************************************************
1558 Tests whether an object is an instance of a class.
1560 *******************************************************************************/
1562 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1565 java_lang_Object *o;
1567 STATISTICS(jniinvokation());
1569 c = (java_lang_Class *) clazz;
1570 o = (java_lang_Object *) obj;
1572 return _Jv_java_lang_Class_isInstance(c, o);
1576 /* Reflection Support *********************************************************/
1578 /* FromReflectedMethod *********************************************************
1580 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1581 object to a method ID.
1583 *******************************************************************************/
1585 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1587 #if defined(ENABLE_JAVASE)
1593 STATISTICS(jniinvokation());
1595 o = (java_handle_t *) method;
1600 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1601 java_lang_reflect_Method *rm;
1603 rm = (java_lang_reflect_Method *) method;
1604 LLNI_field_get_cls(rm, clazz, c);
1605 LLNI_field_get_val(rm, slot , slot);
1607 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1608 java_lang_reflect_Constructor *rc;
1610 rc = (java_lang_reflect_Constructor *) method;
1611 LLNI_field_get_cls(rc, clazz, c);
1612 LLNI_field_get_val(rc, slot , slot);
1617 m = &(c->methods[slot]);
1619 return (jmethodID) m;
1621 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1623 /* keep compiler happy */
1630 /* FromReflectedField **********************************************************
1632 Converts a java.lang.reflect.Field to a field ID.
1634 *******************************************************************************/
1636 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1638 #if defined(ENABLE_JAVASE)
1639 java_lang_reflect_Field *rf;
1644 STATISTICS(jniinvokation());
1646 rf = (java_lang_reflect_Field *) field;
1651 LLNI_field_get_cls(rf, clazz, c);
1652 LLNI_field_get_val(rf, slot , slot);
1653 f = &(c->fields[slot]);
1655 return (jfieldID) f;
1657 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1659 /* keep compiler happy */
1666 /* ToReflectedMethod ***********************************************************
1668 Converts a method ID derived from cls to an instance of the
1669 java.lang.reflect.Method class or to an instance of the
1670 java.lang.reflect.Constructor class.
1672 *******************************************************************************/
1674 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1677 #if defined(ENABLE_JAVASE)
1679 java_lang_reflect_Constructor *rc;
1680 java_lang_reflect_Method *rm;
1682 STATISTICS(jniinvokation());
1684 m = (methodinfo *) methodID;
1686 /* HotSpot does the same assert. */
1688 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1690 if (m->name == utf_init) {
1691 rc = reflect_constructor_new(m);
1693 return (jobject) rc;
1696 rm = reflect_method_new(m);
1698 return (jobject) rm;
1701 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1703 /* keep compiler happy */
1710 /* ToReflectedField ************************************************************
1712 Converts a field ID derived from cls to an instance of the
1713 java.lang.reflect.Field class.
1715 *******************************************************************************/
1717 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1720 STATISTICS(jniinvokation());
1722 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1728 /* Calling Instance Methods ***************************************************/
1730 /* GetMethodID *****************************************************************
1732 Returns the method ID for an instance (nonstatic) method of a class
1733 or interface. The method may be defined in one of the clazz's
1734 superclasses and inherited by clazz. The method is determined by
1735 its name and signature.
1737 GetMethodID() causes an uninitialized class to be initialized.
1739 *******************************************************************************/
1741 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1749 STATISTICS(jniinvokation());
1751 c = (classinfo *) clazz;
1756 if (!(c->state & CLASS_INITIALIZED))
1757 if (!initialize_class(c))
1760 /* try to get the method of the class or one of it's superclasses */
1762 uname = utf_new_char((char *) name);
1763 udesc = utf_new_char((char *) sig);
1765 m = class_resolvemethod(c, uname, udesc);
1767 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1768 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1773 return (jmethodID) m;
1777 /* JNI-functions for calling instance methods *********************************/
1779 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1780 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1781 jmethodID methodID, ...) \
1788 o = (java_handle_t *) obj; \
1789 m = (methodinfo *) methodID; \
1791 va_start(ap, methodID); \
1792 ret = _Jv_jni_Call##intern##Method(o, o->vftbl, m, ap); \
1798 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1799 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1800 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1801 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1802 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1803 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1804 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1805 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1808 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1809 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1810 jmethodID methodID, va_list args) \
1816 o = (java_handle_t *) obj; \
1817 m = (methodinfo *) methodID; \
1819 ret = _Jv_jni_Call##intern##Method(o, o->vftbl, m, args); \
1824 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1825 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1826 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1827 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1828 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1829 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1830 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1831 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1834 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1835 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1836 jmethodID methodID, \
1837 const jvalue *args) \
1843 o = (java_handle_t *) obj; \
1844 m = (methodinfo *) methodID; \
1846 ret = _Jv_jni_Call##intern##MethodA(o, o->vftbl, m, args); \
1851 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1852 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1853 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1854 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1855 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1856 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1857 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1858 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1861 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1869 o = (java_handle_t *) obj;
1870 m = (methodinfo *) methodID;
1872 va_start(ap, methodID);
1873 ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, ap);
1876 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1880 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1887 o = (java_handle_t *) obj;
1888 m = (methodinfo *) methodID;
1890 ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, args);
1892 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1896 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1903 o = (java_handle_t *) obj;
1904 m = (methodinfo *) methodID;
1906 ret = _Jv_jni_CallObjectMethodA(o, o->vftbl, m, args);
1908 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1913 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1919 o = (java_handle_t *) obj;
1920 m = (methodinfo *) methodID;
1922 va_start(ap, methodID);
1923 _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
1928 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1934 o = (java_handle_t *) obj;
1935 m = (methodinfo *) methodID;
1937 _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
1941 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1947 o = (java_handle_t *) obj;
1948 m = (methodinfo *) methodID;
1950 _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
1955 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1956 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1957 jclass clazz, jmethodID methodID, \
1966 o = (java_handle_t *) obj; \
1967 c = (classinfo *) clazz; \
1968 m = (methodinfo *) methodID; \
1970 va_start(ap, methodID); \
1971 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1977 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1978 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1979 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1980 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1981 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1982 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1983 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1984 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1987 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1988 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1989 jclass clazz, jmethodID methodID, \
1997 o = (java_handle_t *) obj; \
1998 c = (classinfo *) clazz; \
1999 m = (methodinfo *) methodID; \
2001 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
2006 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
2007 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
2008 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
2009 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
2010 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
2011 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
2012 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
2013 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
2016 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
2017 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
2018 jclass clazz, jmethodID methodID, \
2019 const jvalue *args) \
2021 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
2026 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
2027 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
2028 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
2029 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
2030 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
2031 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
2032 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
2033 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
2035 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2036 jclass clazz, jmethodID methodID,
2045 o = (java_handle_t *) obj;
2046 c = (classinfo *) clazz;
2047 m = (methodinfo *) methodID;
2049 va_start(ap, methodID);
2050 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2053 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2057 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2058 jclass clazz, jmethodID methodID,
2066 o = (java_handle_t *) obj;
2067 c = (classinfo *) clazz;
2068 m = (methodinfo *) methodID;
2070 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2072 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2076 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2077 jclass clazz, jmethodID methodID,
2080 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2082 return _Jv_JNI_NewLocalRef(env, NULL);
2086 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2087 jmethodID methodID, ...)
2094 o = (java_handle_t *) obj;
2095 c = (classinfo *) clazz;
2096 m = (methodinfo *) methodID;
2098 va_start(ap, methodID);
2099 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2104 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2105 jmethodID methodID, va_list args)
2111 o = (java_handle_t *) obj;
2112 c = (classinfo *) clazz;
2113 m = (methodinfo *) methodID;
2115 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2119 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2120 jmethodID methodID, const jvalue * args)
2126 o = (java_handle_t *) obj;
2127 c = (classinfo *) clazz;
2128 m = (methodinfo *) methodID;
2130 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2134 /* Accessing Fields of Objects ************************************************/
2136 /* GetFieldID ******************************************************************
2138 Returns the field ID for an instance (nonstatic) field of a
2139 class. The field is specified by its name and signature. The
2140 Get<type>Field and Set<type>Field families of accessor functions
2141 use field IDs to retrieve object fields.
2143 *******************************************************************************/
2145 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2153 STATISTICS(jniinvokation());
2155 c = (classinfo *) clazz;
2157 /* XXX NPE check? */
2159 uname = utf_new_char((char *) name);
2160 udesc = utf_new_char((char *) sig);
2162 f = class_findfield(c, uname, udesc);
2165 exceptions_throw_nosuchfielderror(c, uname);
2167 return (jfieldID) f;
2171 /* Get<type>Field Routines *****************************************************
2173 This family of accessor routines returns the value of an instance
2174 (nonstatic) field of an object. The field to access is specified by
2175 a field ID obtained by calling GetFieldID().
2177 *******************************************************************************/
2179 #define JNI_GET_FIELD(name, type, intern) \
2180 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2184 STATISTICS(jniinvokation()); \
2186 ret = GET_FIELD(obj, intern, fieldID); \
2188 return (type) ret; \
2191 JNI_GET_FIELD(Boolean, jboolean, s4)
2192 JNI_GET_FIELD(Byte, jbyte, s4)
2193 JNI_GET_FIELD(Char, jchar, s4)
2194 JNI_GET_FIELD(Short, jshort, s4)
2195 JNI_GET_FIELD(Int, jint, s4)
2196 JNI_GET_FIELD(Long, jlong, s8)
2197 JNI_GET_FIELD(Float, jfloat, float)
2198 JNI_GET_FIELD(Double, jdouble, double)
2201 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2205 STATISTICS(jniinvokation());
2207 #warning this needs to be fixed
2208 o = GET_FIELD(obj, java_handle_t*, fieldID);
2210 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2214 /* Set<type>Field Routines *****************************************************
2216 This family of accessor routines sets the value of an instance
2217 (nonstatic) field of an object. The field to access is specified by
2218 a field ID obtained by calling GetFieldID().
2220 *******************************************************************************/
2222 #define JNI_SET_FIELD(name, type, intern) \
2223 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2226 STATISTICS(jniinvokation()); \
2228 SET_FIELD(obj, intern, fieldID, value); \
2231 JNI_SET_FIELD(Boolean, jboolean, s4)
2232 JNI_SET_FIELD(Byte, jbyte, s4)
2233 JNI_SET_FIELD(Char, jchar, s4)
2234 JNI_SET_FIELD(Short, jshort, s4)
2235 JNI_SET_FIELD(Int, jint, s4)
2236 JNI_SET_FIELD(Long, jlong, s8)
2237 JNI_SET_FIELD(Float, jfloat, float)
2238 JNI_SET_FIELD(Double, jdouble, double)
2241 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2244 STATISTICS(jniinvokation());
2246 #warning this needs to be fixed
2247 SET_FIELD(obj, java_handle_t*, fieldID, value);
2251 /* Calling Static Methods *****************************************************/
2253 /* GetStaticMethodID ***********************************************************
2255 Returns the method ID for a static method of a class. The method is
2256 specified by its name and signature.
2258 GetStaticMethodID() causes an uninitialized class to be
2261 *******************************************************************************/
2263 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2271 STATISTICS(jniinvokation());
2273 c = (classinfo *) clazz;
2278 if (!(c->state & CLASS_INITIALIZED))
2279 if (!initialize_class(c))
2282 /* try to get the static method of the class */
2284 uname = utf_new_char((char *) name);
2285 udesc = utf_new_char((char *) sig);
2287 m = class_resolvemethod(c, uname, udesc);
2289 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2290 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2295 return (jmethodID) m;
2299 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2300 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2301 jmethodID methodID, ...) \
2307 m = (methodinfo *) methodID; \
2309 va_start(ap, methodID); \
2310 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2316 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2317 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2318 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2319 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2320 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2321 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2322 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2323 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2326 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2327 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2328 jmethodID methodID, va_list args) \
2333 m = (methodinfo *) methodID; \
2335 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2340 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2341 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2342 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2343 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2344 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2345 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2346 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2347 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2350 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2351 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2352 jmethodID methodID, const jvalue *args) \
2357 m = (methodinfo *) methodID; \
2359 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2364 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2365 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2366 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2367 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2368 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2369 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2370 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2371 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2374 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2375 jmethodID methodID, ...)
2381 m = (methodinfo *) methodID;
2383 va_start(ap, methodID);
2384 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2387 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2391 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2392 jmethodID methodID, va_list args)
2397 m = (methodinfo *) methodID;
2399 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2401 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2405 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2406 jmethodID methodID, const jvalue *args)
2411 m = (methodinfo *) methodID;
2413 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2415 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2419 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2420 jmethodID methodID, ...)
2425 m = (methodinfo *) methodID;
2427 va_start(ap, methodID);
2428 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2433 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2434 jmethodID methodID, va_list args)
2438 m = (methodinfo *) methodID;
2440 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2444 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2445 jmethodID methodID, const jvalue * args)
2449 m = (methodinfo *) methodID;
2451 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2455 /* Accessing Static Fields ****************************************************/
2457 /* GetStaticFieldID ************************************************************
2459 Returns the field ID for a static field of a class. The field is
2460 specified by its name and signature. The GetStatic<type>Field and
2461 SetStatic<type>Field families of accessor functions use field IDs
2462 to retrieve static fields.
2464 *******************************************************************************/
2466 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2474 STATISTICS(jniinvokation());
2476 c = (classinfo *) clazz;
2478 uname = utf_new_char((char *) name);
2479 usig = utf_new_char((char *) sig);
2481 f = class_findfield(c, uname, usig);
2484 exceptions_throw_nosuchfielderror(c, uname);
2486 return (jfieldID) f;
2490 /* GetStatic<type>Field ********************************************************
2492 This family of accessor routines returns the value of a static
2495 *******************************************************************************/
2497 #define JNI_GET_STATIC_FIELD(name, type, field) \
2498 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2504 STATISTICS(jniinvokation()); \
2506 c = (classinfo *) clazz; \
2507 f = (fieldinfo *) fieldID; \
2509 if (!(c->state & CLASS_INITIALIZED)) \
2510 if (!initialize_class(c)) \
2513 return f->value->field; \
2516 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2517 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2518 JNI_GET_STATIC_FIELD(Char, jchar, i)
2519 JNI_GET_STATIC_FIELD(Short, jshort, i)
2520 JNI_GET_STATIC_FIELD(Int, jint, i)
2521 JNI_GET_STATIC_FIELD(Long, jlong, l)
2522 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2523 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2526 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2532 STATISTICS(jniinvokation());
2534 c = (classinfo *) clazz;
2535 f = (fieldinfo *) fieldID;
2537 if (!(c->state & CLASS_INITIALIZED))
2538 if (!initialize_class(c))
2541 return _Jv_JNI_NewLocalRef(env, f->value->a);
2545 /* SetStatic<type>Field *******************************************************
2547 This family of accessor routines sets the value of a static field
2550 *******************************************************************************/
2552 #define JNI_SET_STATIC_FIELD(name, type, field) \
2553 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2560 STATISTICS(jniinvokation()); \
2562 c = (classinfo *) clazz; \
2563 f = (fieldinfo *) fieldID; \
2565 if (!(c->state & CLASS_INITIALIZED)) \
2566 if (!initialize_class(c)) \
2569 f->value->field = value; \
2572 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2573 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2574 JNI_SET_STATIC_FIELD(Char, jchar, i)
2575 JNI_SET_STATIC_FIELD(Short, jshort, i)
2576 JNI_SET_STATIC_FIELD(Int, jint, i)
2577 JNI_SET_STATIC_FIELD(Long, jlong, l)
2578 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2579 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2582 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2588 STATISTICS(jniinvokation());
2590 c = (classinfo *) clazz;
2591 f = (fieldinfo *) fieldID;
2593 if (!(c->state & CLASS_INITIALIZED))
2594 if (!initialize_class(c))
2597 f->value->a = value;
2601 /* String Operations **********************************************************/
2603 /* NewString *******************************************************************
2605 Create new java.lang.String object from an array of Unicode
2608 *******************************************************************************/
2610 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2612 java_lang_String *s;
2616 STATISTICS(jniinvokation());
2618 s = (java_lang_String *) builtin_new(class_java_lang_String);
2619 a = builtin_newarray_char(len);
2621 /* javastring or characterarray could not be created */
2622 if ((a == NULL) || (s == NULL))
2626 for (i = 0; i < len; i++)
2627 a->data[i] = buf[i];
2629 LLNI_field_set_ref(s, value , a);
2630 LLNI_field_set_val(s, offset, 0);
2631 LLNI_field_set_val(s, count , len);
2633 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2637 static jchar emptyStringJ[]={0,0};
2639 /* GetStringLength *************************************************************
2641 Returns the length (the count of Unicode characters) of a Java
2644 *******************************************************************************/
2646 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2648 java_lang_String *s;
2651 TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
2653 s = (java_lang_String *) str;
2655 LLNI_field_get_val(s, count, len);
2661 /******************** convertes javastring to u2-array ****************************/
2663 u2 *javastring_tou2(jstring so)
2665 java_lang_String *s;
2670 STATISTICS(jniinvokation());
2672 s = (java_lang_String *) so;
2677 LLNI_field_get_ref(s, value, a);
2682 /* allocate memory */
2684 stringbuffer = MNEW(u2, LLNI_field_direct(s, count) + 1);
2688 for (i = 0; i < LLNI_field_direct(s, count); i++)
2689 stringbuffer[i] = a->data[LLNI_field_direct(s, offset) + i];
2691 /* terminate string */
2693 stringbuffer[i] = '\0';
2695 return stringbuffer;
2699 /* GetStringChars **************************************************************
2701 Returns a pointer to the array of Unicode characters of the
2702 string. This pointer is valid until ReleaseStringChars() is called.
2704 *******************************************************************************/
2706 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2710 STATISTICS(jniinvokation());
2712 jc = javastring_tou2(str);
2724 return emptyStringJ;
2728 /* ReleaseStringChars **********************************************************
2730 Informs the VM that the native code no longer needs access to
2731 chars. The chars argument is a pointer obtained from string using
2734 *******************************************************************************/
2736 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2738 java_lang_String *s;
2740 STATISTICS(jniinvokation());
2742 if (chars == emptyStringJ)
2745 s = (java_lang_String *) str;
2747 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2751 /* NewStringUTF ****************************************************************
2753 Constructs a new java.lang.String object from an array of UTF-8
2756 *******************************************************************************/
2758 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2760 java_lang_String *s;
2762 TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
2764 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2766 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2770 /****************** returns the utf8 length in bytes of a string *******************/
2772 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2774 java_lang_String *s;
2777 TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
2779 s = (java_lang_String *) string;
2781 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2787 /* GetStringUTFChars ***********************************************************
2789 Returns a pointer to an array of UTF-8 characters of the
2790 string. This array is valid until it is released by
2791 ReleaseStringUTFChars().
2793 *******************************************************************************/
2795 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2800 STATISTICS(jniinvokation());
2808 u = javastring_toutf((java_handle_t *) string, false);
2817 /* ReleaseStringUTFChars *******************************************************
2819 Informs the VM that the native code no longer needs access to
2820 utf. The utf argument is a pointer derived from string using
2821 GetStringUTFChars().
2823 *******************************************************************************/
2825 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2827 STATISTICS(jniinvokation());
2829 /* XXX we don't release utf chars right now, perhaps that should be done
2830 later. Since there is always one reference the garbage collector will
2835 /* Array Operations ***********************************************************/
2837 /* GetArrayLength **************************************************************
2839 Returns the number of elements in the array.
2841 *******************************************************************************/
2843 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2845 java_arrayheader *a;
2847 STATISTICS(jniinvokation());
2849 a = (java_arrayheader *) array;
2855 /* NewObjectArray **************************************************************
2857 Constructs a new array holding objects in class elementClass. All
2858 elements are initially set to initialElement.
2860 *******************************************************************************/
2862 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2863 jclass elementClass, jobject initialElement)
2867 java_objectarray *oa;
2870 STATISTICS(jniinvokation());
2872 c = (classinfo *) elementClass;
2873 o = (java_handle_t *) initialElement;
2876 exceptions_throw_negativearraysizeexception();
2880 oa = builtin_anewarray(length, c);
2885 /* set all elements to initialElement */
2887 for (i = 0; i < length; i++)
2890 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2894 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2897 java_objectarray *oa;
2900 STATISTICS(jniinvokation());
2902 oa = (java_objectarray *) array;
2904 if (index >= oa->header.size) {
2905 exceptions_throw_arrayindexoutofboundsexception();
2909 o = oa->data[index];
2911 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2915 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2916 jsize index, jobject val)
2918 java_objectarray *oa;
2921 STATISTICS(jniinvokation());
2923 oa = (java_objectarray *) array;
2924 o = (java_handle_t *) val;
2926 if (index >= oa->header.size) {
2927 exceptions_throw_arrayindexoutofboundsexception();
2931 /* check if the class of value is a subclass of the element class
2934 if (!builtin_canstore(oa, o))
2937 oa->data[index] = o;
2941 #define JNI_NEW_ARRAY(name, type, intern) \
2942 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2944 java_##intern##array *a; \
2946 STATISTICS(jniinvokation()); \
2949 exceptions_throw_negativearraysizeexception(); \
2953 a = builtin_newarray_##intern(len); \
2955 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2958 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2959 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2960 JNI_NEW_ARRAY(Char, jcharArray, char)
2961 JNI_NEW_ARRAY(Short, jshortArray, byte)
2962 JNI_NEW_ARRAY(Int, jintArray, int)
2963 JNI_NEW_ARRAY(Long, jlongArray, long)
2964 JNI_NEW_ARRAY(Float, jfloatArray, float)
2965 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2968 /* Get<PrimitiveType>ArrayElements *********************************************
2970 A family of functions that returns the body of the primitive array.
2972 *******************************************************************************/
2974 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2975 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2978 java_##intern##array *a; \
2980 STATISTICS(jniinvokation()); \
2982 a = (java_##intern##array *) array; \
2985 *isCopy = JNI_FALSE; \
2990 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2991 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2992 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2993 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2994 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2995 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2996 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2997 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
3000 /* Release<PrimitiveType>ArrayElements *****************************************
3002 A family of functions that informs the VM that the native code no
3003 longer needs access to elems. The elems argument is a pointer
3004 derived from array using the corresponding
3005 Get<PrimitiveType>ArrayElements() function. If necessary, this
3006 function copies back all changes made to elems to the original
3009 *******************************************************************************/
3011 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
3012 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
3013 type *elems, jint mode) \
3015 java_##intern##array *a; \
3017 STATISTICS(jniinvokation()); \
3019 a = (java_##intern##array *) array; \
3021 if (elems != a->data) { \
3024 MCOPY(a->data, elems, intern2, a->header.size); \
3027 MCOPY(a->data, elems, intern2, a->header.size); \
3028 /* XXX TWISTI how should it be freed? */ \
3031 /* XXX TWISTI how should it be freed? */ \
3037 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3038 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3039 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3040 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3041 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3042 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3043 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3044 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3047 /* Get<PrimitiveType>ArrayRegion **********************************************
3049 A family of functions that copies a region of a primitive array
3052 *******************************************************************************/
3054 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3055 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3056 jsize start, jsize len, type *buf) \
3058 java_##intern##array *a; \
3060 STATISTICS(jniinvokation()); \
3062 a = (java_##intern##array *) array; \
3064 if ((start < 0) || (len < 0) || (start + len > a->header.size)) \
3065 exceptions_throw_arrayindexoutofboundsexception(); \
3067 MCOPY(buf, &a->data[start], intern2, len); \
3070 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3071 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3072 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3073 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3074 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3075 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3076 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3077 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3080 /* Set<PrimitiveType>ArrayRegion **********************************************
3082 A family of functions that copies back a region of a primitive
3083 array from a buffer.
3085 *******************************************************************************/
3087 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3088 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3089 jsize start, jsize len, const type *buf) \
3091 java_##intern##array *a; \
3093 STATISTICS(jniinvokation()); \
3095 a = (java_##intern##array *) array; \
3097 if ((start < 0) || (len < 0) || (start + len > a->header.size)) \
3098 exceptions_throw_arrayindexoutofboundsexception(); \
3100 MCOPY(&a->data[start], buf, intern2, len); \
3103 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3104 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3105 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3106 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3107 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3108 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3109 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3110 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3113 /* Registering Native Methods *************************************************/
3115 /* RegisterNatives *************************************************************
3117 Registers native methods with the class specified by the clazz
3118 argument. The methods parameter specifies an array of
3119 JNINativeMethod structures that contain the names, signatures, and
3120 function pointers of the native methods. The nMethods parameter
3121 specifies the number of native methods in the array.
3123 *******************************************************************************/
3125 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3126 const JNINativeMethod *methods, jint nMethods)
3130 STATISTICS(jniinvokation());
3132 c = (classinfo *) clazz;
3134 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3135 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3138 native_method_register(c->name, methods, nMethods);
3144 /* UnregisterNatives ***********************************************************
3146 Unregisters native methods of a class. The class goes back to the
3147 state before it was linked or registered with its native method
3150 This function should not be used in normal native code. Instead, it
3151 provides special programs a way to reload and relink native
3154 *******************************************************************************/
3156 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3158 STATISTICS(jniinvokation());
3160 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3162 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3168 /* Monitor Operations *********************************************************/
3170 /* MonitorEnter ****************************************************************
3172 Enters the monitor associated with the underlying Java object
3175 *******************************************************************************/
3177 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3179 STATISTICS(jniinvokation());
3182 exceptions_throw_nullpointerexception();
3186 LOCK_MONITOR_ENTER(obj);
3192 /* MonitorExit *****************************************************************
3194 The current thread must be the owner of the monitor associated with
3195 the underlying Java object referred to by obj. The thread
3196 decrements the counter indicating the number of times it has
3197 entered this monitor. If the value of the counter becomes zero, the
3198 current thread releases the monitor.
3200 *******************************************************************************/
3202 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3204 STATISTICS(jniinvokation());
3207 exceptions_throw_nullpointerexception();
3211 LOCK_MONITOR_EXIT(obj);
3217 /* JavaVM Interface ***********************************************************/
3219 /* GetJavaVM *******************************************************************
3221 Returns the Java VM interface (used in the Invocation API)
3222 associated with the current thread. The result is placed at the
3223 location pointed to by the second argument, vm.
3225 *******************************************************************************/
3227 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3229 STATISTICS(jniinvokation());
3231 *vm = (JavaVM *) _Jv_jvm;
3237 /* GetStringRegion *************************************************************
3239 Copies len number of Unicode characters beginning at offset start
3240 to the given buffer buf.
3242 Throws StringIndexOutOfBoundsException on index overflow.
3244 *******************************************************************************/
3246 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3249 java_lang_String *s;
3252 STATISTICS(jniinvokation());
3254 s = (java_lang_String *) str;
3255 LLNI_field_get_ref(s, value, ca);
3257 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3258 (start + len > LLNI_field_direct(s, count))) {
3259 exceptions_throw_stringindexoutofboundsexception();
3263 MCOPY(buf, &ca->data[start], u2, len);
3267 /* GetStringUTFRegion **********************************************************
3269 Translates len number of Unicode characters beginning at offset
3270 start into UTF-8 format and place the result in the given buffer
3273 Throws StringIndexOutOfBoundsException on index overflow.
3275 *******************************************************************************/
3277 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3278 jsize len, char *buf)
3280 java_lang_String *s;
3284 TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
3286 s = (java_lang_String *) str;
3287 LLNI_field_get_ref(s, value, ca);
3289 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3290 (start + len > LLNI_field_direct(s, count))) {
3291 exceptions_throw_stringindexoutofboundsexception();
3295 for (i = 0; i < len; i++)
3296 buf[i] = ca->data[LLNI_field_direct(s, offset) + start + i];
3302 /* GetPrimitiveArrayCritical ***************************************************
3304 Obtain a direct pointer to array elements.
3306 *******************************************************************************/
3308 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3314 ba = (java_bytearray *) array;
3316 /* do the same as Kaffe does */
3318 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3324 /* ReleasePrimitiveArrayCritical ***********************************************
3326 No specific documentation.
3328 *******************************************************************************/
3330 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3331 void *carray, jint mode)
3333 STATISTICS(jniinvokation());
3335 /* do the same as Kaffe does */
3337 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3342 /* GetStringCritical ***********************************************************
3344 The semantics of these two functions are similar to the existing
3345 Get/ReleaseStringChars functions.
3347 *******************************************************************************/
3349 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3352 STATISTICS(jniinvokation());
3354 return _Jv_JNI_GetStringChars(env, string, isCopy);
3358 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3359 const jchar *cstring)
3361 STATISTICS(jniinvokation());
3363 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3367 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3369 STATISTICS(jniinvokation());
3371 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
3377 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3379 STATISTICS(jniinvokation());
3381 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
3385 /* NewGlobalRef ****************************************************************
3387 Creates a new global reference to the object referred to by the obj
3390 *******************************************************************************/
3392 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3394 hashtable_global_ref_entry *gre;
3395 u4 key; /* hashkey */
3396 u4 slot; /* slot in hashtable */
3399 STATISTICS(jniinvokation());
3401 o = (java_handle_t *) obj;
3403 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3405 /* normally addresses are aligned to 4, 8 or 16 bytes */
3407 key = ((u4) (ptrint) obj) >> 4; /* align to 16-byte boundaries */
3408 slot = key & (hashtable_global_ref->size - 1);
3409 gre = hashtable_global_ref->ptr[slot];
3411 /* search external hash chain for the entry */
3415 /* global object found, increment the reference */
3419 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3424 gre = gre->hashlink; /* next element in external chain */
3427 /* global ref not found, create a new one */
3429 gre = NEW(hashtable_global_ref_entry);
3434 /* insert entry into hashtable */
3436 gre->hashlink = hashtable_global_ref->ptr[slot];
3438 hashtable_global_ref->ptr[slot] = gre;
3440 /* update number of hashtable-entries */
3442 hashtable_global_ref->entries++;
3444 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3450 /* DeleteGlobalRef *************************************************************
3452 Deletes the global reference pointed to by globalRef.
3454 *******************************************************************************/
3456 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3458 hashtable_global_ref_entry *gre;
3459 hashtable_global_ref_entry *prevgre;
3460 u4 key; /* hashkey */
3461 u4 slot; /* slot in hashtable */
3464 STATISTICS(jniinvokation());
3466 o = (java_handle_t *) globalRef;
3468 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3470 /* normally addresses are aligned to 4, 8 or 16 bytes */
3472 key = ((u4) (ptrint) globalRef) >> 4; /* align to 16-byte boundaries */
3473 slot = key & (hashtable_global_ref->size - 1);
3474 gre = hashtable_global_ref->ptr[slot];
3476 /* initialize prevgre */
3480 /* search external hash chain for the entry */
3484 /* global object found, decrement the reference count */
3488 /* if reference count is 0, remove the entry */
3490 if (gre->refs == 0) {
3491 /* special handling if it's the first in the chain */
3493 if (prevgre == NULL)
3494 hashtable_global_ref->ptr[slot] = gre->hashlink;
3496 prevgre->hashlink = gre->hashlink;
3498 FREE(gre, hashtable_global_ref_entry);
3501 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3506 prevgre = gre; /* save current pointer for removal */
3507 gre = gre->hashlink; /* next element in external chain */
3510 log_println("JNI-DeleteGlobalRef: global reference not found");
3512 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3516 /* ExceptionCheck **************************************************************
3518 Returns JNI_TRUE when there is a pending exception; otherwise,
3521 *******************************************************************************/
3523 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3527 STATISTICS(jniinvokation());
3529 o = exceptions_get_exception();
3531 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3535 /* New JNI 1.4 functions ******************************************************/
3537 /* NewDirectByteBuffer *********************************************************
3539 Allocates and returns a direct java.nio.ByteBuffer referring to the
3540 block of memory starting at the memory address address and
3541 extending capacity bytes.
3543 *******************************************************************************/
3545 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3547 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3548 java_handle_t *nbuf;
3550 # if SIZEOF_VOID_P == 8
3551 gnu_classpath_Pointer64 *paddress;
3553 gnu_classpath_Pointer32 *paddress;
3556 STATISTICS(jniinvokation());
3558 /* alocate a gnu.classpath.Pointer{32,64} object */
3560 # if SIZEOF_VOID_P == 8
3561 if (!(paddress = (gnu_classpath_Pointer64 *)
3562 builtin_new(class_gnu_classpath_Pointer64)))
3564 if (!(paddress = (gnu_classpath_Pointer32 *)
3565 builtin_new(class_gnu_classpath_Pointer32)))
3569 /* fill gnu.classpath.Pointer{32,64} with address */
3571 LLNI_field_set_val(paddress, data, (ptrint) address);
3573 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3575 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3576 (jmethodID) dbbirw_init, NULL, paddress,
3577 (jint) capacity, (jint) capacity, (jint) 0);
3579 /* add local reference and return the value */
3581 return _Jv_JNI_NewLocalRef(env, nbuf);
3583 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3585 /* keep compiler happy */
3592 /* GetDirectBufferAddress ******************************************************
3594 Fetches and returns the starting address of the memory region
3595 referenced by the given direct java.nio.Buffer.
3597 *******************************************************************************/
3599 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3601 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3602 java_nio_DirectByteBufferImpl *nbuf;
3603 # if SIZEOF_VOID_P == 8
3604 gnu_classpath_Pointer64 *paddress;
3606 gnu_classpath_Pointer32 *paddress;
3610 STATISTICS(jniinvokation());
3612 if (!builtin_instanceof(buf, class_java_nio_Buffer))
3615 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3617 # if SIZEOF_VOID_P == 8
3618 LLNI_field_get_ref(nbuf, address, paddress);
3619 /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
3621 LLNI_field_get_ref(nbuf, address, paddress);
3622 /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
3625 if (paddress == NULL)
3628 LLNI_field_get_val(paddress, data, address);
3629 /* this was the cast to avaoid warning: (void *) paddress->data */
3633 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3635 /* keep compiler happy */
3642 /* GetDirectBufferCapacity *****************************************************
3644 Fetches and returns the capacity in bytes of the memory region
3645 referenced by the given direct java.nio.Buffer.
3647 *******************************************************************************/
3649 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3651 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3653 java_nio_Buffer *nbuf;
3656 STATISTICS(jniinvokation());
3658 o = (java_handle_t *) buf;
3660 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3663 nbuf = (java_nio_Buffer *) o;
3665 LLNI_field_get_val(nbuf, cap, capacity);
3669 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3671 /* keep compiler happy */
3678 /* DestroyJavaVM ***************************************************************
3680 Unloads a Java VM and reclaims its resources. Only the main thread
3681 can unload the VM. The system waits until the main thread is only
3682 remaining user thread before it destroys the VM.
3684 *******************************************************************************/
3686 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3690 STATISTICS(jniinvokation());
3692 status = vm_destroy(vm);
3698 /* AttachCurrentThread *********************************************************
3700 Attaches the current thread to a Java VM. Returns a JNI interface
3701 pointer in the JNIEnv argument.
3703 Trying to attach a thread that is already attached is a no-op.
3705 A native thread cannot be attached simultaneously to two Java VMs.
3707 When a thread is attached to the VM, the context class loader is
3708 the bootstrap loader.
3710 *******************************************************************************/
3712 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3714 JavaVMAttachArgs *vm_aargs;
3716 #if defined(ENABLE_THREADS)
3717 if (threads_get_current_threadobject() == NULL) {
3718 vm_aargs = (JavaVMAttachArgs *) thr_args;
3720 if (vm_aargs != NULL) {
3721 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3722 (vm_aargs->version != JNI_VERSION_1_4))
3723 return JNI_EVERSION;
3726 if (!threads_attach_current_thread(vm_aargs, false))
3729 if (!localref_table_init())
3740 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3742 STATISTICS(jniinvokation());
3744 return jni_attach_current_thread(p_env, thr_args, false);
3748 /* DetachCurrentThread *********************************************************
3750 Detaches the current thread from a Java VM. All Java monitors held
3751 by this thread are released. All Java threads waiting for this
3752 thread to die are notified.
3754 In JDK 1.1, the main thread cannot be detached from the VM. It must
3755 call DestroyJavaVM to unload the entire VM.
3757 In the JDK, the main thread can be detached from the VM.
3759 The main thread, which is the thread that created the Java VM,
3760 cannot be detached from the VM. Instead, the main thread must call
3761 JNI_DestroyJavaVM() to unload the entire VM.
3763 *******************************************************************************/
3765 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3767 #if defined(ENABLE_THREADS)
3768 threadobject *thread;
3770 STATISTICS(jniinvokation());
3772 thread = threads_get_current_threadobject();
3777 if (!threads_detach_thread(thread))
3785 /* GetEnv **********************************************************************
3787 If the current thread is not attached to the VM, sets *env to NULL,
3788 and returns JNI_EDETACHED. If the specified version is not
3789 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3790 sets *env to the appropriate interface, and returns JNI_OK.
3792 *******************************************************************************/
3794 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3796 STATISTICS(jniinvokation());
3798 #if defined(ENABLE_THREADS)
3799 if (threads_get_current_threadobject() == NULL) {
3802 return JNI_EDETACHED;
3806 /* check the JNI version */
3809 case JNI_VERSION_1_1:
3810 case JNI_VERSION_1_2:
3811 case JNI_VERSION_1_4:
3819 #if defined(ENABLE_JVMTI)
3820 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3821 == JVMTI_VERSION_INTERFACE_JVMTI) {
3823 *env = (void *) jvmti_new_environment();
3832 return JNI_EVERSION;
3836 /* AttachCurrentThreadAsDaemon *************************************************
3838 Same semantics as AttachCurrentThread, but the newly-created
3839 java.lang.Thread instance is a daemon.
3841 If the thread has already been attached via either
3842 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3843 simply sets the value pointed to by penv to the JNIEnv of the
3844 current thread. In this case neither AttachCurrentThread nor this
3845 routine have any effect on the daemon status of the thread.
3847 *******************************************************************************/
3849 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3851 STATISTICS(jniinvokation());
3853 return jni_attach_current_thread(penv, args, true);
3857 /* JNI invocation table *******************************************************/
3859 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3864 _Jv_JNI_DestroyJavaVM,
3865 _Jv_JNI_AttachCurrentThread,
3866 _Jv_JNI_DetachCurrentThread,
3868 _Jv_JNI_AttachCurrentThreadAsDaemon
3872 /* JNI function table *********************************************************/
3874 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3881 _Jv_JNI_DefineClass,
3883 _Jv_JNI_FromReflectedMethod,
3884 _Jv_JNI_FromReflectedField,
3885 _Jv_JNI_ToReflectedMethod,
3886 _Jv_JNI_GetSuperclass,
3887 _Jv_JNI_IsAssignableFrom,
3888 _Jv_JNI_ToReflectedField,
3892 _Jv_JNI_ExceptionOccurred,
3893 _Jv_JNI_ExceptionDescribe,
3894 _Jv_JNI_ExceptionClear,
3896 _Jv_JNI_PushLocalFrame,
3897 _Jv_JNI_PopLocalFrame,
3899 _Jv_JNI_NewGlobalRef,
3900 _Jv_JNI_DeleteGlobalRef,
3901 _Jv_JNI_DeleteLocalRef,
3902 _Jv_JNI_IsSameObject,
3903 _Jv_JNI_NewLocalRef,
3904 _Jv_JNI_EnsureLocalCapacity,
3906 _Jv_JNI_AllocObject,
3911 _Jv_JNI_GetObjectClass,
3912 _Jv_JNI_IsInstanceOf,
3914 _Jv_JNI_GetMethodID,
3916 _Jv_JNI_CallObjectMethod,
3917 _Jv_JNI_CallObjectMethodV,
3918 _Jv_JNI_CallObjectMethodA,
3919 _Jv_JNI_CallBooleanMethod,
3920 _Jv_JNI_CallBooleanMethodV,
3921 _Jv_JNI_CallBooleanMethodA,
3922 _Jv_JNI_CallByteMethod,
3923 _Jv_JNI_CallByteMethodV,
3924 _Jv_JNI_CallByteMethodA,
3925 _Jv_JNI_CallCharMethod,
3926 _Jv_JNI_CallCharMethodV,
3927 _Jv_JNI_CallCharMethodA,
3928 _Jv_JNI_CallShortMethod,
3929 _Jv_JNI_CallShortMethodV,
3930 _Jv_JNI_CallShortMethodA,
3931 _Jv_JNI_CallIntMethod,
3932 _Jv_JNI_CallIntMethodV,
3933 _Jv_JNI_CallIntMethodA,
3934 _Jv_JNI_CallLongMethod,
3935 _Jv_JNI_CallLongMethodV,
3936 _Jv_JNI_CallLongMethodA,
3937 _Jv_JNI_CallFloatMethod,
3938 _Jv_JNI_CallFloatMethodV,
3939 _Jv_JNI_CallFloatMethodA,
3940 _Jv_JNI_CallDoubleMethod,
3941 _Jv_JNI_CallDoubleMethodV,
3942 _Jv_JNI_CallDoubleMethodA,
3943 _Jv_JNI_CallVoidMethod,
3944 _Jv_JNI_CallVoidMethodV,
3945 _Jv_JNI_CallVoidMethodA,
3947 _Jv_JNI_CallNonvirtualObjectMethod,
3948 _Jv_JNI_CallNonvirtualObjectMethodV,
3949 _Jv_JNI_CallNonvirtualObjectMethodA,
3950 _Jv_JNI_CallNonvirtualBooleanMethod,
3951 _Jv_JNI_CallNonvirtualBooleanMethodV,
3952 _Jv_JNI_CallNonvirtualBooleanMethodA,
3953 _Jv_JNI_CallNonvirtualByteMethod,
3954 _Jv_JNI_CallNonvirtualByteMethodV,
3955 _Jv_JNI_CallNonvirtualByteMethodA,
3956 _Jv_JNI_CallNonvirtualCharMethod,
3957 _Jv_JNI_CallNonvirtualCharMethodV,
3958 _Jv_JNI_CallNonvirtualCharMethodA,
3959 _Jv_JNI_CallNonvirtualShortMethod,
3960 _Jv_JNI_CallNonvirtualShortMethodV,
3961 _Jv_JNI_CallNonvirtualShortMethodA,
3962 _Jv_JNI_CallNonvirtualIntMethod,
3963 _Jv_JNI_CallNonvirtualIntMethodV,
3964 _Jv_JNI_CallNonvirtualIntMethodA,
3965 _Jv_JNI_CallNonvirtualLongMethod,
3966 _Jv_JNI_CallNonvirtualLongMethodV,
3967 _Jv_JNI_CallNonvirtualLongMethodA,
3968 _Jv_JNI_CallNonvirtualFloatMethod,
3969 _Jv_JNI_CallNonvirtualFloatMethodV,
3970 _Jv_JNI_CallNonvirtualFloatMethodA,
3971 _Jv_JNI_CallNonvirtualDoubleMethod,
3972 _Jv_JNI_CallNonvirtualDoubleMethodV,
3973 _Jv_JNI_CallNonvirtualDoubleMethodA,
3974 _Jv_JNI_CallNonvirtualVoidMethod,
3975 _Jv_JNI_CallNonvirtualVoidMethodV,
3976 _Jv_JNI_CallNonvirtualVoidMethodA,
3980 _Jv_JNI_GetObjectField,
3981 _Jv_JNI_GetBooleanField,
3982 _Jv_JNI_GetByteField,
3983 _Jv_JNI_GetCharField,
3984 _Jv_JNI_GetShortField,
3985 _Jv_JNI_GetIntField,
3986 _Jv_JNI_GetLongField,
3987 _Jv_JNI_GetFloatField,
3988 _Jv_JNI_GetDoubleField,
3989 _Jv_JNI_SetObjectField,
3990 _Jv_JNI_SetBooleanField,
3991 _Jv_JNI_SetByteField,
3992 _Jv_JNI_SetCharField,
3993 _Jv_JNI_SetShortField,
3994 _Jv_JNI_SetIntField,
3995 _Jv_JNI_SetLongField,
3996 _Jv_JNI_SetFloatField,
3997 _Jv_JNI_SetDoubleField,
3999 _Jv_JNI_GetStaticMethodID,
4001 _Jv_JNI_CallStaticObjectMethod,
4002 _Jv_JNI_CallStaticObjectMethodV,
4003 _Jv_JNI_CallStaticObjectMethodA,
4004 _Jv_JNI_CallStaticBooleanMethod,
4005 _Jv_JNI_CallStaticBooleanMethodV,
4006 _Jv_JNI_CallStaticBooleanMethodA,
4007 _Jv_JNI_CallStaticByteMethod,
4008 _Jv_JNI_CallStaticByteMethodV,
4009 _Jv_JNI_CallStaticByteMethodA,
4010 _Jv_JNI_CallStaticCharMethod,
4011 _Jv_JNI_CallStaticCharMethodV,
4012 _Jv_JNI_CallStaticCharMethodA,
4013 _Jv_JNI_CallStaticShortMethod,
4014 _Jv_JNI_CallStaticShortMethodV,
4015 _Jv_JNI_CallStaticShortMethodA,
4016 _Jv_JNI_CallStaticIntMethod,
4017 _Jv_JNI_CallStaticIntMethodV,
4018 _Jv_JNI_CallStaticIntMethodA,
4019 _Jv_JNI_CallStaticLongMethod,
4020 _Jv_JNI_CallStaticLongMethodV,
4021 _Jv_JNI_CallStaticLongMethodA,
4022 _Jv_JNI_CallStaticFloatMethod,
4023 _Jv_JNI_CallStaticFloatMethodV,
4024 _Jv_JNI_CallStaticFloatMethodA,
4025 _Jv_JNI_CallStaticDoubleMethod,
4026 _Jv_JNI_CallStaticDoubleMethodV,
4027 _Jv_JNI_CallStaticDoubleMethodA,
4028 _Jv_JNI_CallStaticVoidMethod,
4029 _Jv_JNI_CallStaticVoidMethodV,
4030 _Jv_JNI_CallStaticVoidMethodA,
4032 _Jv_JNI_GetStaticFieldID,
4034 _Jv_JNI_GetStaticObjectField,
4035 _Jv_JNI_GetStaticBooleanField,
4036 _Jv_JNI_GetStaticByteField,
4037 _Jv_JNI_GetStaticCharField,
4038 _Jv_JNI_GetStaticShortField,
4039 _Jv_JNI_GetStaticIntField,
4040 _Jv_JNI_GetStaticLongField,
4041 _Jv_JNI_GetStaticFloatField,
4042 _Jv_JNI_GetStaticDoubleField,
4043 _Jv_JNI_SetStaticObjectField,
4044 _Jv_JNI_SetStaticBooleanField,
4045 _Jv_JNI_SetStaticByteField,
4046 _Jv_JNI_SetStaticCharField,
4047 _Jv_JNI_SetStaticShortField,
4048 _Jv_JNI_SetStaticIntField,
4049 _Jv_JNI_SetStaticLongField,
4050 _Jv_JNI_SetStaticFloatField,
4051 _Jv_JNI_SetStaticDoubleField,
4054 _Jv_JNI_GetStringLength,
4055 _Jv_JNI_GetStringChars,
4056 _Jv_JNI_ReleaseStringChars,
4058 _Jv_JNI_NewStringUTF,
4059 _Jv_JNI_GetStringUTFLength,
4060 _Jv_JNI_GetStringUTFChars,
4061 _Jv_JNI_ReleaseStringUTFChars,
4063 _Jv_JNI_GetArrayLength,
4065 _Jv_JNI_NewObjectArray,
4066 _Jv_JNI_GetObjectArrayElement,
4067 _Jv_JNI_SetObjectArrayElement,
4069 _Jv_JNI_NewBooleanArray,
4070 _Jv_JNI_NewByteArray,
4071 _Jv_JNI_NewCharArray,
4072 _Jv_JNI_NewShortArray,
4073 _Jv_JNI_NewIntArray,
4074 _Jv_JNI_NewLongArray,
4075 _Jv_JNI_NewFloatArray,
4076 _Jv_JNI_NewDoubleArray,
4078 _Jv_JNI_GetBooleanArrayElements,
4079 _Jv_JNI_GetByteArrayElements,
4080 _Jv_JNI_GetCharArrayElements,
4081 _Jv_JNI_GetShortArrayElements,
4082 _Jv_JNI_GetIntArrayElements,
4083 _Jv_JNI_GetLongArrayElements,
4084 _Jv_JNI_GetFloatArrayElements,
4085 _Jv_JNI_GetDoubleArrayElements,
4087 _Jv_JNI_ReleaseBooleanArrayElements,
4088 _Jv_JNI_ReleaseByteArrayElements,
4089 _Jv_JNI_ReleaseCharArrayElements,
4090 _Jv_JNI_ReleaseShortArrayElements,
4091 _Jv_JNI_ReleaseIntArrayElements,
4092 _Jv_JNI_ReleaseLongArrayElements,
4093 _Jv_JNI_ReleaseFloatArrayElements,
4094 _Jv_JNI_ReleaseDoubleArrayElements,
4096 _Jv_JNI_GetBooleanArrayRegion,
4097 _Jv_JNI_GetByteArrayRegion,
4098 _Jv_JNI_GetCharArrayRegion,
4099 _Jv_JNI_GetShortArrayRegion,
4100 _Jv_JNI_GetIntArrayRegion,
4101 _Jv_JNI_GetLongArrayRegion,
4102 _Jv_JNI_GetFloatArrayRegion,
4103 _Jv_JNI_GetDoubleArrayRegion,
4104 _Jv_JNI_SetBooleanArrayRegion,
4105 _Jv_JNI_SetByteArrayRegion,
4106 _Jv_JNI_SetCharArrayRegion,
4107 _Jv_JNI_SetShortArrayRegion,
4108 _Jv_JNI_SetIntArrayRegion,
4109 _Jv_JNI_SetLongArrayRegion,
4110 _Jv_JNI_SetFloatArrayRegion,
4111 _Jv_JNI_SetDoubleArrayRegion,
4113 _Jv_JNI_RegisterNatives,
4114 _Jv_JNI_UnregisterNatives,
4116 _Jv_JNI_MonitorEnter,
4117 _Jv_JNI_MonitorExit,
4121 /* new JNI 1.2 functions */
4123 _Jv_JNI_GetStringRegion,
4124 _Jv_JNI_GetStringUTFRegion,
4126 _Jv_JNI_GetPrimitiveArrayCritical,
4127 _Jv_JNI_ReleasePrimitiveArrayCritical,
4129 _Jv_JNI_GetStringCritical,
4130 _Jv_JNI_ReleaseStringCritical,
4132 _Jv_JNI_NewWeakGlobalRef,
4133 _Jv_JNI_DeleteWeakGlobalRef,
4135 _Jv_JNI_ExceptionCheck,
4137 /* new JNI 1.4 functions */
4139 _Jv_JNI_NewDirectByteBuffer,
4140 _Jv_JNI_GetDirectBufferAddress,
4141 _Jv_JNI_GetDirectBufferCapacity
4145 /* Invocation API Functions ***************************************************/
4147 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4149 Returns a default configuration for the Java VM.
4151 *******************************************************************************/
4153 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4155 JavaVMInitArgs *_vm_args;
4157 _vm_args = (JavaVMInitArgs *) vm_args;
4159 /* GNU classpath currently supports JNI 1.2 */
4161 switch (_vm_args->version) {
4162 case JNI_VERSION_1_1:
4163 _vm_args->version = JNI_VERSION_1_1;
4166 case JNI_VERSION_1_2:
4167 case JNI_VERSION_1_4:
4168 _vm_args->ignoreUnrecognized = JNI_FALSE;
4169 _vm_args->options = NULL;
4170 _vm_args->nOptions = 0;
4181 /* JNI_GetCreatedJavaVMs *******************************************************
4183 Returns all Java VMs that have been created. Pointers to VMs are written in
4184 the buffer vmBuf in the order they are created. At most bufLen number of
4185 entries will be written. The total number of created VMs is returned in
4188 *******************************************************************************/
4190 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4192 TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
4197 /* We currently only support 1 VM running. */
4199 vmBuf[0] = (JavaVM *) _Jv_jvm;
4206 /* JNI_CreateJavaVM ************************************************************
4208 Loads and initializes a Java VM. The current thread becomes the main thread.
4209 Sets the env argument to the JNI interface pointer of the main thread.
4211 *******************************************************************************/
4213 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4215 TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
4217 /* actually create the JVM */
4219 if (!vm_createjvm(p_vm, p_env, vm_args))
4227 * These are local overrides for various environment variables in Emacs.
4228 * Please do not remove this and leave it at the end of the file, where
4229 * Emacs will automagically detect them.
4230 * ---------------------------------------------------------------------
4233 * indent-tabs-mode: t
4237 * vim:noexpandtab:sw=4:ts=4: