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 8391 2007-08-21 20:34:27Z michi $
38 #include "mm/gc-common.h"
39 #include "mm/memory.h"
41 #include "native/jni.h"
42 #include "native/llni.h"
43 #include "native/localref.h"
44 #include "native/native.h"
46 #if defined(ENABLE_JAVASE)
47 # if defined(WITH_CLASSPATH_GNU)
48 # include "native/include/gnu_classpath_Pointer.h"
50 # if SIZEOF_VOID_P == 8
51 # include "native/include/gnu_classpath_Pointer64.h"
53 # include "native/include/gnu_classpath_Pointer32.h"
58 #include "native/include/java_lang_Object.h"
59 #include "native/include/java_lang_Byte.h"
60 #include "native/include/java_lang_Character.h"
61 #include "native/include/java_lang_Short.h"
62 #include "native/include/java_lang_Integer.h"
63 #include "native/include/java_lang_Boolean.h"
64 #include "native/include/java_lang_Long.h"
65 #include "native/include/java_lang_Float.h"
66 #include "native/include/java_lang_Double.h"
67 #include "native/include/java_lang_String.h"
68 #include "native/include/java_lang_Throwable.h"
70 #if defined(ENABLE_JAVASE)
71 # if defined(WITH_CLASSPATH_SUN)
72 # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
75 # include "native/include/java_lang_ClassLoader.h"
77 # include "native/include/java_lang_reflect_Constructor.h"
78 # include "native/include/java_lang_reflect_Field.h"
79 # include "native/include/java_lang_reflect_Method.h"
81 # include "native/include/java_nio_Buffer.h"
83 # if defined(WITH_CLASSPATH_GNU)
84 # include "native/include/java_nio_DirectByteBufferImpl.h"
88 #if defined(ENABLE_JVMTI)
89 # include "native/jvmti/cacaodbg.h"
92 #include "native/vm/java_lang_Class.h"
94 #if defined(ENABLE_JAVASE)
95 # include "native/vm/java_lang_ClassLoader.h"
96 # include "native/vm/reflect.h"
99 #include "threads/lock-common.h"
100 #include "threads/threads-common.h"
102 #include "toolbox/logging.h"
104 #include "vm/builtin.h"
105 #include "vm/exceptions.h"
106 #include "vm/global.h"
107 #include "vm/initialize.h"
108 #include "vm/primitive.h"
109 #include "vm/resolve.h"
110 #include "vm/stringlocal.h"
113 #include "vm/jit/asmpart.h"
114 #include "vm/jit/jit.h"
115 #include "vm/jit/stacktrace.h"
117 #include "vmcore/loader.h"
118 #include "vmcore/options.h"
119 #include "vmcore/statistics.h"
122 /* debug **********************************************************************/
125 # define TRACEJNICALLS(format, ...) \
127 if (opt_TraceJNICalls) { \
128 log_println((format), __VA_ARGS__); \
132 # define TRACEJNICALLS(format, ...)
136 /* global variables ***********************************************************/
138 /* global reference table *****************************************************/
140 /* hashsize must be power of 2 */
142 #define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
144 static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
147 /* direct buffer stuff ********************************************************/
149 #if defined(ENABLE_JAVASE)
150 static classinfo *class_java_nio_Buffer;
151 static classinfo *class_java_nio_DirectByteBufferImpl;
152 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
154 # if defined(WITH_CLASSPATH_GNU)
155 # if SIZEOF_VOID_P == 8
156 static classinfo *class_gnu_classpath_Pointer64;
158 static classinfo *class_gnu_classpath_Pointer32;
162 static methodinfo *dbbirw_init;
166 /* accessing instance fields macros *******************************************/
168 #define SET_FIELD(o,type,f,value) \
169 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
171 #define GET_FIELD(o,type,f) \
172 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
175 /* some forward declarations **************************************************/
177 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
180 /* jni_init ********************************************************************
182 Initialize the JNI subsystem.
184 *******************************************************************************/
188 /* create global ref hashtable */
190 hashtable_global_ref = NEW(hashtable);
192 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
195 #if defined(ENABLE_JAVASE)
196 /* direct buffer stuff */
198 if (!(class_java_nio_Buffer =
199 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
200 !link_class(class_java_nio_Buffer))
203 # if defined(WITH_CLASSPATH_GNU)
204 if (!(class_java_nio_DirectByteBufferImpl =
205 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
206 !link_class(class_java_nio_DirectByteBufferImpl))
209 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
210 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
211 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
215 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
217 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
220 # if SIZEOF_VOID_P == 8
221 if (!(class_gnu_classpath_Pointer64 =
222 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
223 !link_class(class_gnu_classpath_Pointer64))
226 if (!(class_gnu_classpath_Pointer32 =
227 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
228 !link_class(class_gnu_classpath_Pointer32))
232 #endif /* defined(ENABLE_JAVASE) */
238 /* _Jv_jni_CallObjectMethod ****************************************************
240 Internal function to call Java Object methods.
242 *******************************************************************************/
244 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
246 methodinfo *m, va_list ap)
251 STATISTICS(jniinvokation());
254 exceptions_throw_nullpointerexception();
258 /* Class initialization is done by the JIT compiler. This is ok
259 since a static method always belongs to the declaring class. */
261 if (m->flags & ACC_STATIC) {
262 /* For static methods we reset the object. */
267 /* for convenience */
272 /* For instance methods we make a virtual function table lookup. */
274 resm = method_vftbl_lookup(vftbl, m);
277 STATISTICS(jnicallXmethodnvokation());
279 ro = vm_call_method_valist(resm, o, ap);
285 /* _Jv_jni_CallObjectMethodA ***************************************************
287 Internal function to call Java Object methods.
289 *******************************************************************************/
291 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
299 STATISTICS(jniinvokation());
302 exceptions_throw_nullpointerexception();
306 /* Class initialization is done by the JIT compiler. This is ok
307 since a static method always belongs to the declaring class. */
309 if (m->flags & ACC_STATIC) {
310 /* For static methods we reset the object. */
315 /* for convenience */
320 /* For instance methods we make a virtual function table lookup. */
322 resm = method_vftbl_lookup(vftbl, m);
325 STATISTICS(jnicallXmethodnvokation());
327 ro = vm_call_method_jvalue(resm, o, args);
333 /* _Jv_jni_CallIntMethod *******************************************************
335 Internal function to call Java integer class methods (boolean,
336 byte, char, short, int).
338 *******************************************************************************/
340 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
341 methodinfo *m, va_list ap)
346 STATISTICS(jniinvokation());
349 exceptions_throw_nullpointerexception();
353 /* Class initialization is done by the JIT compiler. This is ok
354 since a static method always belongs to the declaring class. */
356 if (m->flags & ACC_STATIC) {
357 /* For static methods we reset the object. */
362 /* for convenience */
367 /* For instance methods we make a virtual function table lookup. */
369 resm = method_vftbl_lookup(vftbl, m);
372 STATISTICS(jnicallXmethodnvokation());
374 i = vm_call_method_int_valist(resm, o, ap);
380 /* _Jv_jni_CallIntMethodA ******************************************************
382 Internal function to call Java integer class methods (boolean,
383 byte, char, short, int).
385 *******************************************************************************/
387 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
388 methodinfo *m, const jvalue *args)
393 STATISTICS(jniinvokation());
396 exceptions_throw_nullpointerexception();
400 /* Class initialization is done by the JIT compiler. This is ok
401 since a static method always belongs to the declaring class. */
403 if (m->flags & ACC_STATIC) {
404 /* For static methods we reset the object. */
409 /* for convenience */
414 /* For instance methods we make a virtual function table lookup. */
416 resm = method_vftbl_lookup(vftbl, m);
419 STATISTICS(jnicallXmethodnvokation());
421 i = vm_call_method_int_jvalue(resm, o, args);
427 /* _Jv_jni_CallLongMethod ******************************************************
429 Internal function to call Java long methods.
431 *******************************************************************************/
433 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
434 methodinfo *m, va_list ap)
439 STATISTICS(jniinvokation());
442 exceptions_throw_nullpointerexception();
446 /* Class initialization is done by the JIT compiler. This is ok
447 since a static method always belongs to the declaring class. */
449 if (m->flags & ACC_STATIC) {
450 /* For static methods we reset the object. */
455 /* for convenience */
460 /* For instance methods we make a virtual function table lookup. */
462 resm = method_vftbl_lookup(vftbl, m);
465 STATISTICS(jnicallXmethodnvokation());
467 l = vm_call_method_long_valist(resm, o, ap);
473 /* _Jv_jni_CallLongMethodA *****************************************************
475 Internal function to call Java long methods.
477 *******************************************************************************/
479 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
480 methodinfo *m, const jvalue *args)
485 STATISTICS(jniinvokation());
488 exceptions_throw_nullpointerexception();
492 /* Class initialization is done by the JIT compiler. This is ok
493 since a static method always belongs to the declaring class. */
495 if (m->flags & ACC_STATIC) {
496 /* For static methods we reset the object. */
501 /* for convenience */
506 /* For instance methods we make a virtual function table lookup. */
508 resm = method_vftbl_lookup(vftbl, m);
511 STATISTICS(jnicallXmethodnvokation());
513 l = vm_call_method_long_jvalue(resm, o, args);
519 /* _Jv_jni_CallFloatMethod *****************************************************
521 Internal function to call Java float methods.
523 *******************************************************************************/
525 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
526 methodinfo *m, va_list ap)
531 /* Class initialization is done by the JIT compiler. This is ok
532 since a static method always belongs to the declaring class. */
534 if (m->flags & ACC_STATIC) {
535 /* For static methods we reset the object. */
540 /* for convenience */
545 /* For instance methods we make a virtual function table lookup. */
547 resm = method_vftbl_lookup(vftbl, m);
550 STATISTICS(jnicallXmethodnvokation());
552 f = vm_call_method_float_valist(resm, o, ap);
558 /* _Jv_jni_CallFloatMethodA ****************************************************
560 Internal function to call Java float methods.
562 *******************************************************************************/
564 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
565 methodinfo *m, const jvalue *args)
570 /* Class initialization is done by the JIT compiler. This is ok
571 since a static method always belongs to the declaring class. */
573 if (m->flags & ACC_STATIC) {
574 /* For static methods we reset the object. */
579 /* for convenience */
584 /* For instance methods we make a virtual function table lookup. */
586 resm = method_vftbl_lookup(vftbl, m);
589 STATISTICS(jnicallXmethodnvokation());
591 f = vm_call_method_float_jvalue(resm, o, args);
597 /* _Jv_jni_CallDoubleMethod ****************************************************
599 Internal function to call Java double methods.
601 *******************************************************************************/
603 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
604 methodinfo *m, va_list ap)
609 /* Class initialization is done by the JIT compiler. This is ok
610 since a static method always belongs to the declaring class. */
612 if (m->flags & ACC_STATIC) {
613 /* For static methods we reset the object. */
618 /* for convenience */
623 /* For instance methods we make a virtual function table lookup. */
625 resm = method_vftbl_lookup(vftbl, m);
628 d = vm_call_method_double_valist(resm, o, ap);
634 /* _Jv_jni_CallDoubleMethodA ***************************************************
636 Internal function to call Java double methods.
638 *******************************************************************************/
640 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
641 methodinfo *m, const jvalue *args)
646 /* Class initialization is done by the JIT compiler. This is ok
647 since a static method always belongs to the declaring class. */
649 if (m->flags & ACC_STATIC) {
650 /* For static methods we reset the object. */
655 /* for convenience */
660 /* For instance methods we make a virtual function table lookup. */
662 resm = method_vftbl_lookup(vftbl, m);
665 d = vm_call_method_double_jvalue(resm, o, args);
671 /* _Jv_jni_CallVoidMethod ******************************************************
673 Internal function to call Java void methods.
675 *******************************************************************************/
677 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
678 methodinfo *m, va_list ap)
683 exceptions_throw_nullpointerexception();
687 /* Class initialization is done by the JIT compiler. This is ok
688 since a static method always belongs to the declaring class. */
690 if (m->flags & ACC_STATIC) {
691 /* For static methods we reset the object. */
696 /* for convenience */
701 /* For instance methods we make a virtual function table lookup. */
703 resm = method_vftbl_lookup(vftbl, m);
706 STATISTICS(jnicallXmethodnvokation());
708 (void) vm_call_method_valist(resm, o, ap);
712 /* _Jv_jni_CallVoidMethodA *****************************************************
714 Internal function to call Java void methods.
716 *******************************************************************************/
718 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
719 methodinfo *m, const jvalue *args)
724 exceptions_throw_nullpointerexception();
728 /* Class initialization is done by the JIT compiler. This is ok
729 since a static method always belongs to the declaring class. */
731 if (m->flags & ACC_STATIC) {
732 /* For static methods we reset the object. */
737 /* for convenience */
742 /* For instance methods we make a virtual function table lookup. */
744 resm = method_vftbl_lookup(vftbl, m);
747 STATISTICS(jnicallXmethodnvokation());
749 (void) vm_call_method_jvalue(resm, o, args);
753 /* _Jv_jni_invokeNative ********************************************************
755 Invoke a method on the given object with the given arguments.
757 For instance methods OBJ must be != NULL and the method is looked up
758 in the vftbl of the object.
760 For static methods, OBJ is ignored.
762 *******************************************************************************/
764 java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
765 java_handle_objectarray_t *params)
777 exceptions_throw_nullpointerexception();
781 argcount = m->parseddesc->paramcount;
782 paramcount = argcount;
784 /* if method is non-static, remove the `this' pointer */
786 if (!(m->flags & ACC_STATIC))
789 /* For instance methods the object has to be an instance of the
790 class the method belongs to. For static methods the obj
791 parameter is ignored. */
793 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
794 exceptions_throw_illegalargumentexception();
798 /* check if we got the right number of arguments */
800 if (((params == NULL) && (paramcount != 0)) ||
801 (params && (LLNI_array_size(params) != paramcount)))
803 exceptions_throw_illegalargumentexception();
807 /* for instance methods we need an object */
809 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
810 /* XXX not sure if that is the correct exception */
811 exceptions_throw_nullpointerexception();
815 /* for static methods, zero object to make subsequent code simpler */
816 if (m->flags & ACC_STATIC)
820 /* for instance methods we must do a vftbl lookup */
821 resm = method_vftbl_lookup(LLNI_vftbl_direct(o), m);
824 /* for static methods, just for convenience */
828 /* mark start of dump memory area */
830 dumpsize = dump_size();
832 /* Fill the argument array from a object-array. */
834 array = vm_array_from_objectarray(resm, o, params);
836 /* The array can be NULL if we don't have any arguments to pass
837 and the architecture does not have any argument registers
838 (e.g. i386). In that case we additionally check for an
841 if ((array == NULL) && (exceptions_get_exception() != NULL)) {
842 /* release dump area */
844 dump_release(dumpsize);
849 switch (resm->parseddesc->returntype.decltype) {
851 (void) vm_call_array(resm, array);
855 case PRIMITIVETYPE_BOOLEAN:
856 case PRIMITIVETYPE_BYTE:
857 case PRIMITIVETYPE_CHAR:
858 case PRIMITIVETYPE_SHORT:
859 case PRIMITIVETYPE_INT:
860 value.i = vm_call_int_array(resm, array);
861 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
864 case PRIMITIVETYPE_LONG:
865 value.l = vm_call_long_array(resm, array);
866 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
869 case PRIMITIVETYPE_FLOAT:
870 value.f = vm_call_float_array(resm, array);
871 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
874 case PRIMITIVETYPE_DOUBLE:
875 value.d = vm_call_double_array(resm, array);
876 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
880 ro = vm_call_array(resm, array);
884 vm_abort("_Jv_jni_invokeNative: invalid return type %d", resm->parseddesc->returntype.decltype);
887 xptr = exceptions_get_exception();
890 /* clear exception pointer, we are calling JIT code again */
892 exceptions_clear_exception();
894 exceptions_throw_invocationtargetexception(xptr);
897 /* release dump area */
899 dump_release(dumpsize);
905 /* GetVersion ******************************************************************
907 Returns the major version number in the higher 16 bits and the
908 minor version number in the lower 16 bits.
910 *******************************************************************************/
912 jint _Jv_JNI_GetVersion(JNIEnv *env)
914 STATISTICS(jniinvokation());
916 /* we support JNI 1.4 */
918 return JNI_VERSION_1_4;
922 /* Class Operations ***********************************************************/
924 /* DefineClass *****************************************************************
926 Loads a class from a buffer of raw class data. The buffer
927 containing the raw class data is not referenced by the VM after the
928 DefineClass call returns, and it may be discarded if desired.
930 *******************************************************************************/
932 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
933 const jbyte *buf, jsize bufLen)
935 #if defined(ENABLE_JAVASE)
941 TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d", env, name, loader, buf, bufLen);
943 u = utf_new_char(name);
944 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
946 c = class_define(u, cl, bufLen, (const uint8_t *) buf);
948 co = LLNI_classinfo_wrap(c);
950 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
952 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
954 /* keep compiler happy */
961 /* FindClass *******************************************************************
963 This function loads a locally-defined class. It searches the
964 directories and zip files specified by the CLASSPATH environment
965 variable for the class with the specified name.
967 *******************************************************************************/
969 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
971 #if defined(ENABLE_JAVASE)
977 STATISTICS(jniinvokation());
979 u = utf_new_char_classname((char *) name);
981 /* Check stacktrace for classloader, if one found use it,
982 otherwise use the system classloader. */
984 /* Quote from the JNI documentation:
986 In the Java 2 Platform, FindClass locates the class loader
987 associated with the current native method. If the native code
988 belongs to a system class, no class loader will be
989 involved. Otherwise, the proper class loader will be invoked to
990 load and link the named class. When FindClass is called through
991 the Invocation Interface, there is no current native method or
992 its associated class loader. In that case, the result of
993 ClassLoader.getBaseClassLoader is used." */
995 cc = stacktrace_getCurrentClass();
998 c = load_class_from_sysloader(u);
1000 c = load_class_from_classloader(u, cc->classloader);
1008 co = LLNI_classinfo_wrap(c);
1010 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1012 vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1014 /* keep compiler happy */
1021 /* GetSuperclass ***************************************************************
1023 If clazz represents any class other than the class Object, then
1024 this function returns the object that represents the superclass of
1025 the class specified by clazz.
1027 *******************************************************************************/
1029 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1033 java_lang_Class *co;
1035 TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
1037 c = LLNI_classinfo_unwrap(sub);
1042 super = class_get_superclass(c);
1044 co = LLNI_classinfo_wrap(super);
1046 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1050 /* IsAssignableFrom ************************************************************
1052 Determines whether an object of sub can be safely cast to sup.
1054 *******************************************************************************/
1056 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1058 java_lang_Class *csup;
1059 java_lang_Class *csub;
1061 csup = (java_lang_Class *) sup;
1062 csub = (java_lang_Class *) sub;
1064 STATISTICS(jniinvokation());
1066 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1070 /* Throw ***********************************************************************
1072 Causes a java.lang.Throwable object to be thrown.
1074 *******************************************************************************/
1076 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1080 STATISTICS(jniinvokation());
1082 o = (java_handle_t *) obj;
1084 exceptions_set_exception(o);
1090 /* ThrowNew ********************************************************************
1092 Constructs an exception object from the specified class with the
1093 message specified by message and causes that exception to be
1096 *******************************************************************************/
1098 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1104 STATISTICS(jniinvokation());
1106 c = LLNI_classinfo_unwrap(clazz);
1109 s = javastring_new_from_utf_string(msg);
1111 /* instantiate exception object */
1113 o = native_new_and_init_string(c, s);
1118 exceptions_set_exception(o);
1124 /* ExceptionOccurred ***********************************************************
1126 Determines if an exception is being thrown. The exception stays
1127 being thrown until either the native code calls ExceptionClear(),
1128 or the Java code handles the exception.
1130 *******************************************************************************/
1132 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1136 STATISTICS(jniinvokation());
1138 o = exceptions_get_exception();
1140 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1144 /* ExceptionDescribe ***********************************************************
1146 Prints an exception and a backtrace of the stack to a system
1147 error-reporting channel, such as stderr. This is a convenience
1148 routine provided for debugging.
1150 *******************************************************************************/
1152 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1158 STATISTICS(jniinvokation());
1160 o = exceptions_get_exception();
1163 /* clear exception, because we are calling jit code again */
1165 exceptions_clear_exception();
1167 /* get printStackTrace method from exception class */
1169 LLNI_class_get(o, c);
1171 m = class_resolveclassmethod(c,
1172 utf_printStackTrace,
1178 /* XXX what should we do? */
1181 /* print the stacktrace */
1183 (void) vm_call_method(m, o);
1188 /* ExceptionClear **************************************************************
1190 Clears any exception that is currently being thrown. If no
1191 exception is currently being thrown, this routine has no effect.
1193 *******************************************************************************/
1195 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1197 STATISTICS(jniinvokation());
1199 exceptions_clear_exception();
1203 /* FatalError ******************************************************************
1205 Raises a fatal error and does not expect the VM to recover. This
1206 function does not return.
1208 *******************************************************************************/
1210 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1212 STATISTICS(jniinvokation());
1214 /* this seems to be the best way */
1216 vm_abort("JNI Fatal error: %s", msg);
1220 /* PushLocalFrame **************************************************************
1222 Creates a new local reference frame, in which at least a given
1223 number of local references can be created.
1225 *******************************************************************************/
1227 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1229 STATISTICS(jniinvokation());
1234 /* add new local reference frame to current table */
1236 if (!localref_frame_push(capacity))
1243 /* PopLocalFrame ***************************************************************
1245 Pops off the current local reference frame, frees all the local
1246 references, and returns a local reference in the previous local
1247 reference frame for the given result object.
1249 *******************************************************************************/
1251 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1253 STATISTICS(jniinvokation());
1255 /* release all current local frames */
1257 localref_frame_pop_all();
1259 /* add local reference and return the value */
1261 return _Jv_JNI_NewLocalRef(env, result);
1265 /* DeleteLocalRef **************************************************************
1267 Deletes the local reference pointed to by localRef.
1269 *******************************************************************************/
1271 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1275 STATISTICS(jniinvokation());
1277 o = (java_handle_t *) localRef;
1279 /* delete the reference */
1285 /* IsSameObject ****************************************************************
1287 Tests whether two references refer to the same Java object.
1289 *******************************************************************************/
1291 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1297 STATISTICS(jniinvokation());
1299 o1 = (java_handle_t *) ref1;
1300 o2 = (java_handle_t *) ref2;
1302 LLNI_CRITICAL_START;
1304 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1315 /* NewLocalRef *****************************************************************
1317 Creates a new local reference that refers to the same object as ref.
1319 *******************************************************************************/
1321 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1324 java_handle_t *localref;
1326 STATISTICS(jniinvokation());
1331 o = (java_handle_t *) ref;
1333 /* insert the reference */
1335 localref = localref_add(LLNI_DIRECT(o));
1341 /* EnsureLocalCapacity *********************************************************
1343 Ensures that at least a given number of local references can be
1344 created in the current thread
1346 *******************************************************************************/
1348 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1350 localref_table *lrt;
1352 STATISTICS(jniinvokation());
1354 /* get local reference table (thread specific) */
1356 lrt = LOCALREFTABLE;
1358 /* check if capacity elements are available in the local references table */
1360 if ((lrt->used + capacity) > lrt->capacity)
1361 return _Jv_JNI_PushLocalFrame(env, capacity);
1367 /* AllocObject *****************************************************************
1369 Allocates a new Java object without invoking any of the
1370 constructors for the object. Returns a reference to the object.
1372 *******************************************************************************/
1374 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1379 STATISTICS(jniinvokation());
1381 c = LLNI_classinfo_unwrap(clazz);
1383 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1384 exceptions_throw_instantiationexception(c);
1390 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1394 /* NewObject *******************************************************************
1396 Programmers place all arguments that are to be passed to the
1397 constructor immediately following the methodID
1398 argument. NewObject() accepts these arguments and passes them to
1399 the Java method that the programmer wishes to invoke.
1401 *******************************************************************************/
1403 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1410 STATISTICS(jniinvokation());
1412 c = LLNI_classinfo_unwrap(clazz);
1413 m = (methodinfo *) methodID;
1422 /* call constructor */
1424 va_start(ap, methodID);
1425 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1428 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1432 /* NewObjectV ******************************************************************
1434 Programmers place all arguments that are to be passed to the
1435 constructor in an args argument of type va_list that immediately
1436 follows the methodID argument. NewObjectV() accepts these
1437 arguments, and, in turn, passes them to the Java method that the
1438 programmer wishes to invoke.
1440 *******************************************************************************/
1442 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1449 STATISTICS(jniinvokation());
1451 c = LLNI_classinfo_unwrap(clazz);
1452 m = (methodinfo *) methodID;
1461 /* call constructor */
1463 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1465 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1469 /* NewObjectA *****************************************************************
1471 Programmers place all arguments that are to be passed to the
1472 constructor in an args array of jvalues that immediately follows
1473 the methodID argument. NewObjectA() accepts the arguments in this
1474 array, and, in turn, passes them to the Java method that the
1475 programmer wishes to invoke.
1477 *******************************************************************************/
1479 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1486 STATISTICS(jniinvokation());
1488 c = LLNI_classinfo_unwrap(clazz);
1489 m = (methodinfo *) methodID;
1498 /* call constructor */
1500 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1502 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1506 /* GetObjectClass **************************************************************
1508 Returns the class of an object.
1510 *******************************************************************************/
1512 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1516 java_lang_Class *co;
1518 STATISTICS(jniinvokation());
1520 o = (java_handle_t *) obj;
1522 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1525 LLNI_class_get(o, c);
1527 co = LLNI_classinfo_wrap(c);
1529 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1533 /* IsInstanceOf ****************************************************************
1535 Tests whether an object is an instance of a class.
1537 *******************************************************************************/
1539 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1542 java_lang_Object *o;
1544 STATISTICS(jniinvokation());
1546 c = (java_lang_Class *) clazz;
1547 o = (java_lang_Object *) obj;
1549 return _Jv_java_lang_Class_isInstance(c, o);
1553 /* Reflection Support *********************************************************/
1555 /* FromReflectedMethod *********************************************************
1557 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1558 object to a method ID.
1560 *******************************************************************************/
1562 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1564 #if defined(ENABLE_JAVASE)
1570 STATISTICS(jniinvokation());
1572 o = (java_handle_t *) method;
1577 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1578 java_lang_reflect_Method *rm;
1580 rm = (java_lang_reflect_Method *) method;
1581 LLNI_field_get_cls(rm, clazz, c);
1582 LLNI_field_get_val(rm, slot , slot);
1584 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1585 java_lang_reflect_Constructor *rc;
1587 rc = (java_lang_reflect_Constructor *) method;
1588 LLNI_field_get_cls(rc, clazz, c);
1589 LLNI_field_get_val(rc, slot , slot);
1594 m = &(c->methods[slot]);
1596 return (jmethodID) m;
1598 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1600 /* keep compiler happy */
1607 /* FromReflectedField **********************************************************
1609 Converts a java.lang.reflect.Field to a field ID.
1611 *******************************************************************************/
1613 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1615 #if defined(ENABLE_JAVASE)
1616 java_lang_reflect_Field *rf;
1621 STATISTICS(jniinvokation());
1623 rf = (java_lang_reflect_Field *) field;
1628 LLNI_field_get_cls(rf, clazz, c);
1629 LLNI_field_get_val(rf, slot , slot);
1630 f = &(c->fields[slot]);
1632 return (jfieldID) f;
1634 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1636 /* keep compiler happy */
1643 /* ToReflectedMethod ***********************************************************
1645 Converts a method ID derived from cls to an instance of the
1646 java.lang.reflect.Method class or to an instance of the
1647 java.lang.reflect.Constructor class.
1649 *******************************************************************************/
1651 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1654 #if defined(ENABLE_JAVASE)
1656 java_lang_reflect_Constructor *rc;
1657 java_lang_reflect_Method *rm;
1659 STATISTICS(jniinvokation());
1661 m = (methodinfo *) methodID;
1663 /* HotSpot does the same assert. */
1665 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1667 if (m->name == utf_init) {
1668 rc = reflect_constructor_new(m);
1670 return (jobject) rc;
1673 rm = reflect_method_new(m);
1675 return (jobject) rm;
1678 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1680 /* keep compiler happy */
1687 /* ToReflectedField ************************************************************
1689 Converts a field ID derived from cls to an instance of the
1690 java.lang.reflect.Field class.
1692 *******************************************************************************/
1694 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1697 STATISTICS(jniinvokation());
1699 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1705 /* Calling Instance Methods ***************************************************/
1707 /* GetMethodID *****************************************************************
1709 Returns the method ID for an instance (nonstatic) method of a class
1710 or interface. The method may be defined in one of the clazz's
1711 superclasses and inherited by clazz. The method is determined by
1712 its name and signature.
1714 GetMethodID() causes an uninitialized class to be initialized.
1716 *******************************************************************************/
1718 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1726 STATISTICS(jniinvokation());
1728 c = LLNI_classinfo_unwrap(clazz);
1733 if (!(c->state & CLASS_INITIALIZED))
1734 if (!initialize_class(c))
1737 /* try to get the method of the class or one of it's superclasses */
1739 uname = utf_new_char((char *) name);
1740 udesc = utf_new_char((char *) sig);
1742 m = class_resolvemethod(c, uname, udesc);
1744 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1745 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1750 return (jmethodID) m;
1754 /* JNI-functions for calling instance methods *********************************/
1756 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1757 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1758 jmethodID methodID, ...) \
1765 o = (java_handle_t *) obj; \
1766 m = (methodinfo *) methodID; \
1768 va_start(ap, methodID); \
1769 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1775 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1776 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1777 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1778 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1779 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1780 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1781 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1782 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1785 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1786 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1787 jmethodID methodID, va_list args) \
1793 o = (java_handle_t *) obj; \
1794 m = (methodinfo *) methodID; \
1796 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1801 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1802 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1803 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1804 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1805 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1806 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1807 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1808 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1811 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1812 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1813 jmethodID methodID, \
1814 const jvalue *args) \
1820 o = (java_handle_t *) obj; \
1821 m = (methodinfo *) methodID; \
1823 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1828 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1829 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1830 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1831 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1832 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1833 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1834 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1835 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1838 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1846 o = (java_handle_t *) obj;
1847 m = (methodinfo *) methodID;
1849 va_start(ap, methodID);
1850 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1853 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1857 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1864 o = (java_handle_t *) obj;
1865 m = (methodinfo *) methodID;
1867 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1869 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1873 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1880 o = (java_handle_t *) obj;
1881 m = (methodinfo *) methodID;
1883 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1885 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1890 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1896 o = (java_handle_t *) obj;
1897 m = (methodinfo *) methodID;
1899 va_start(ap, methodID);
1900 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1905 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1911 o = (java_handle_t *) obj;
1912 m = (methodinfo *) methodID;
1914 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1918 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1924 o = (java_handle_t *) obj;
1925 m = (methodinfo *) methodID;
1927 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1932 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1933 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1934 jclass clazz, jmethodID methodID, \
1943 o = (java_handle_t *) obj; \
1944 c = LLNI_classinfo_unwrap(clazz); \
1945 m = (methodinfo *) methodID; \
1947 va_start(ap, methodID); \
1948 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1954 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1955 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1956 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1957 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1958 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1959 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1960 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1961 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1964 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1965 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1966 jclass clazz, jmethodID methodID, \
1974 o = (java_handle_t *) obj; \
1975 c = LLNI_classinfo_unwrap(clazz); \
1976 m = (methodinfo *) methodID; \
1978 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1983 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1984 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1985 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1986 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1987 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1988 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1989 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1990 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1993 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1994 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1995 jclass clazz, jmethodID methodID, \
1996 const jvalue *args) \
1998 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
2003 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
2004 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
2005 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
2006 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
2007 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
2008 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
2009 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
2010 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
2012 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2013 jclass clazz, jmethodID methodID,
2022 o = (java_handle_t *) obj;
2023 c = LLNI_classinfo_unwrap(clazz);
2024 m = (methodinfo *) methodID;
2026 va_start(ap, methodID);
2027 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2030 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2034 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2035 jclass clazz, jmethodID methodID,
2043 o = (java_handle_t *) obj;
2044 c = LLNI_classinfo_unwrap(clazz);
2045 m = (methodinfo *) methodID;
2047 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2049 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2053 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2054 jclass clazz, jmethodID methodID,
2057 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2059 return _Jv_JNI_NewLocalRef(env, NULL);
2063 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2064 jmethodID methodID, ...)
2071 o = (java_handle_t *) obj;
2072 c = LLNI_classinfo_unwrap(clazz);
2073 m = (methodinfo *) methodID;
2075 va_start(ap, methodID);
2076 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2081 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2082 jmethodID methodID, va_list args)
2088 o = (java_handle_t *) obj;
2089 c = LLNI_classinfo_unwrap(clazz);
2090 m = (methodinfo *) methodID;
2092 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2096 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2097 jmethodID methodID, const jvalue * args)
2103 o = (java_handle_t *) obj;
2104 c = LLNI_classinfo_unwrap(clazz);
2105 m = (methodinfo *) methodID;
2107 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2111 /* Accessing Fields of Objects ************************************************/
2113 /* GetFieldID ******************************************************************
2115 Returns the field ID for an instance (nonstatic) field of a
2116 class. The field is specified by its name and signature. The
2117 Get<type>Field and Set<type>Field families of accessor functions
2118 use field IDs to retrieve object fields.
2120 *******************************************************************************/
2122 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2130 STATISTICS(jniinvokation());
2132 c = LLNI_classinfo_unwrap(clazz);
2134 /* XXX NPE check? */
2136 uname = utf_new_char((char *) name);
2137 udesc = utf_new_char((char *) sig);
2139 f = class_findfield(c, uname, udesc);
2142 exceptions_throw_nosuchfielderror(c, uname);
2144 return (jfieldID) f;
2148 /* Get<type>Field Routines *****************************************************
2150 This family of accessor routines returns the value of an instance
2151 (nonstatic) field of an object. The field to access is specified by
2152 a field ID obtained by calling GetFieldID().
2154 *******************************************************************************/
2156 #define JNI_GET_FIELD(name, type, intern) \
2157 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2161 STATISTICS(jniinvokation()); \
2163 ret = GET_FIELD(obj, intern, fieldID); \
2165 return (type) ret; \
2168 JNI_GET_FIELD(Boolean, jboolean, s4)
2169 JNI_GET_FIELD(Byte, jbyte, s4)
2170 JNI_GET_FIELD(Char, jchar, s4)
2171 JNI_GET_FIELD(Short, jshort, s4)
2172 JNI_GET_FIELD(Int, jint, s4)
2173 JNI_GET_FIELD(Long, jlong, s8)
2174 JNI_GET_FIELD(Float, jfloat, float)
2175 JNI_GET_FIELD(Double, jdouble, double)
2178 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2182 STATISTICS(jniinvokation());
2184 vm_abort("this needs to be fixed");
2185 o = GET_FIELD(obj, java_handle_t*, fieldID);
2187 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2191 /* Set<type>Field Routines *****************************************************
2193 This family of accessor routines sets the value of an instance
2194 (nonstatic) field of an object. The field to access is specified by
2195 a field ID obtained by calling GetFieldID().
2197 *******************************************************************************/
2199 #define JNI_SET_FIELD(name, type, intern) \
2200 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2203 STATISTICS(jniinvokation()); \
2205 SET_FIELD(obj, intern, fieldID, value); \
2208 JNI_SET_FIELD(Boolean, jboolean, s4)
2209 JNI_SET_FIELD(Byte, jbyte, s4)
2210 JNI_SET_FIELD(Char, jchar, s4)
2211 JNI_SET_FIELD(Short, jshort, s4)
2212 JNI_SET_FIELD(Int, jint, s4)
2213 JNI_SET_FIELD(Long, jlong, s8)
2214 JNI_SET_FIELD(Float, jfloat, float)
2215 JNI_SET_FIELD(Double, jdouble, double)
2218 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2221 STATISTICS(jniinvokation());
2223 vm_abort("this needs to be fixed");
2224 SET_FIELD(obj, java_handle_t*, fieldID, value);
2228 /* Calling Static Methods *****************************************************/
2230 /* GetStaticMethodID ***********************************************************
2232 Returns the method ID for a static method of a class. The method is
2233 specified by its name and signature.
2235 GetStaticMethodID() causes an uninitialized class to be
2238 *******************************************************************************/
2240 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2248 STATISTICS(jniinvokation());
2250 c = LLNI_classinfo_unwrap(clazz);
2255 if (!(c->state & CLASS_INITIALIZED))
2256 if (!initialize_class(c))
2259 /* try to get the static method of the class */
2261 uname = utf_new_char((char *) name);
2262 udesc = utf_new_char((char *) sig);
2264 m = class_resolvemethod(c, uname, udesc);
2266 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2267 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2272 return (jmethodID) m;
2276 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2277 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2278 jmethodID methodID, ...) \
2284 m = (methodinfo *) methodID; \
2286 va_start(ap, methodID); \
2287 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2293 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2294 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2295 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2296 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2297 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2298 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2299 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2300 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2303 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2304 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2305 jmethodID methodID, va_list args) \
2310 m = (methodinfo *) methodID; \
2312 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2317 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2318 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2319 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2320 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2321 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2322 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2323 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2324 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2327 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2328 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2329 jmethodID methodID, const jvalue *args) \
2334 m = (methodinfo *) methodID; \
2336 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2341 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2342 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2343 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2344 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2345 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2346 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2347 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2348 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2351 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2352 jmethodID methodID, ...)
2358 m = (methodinfo *) methodID;
2360 va_start(ap, methodID);
2361 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2364 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2368 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2369 jmethodID methodID, va_list args)
2374 m = (methodinfo *) methodID;
2376 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2378 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2382 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2383 jmethodID methodID, const jvalue *args)
2388 m = (methodinfo *) methodID;
2390 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2392 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2396 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2397 jmethodID methodID, ...)
2402 m = (methodinfo *) methodID;
2404 va_start(ap, methodID);
2405 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2410 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2411 jmethodID methodID, va_list args)
2415 m = (methodinfo *) methodID;
2417 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2421 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2422 jmethodID methodID, const jvalue * args)
2426 m = (methodinfo *) methodID;
2428 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2432 /* Accessing Static Fields ****************************************************/
2434 /* GetStaticFieldID ************************************************************
2436 Returns the field ID for a static field of a class. The field is
2437 specified by its name and signature. The GetStatic<type>Field and
2438 SetStatic<type>Field families of accessor functions use field IDs
2439 to retrieve static fields.
2441 *******************************************************************************/
2443 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2451 STATISTICS(jniinvokation());
2453 c = LLNI_classinfo_unwrap(clazz);
2455 uname = utf_new_char((char *) name);
2456 usig = utf_new_char((char *) sig);
2458 f = class_findfield(c, uname, usig);
2461 exceptions_throw_nosuchfielderror(c, uname);
2463 return (jfieldID) f;
2467 /* GetStatic<type>Field ********************************************************
2469 This family of accessor routines returns the value of a static
2472 *******************************************************************************/
2474 #define JNI_GET_STATIC_FIELD(name, type, field) \
2475 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2481 STATISTICS(jniinvokation()); \
2483 c = LLNI_classinfo_unwrap(clazz); \
2484 f = (fieldinfo *) fieldID; \
2486 if (!(c->state & CLASS_INITIALIZED)) \
2487 if (!initialize_class(c)) \
2490 return f->value->field; \
2493 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2494 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2495 JNI_GET_STATIC_FIELD(Char, jchar, i)
2496 JNI_GET_STATIC_FIELD(Short, jshort, i)
2497 JNI_GET_STATIC_FIELD(Int, jint, i)
2498 JNI_GET_STATIC_FIELD(Long, jlong, l)
2499 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2500 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2503 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2509 STATISTICS(jniinvokation());
2511 c = LLNI_classinfo_unwrap(clazz);
2512 f = (fieldinfo *) fieldID;
2514 if (!(c->state & CLASS_INITIALIZED))
2515 if (!initialize_class(c))
2518 return _Jv_JNI_NewLocalRef(env, f->value->a);
2522 /* SetStatic<type>Field *******************************************************
2524 This family of accessor routines sets the value of a static field
2527 *******************************************************************************/
2529 #define JNI_SET_STATIC_FIELD(name, type, field) \
2530 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2537 STATISTICS(jniinvokation()); \
2539 c = LLNI_classinfo_unwrap(clazz); \
2540 f = (fieldinfo *) fieldID; \
2542 if (!(c->state & CLASS_INITIALIZED)) \
2543 if (!initialize_class(c)) \
2546 f->value->field = value; \
2549 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2550 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2551 JNI_SET_STATIC_FIELD(Char, jchar, i)
2552 JNI_SET_STATIC_FIELD(Short, jshort, i)
2553 JNI_SET_STATIC_FIELD(Int, jint, i)
2554 JNI_SET_STATIC_FIELD(Long, jlong, l)
2555 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2556 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2559 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2565 STATISTICS(jniinvokation());
2567 c = LLNI_classinfo_unwrap(clazz);
2568 f = (fieldinfo *) fieldID;
2570 if (!(c->state & CLASS_INITIALIZED))
2571 if (!initialize_class(c))
2574 f->value->a = value;
2578 /* String Operations **********************************************************/
2580 /* NewString *******************************************************************
2582 Create new java.lang.String object from an array of Unicode
2585 *******************************************************************************/
2587 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2589 java_lang_String *s;
2590 java_handle_chararray_t *a;
2593 STATISTICS(jniinvokation());
2595 s = (java_lang_String *) builtin_new(class_java_lang_String);
2596 a = builtin_newarray_char(len);
2598 /* javastring or characterarray could not be created */
2599 if ((a == NULL) || (s == NULL))
2603 for (i = 0; i < len; i++)
2604 LLNI_array_direct(a, i) = buf[i];
2606 LLNI_field_set_ref(s, value , a);
2607 LLNI_field_set_val(s, offset, 0);
2608 LLNI_field_set_val(s, count , len);
2610 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2614 static jchar emptyStringJ[]={0,0};
2616 /* GetStringLength *************************************************************
2618 Returns the length (the count of Unicode characters) of a Java
2621 *******************************************************************************/
2623 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2625 java_lang_String *s;
2628 TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
2630 s = (java_lang_String *) str;
2632 LLNI_field_get_val(s, count, len);
2638 /******************** convertes javastring to u2-array ****************************/
2640 u2 *javastring_tou2(jstring so)
2642 java_lang_String *s;
2643 java_handle_chararray_t *a;
2649 STATISTICS(jniinvokation());
2651 s = (java_lang_String *) so;
2656 LLNI_field_get_ref(s, value, a);
2661 LLNI_field_get_val(s, count, count);
2662 LLNI_field_get_val(s, offset, offset);
2664 /* allocate memory */
2666 stringbuffer = MNEW(u2, count + 1);
2670 for (i = 0; i < count; i++)
2671 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2673 /* terminate string */
2675 stringbuffer[i] = '\0';
2677 return stringbuffer;
2681 /* GetStringChars **************************************************************
2683 Returns a pointer to the array of Unicode characters of the
2684 string. This pointer is valid until ReleaseStringChars() is called.
2686 *******************************************************************************/
2688 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2692 STATISTICS(jniinvokation());
2694 jc = javastring_tou2(str);
2706 return emptyStringJ;
2710 /* ReleaseStringChars **********************************************************
2712 Informs the VM that the native code no longer needs access to
2713 chars. The chars argument is a pointer obtained from string using
2716 *******************************************************************************/
2718 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2720 java_lang_String *s;
2722 STATISTICS(jniinvokation());
2724 if (chars == emptyStringJ)
2727 s = (java_lang_String *) str;
2729 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2733 /* NewStringUTF ****************************************************************
2735 Constructs a new java.lang.String object from an array of UTF-8
2738 *******************************************************************************/
2740 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2742 java_lang_String *s;
2744 TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
2746 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2748 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2752 /****************** returns the utf8 length in bytes of a string *******************/
2754 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2756 java_lang_String *s;
2759 TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
2761 s = (java_lang_String *) string;
2763 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2769 /* GetStringUTFChars ***********************************************************
2771 Returns a pointer to an array of UTF-8 characters of the
2772 string. This array is valid until it is released by
2773 ReleaseStringUTFChars().
2775 *******************************************************************************/
2777 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2782 STATISTICS(jniinvokation());
2790 u = javastring_toutf((java_handle_t *) string, false);
2799 /* ReleaseStringUTFChars *******************************************************
2801 Informs the VM that the native code no longer needs access to
2802 utf. The utf argument is a pointer derived from string using
2803 GetStringUTFChars().
2805 *******************************************************************************/
2807 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2809 STATISTICS(jniinvokation());
2811 /* XXX we don't release utf chars right now, perhaps that should be done
2812 later. Since there is always one reference the garbage collector will
2817 /* Array Operations ***********************************************************/
2819 /* GetArrayLength **************************************************************
2821 Returns the number of elements in the array.
2823 *******************************************************************************/
2825 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2830 STATISTICS(jniinvokation());
2832 a = (java_handle_t *) array;
2834 size = LLNI_array_size(a);
2840 /* NewObjectArray **************************************************************
2842 Constructs a new array holding objects in class elementClass. All
2843 elements are initially set to initialElement.
2845 *******************************************************************************/
2847 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2848 jclass elementClass, jobject initialElement)
2852 java_handle_objectarray_t *oa;
2855 STATISTICS(jniinvokation());
2857 c = LLNI_classinfo_unwrap(elementClass);
2858 o = (java_handle_t *) initialElement;
2861 exceptions_throw_negativearraysizeexception();
2865 oa = builtin_anewarray(length, c);
2870 /* set all elements to initialElement */
2872 for (i = 0; i < length; i++)
2873 LLNI_objectarray_element_set(oa, i, o);
2875 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2879 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2882 java_handle_objectarray_t *oa;
2885 STATISTICS(jniinvokation());
2887 oa = (java_handle_objectarray_t *) array;
2889 if (index >= LLNI_array_size(oa)) {
2890 exceptions_throw_arrayindexoutofboundsexception();
2894 LLNI_objectarray_element_get(oa, index, o);
2896 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2900 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2901 jsize index, jobject val)
2903 java_handle_objectarray_t *oa;
2906 STATISTICS(jniinvokation());
2908 oa = (java_handle_objectarray_t *) array;
2909 o = (java_handle_t *) val;
2911 if (index >= LLNI_array_size(oa)) {
2912 exceptions_throw_arrayindexoutofboundsexception();
2916 /* check if the class of value is a subclass of the element class
2919 if (!builtin_canstore(LLNI_DIRECT(oa), LLNI_DIRECT(o)))
2922 LLNI_objectarray_element_set(oa, index, o);
2926 #define JNI_NEW_ARRAY(name, type, intern) \
2927 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2929 java_handle_##intern##array_t *a; \
2931 STATISTICS(jniinvokation()); \
2934 exceptions_throw_negativearraysizeexception(); \
2938 a = builtin_newarray_##intern(len); \
2940 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2943 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2944 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2945 JNI_NEW_ARRAY(Char, jcharArray, char)
2946 JNI_NEW_ARRAY(Short, jshortArray, byte)
2947 JNI_NEW_ARRAY(Int, jintArray, int)
2948 JNI_NEW_ARRAY(Long, jlongArray, long)
2949 JNI_NEW_ARRAY(Float, jfloatArray, float)
2950 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2953 /* Get<PrimitiveType>ArrayElements *********************************************
2955 A family of functions that returns the body of the primitive array.
2957 *******************************************************************************/
2959 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2960 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2963 java_handle_##intern##array_t *a; \
2965 STATISTICS(jniinvokation()); \
2967 a = (java_handle_##intern##array_t *) array; \
2970 *isCopy = JNI_FALSE; \
2972 return LLNI_array_data(a); \
2975 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2976 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2977 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2978 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2979 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2980 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2981 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2982 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
2985 /* Release<PrimitiveType>ArrayElements *****************************************
2987 A family of functions that informs the VM that the native code no
2988 longer needs access to elems. The elems argument is a pointer
2989 derived from array using the corresponding
2990 Get<PrimitiveType>ArrayElements() function. If necessary, this
2991 function copies back all changes made to elems to the original
2994 *******************************************************************************/
2996 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
2997 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
2998 type *elems, jint mode) \
3000 java_handle_##intern##array_t *a; \
3002 STATISTICS(jniinvokation()); \
3004 a = (java_handle_##intern##array_t *) array; \
3006 if (elems != LLNI_array_data(a)) { \
3009 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3012 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3013 /* XXX TWISTI how should it be freed? */ \
3016 /* XXX TWISTI how should it be freed? */ \
3022 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3023 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3024 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3025 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3026 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3027 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3028 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3029 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3032 /* Get<PrimitiveType>ArrayRegion **********************************************
3034 A family of functions that copies a region of a primitive array
3037 *******************************************************************************/
3039 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3040 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3041 jsize start, jsize len, type *buf) \
3043 java_handle_##intern##array_t *a; \
3045 STATISTICS(jniinvokation()); \
3047 a = (java_handle_##intern##array_t *) array; \
3049 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3050 exceptions_throw_arrayindexoutofboundsexception(); \
3052 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3055 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3056 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3057 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3058 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3059 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3060 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3061 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3062 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3065 /* Set<PrimitiveType>ArrayRegion **********************************************
3067 A family of functions that copies back a region of a primitive
3068 array from a buffer.
3070 *******************************************************************************/
3072 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3073 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3074 jsize start, jsize len, const type *buf) \
3076 java_handle_##intern##array_t *a; \
3078 STATISTICS(jniinvokation()); \
3080 a = (java_handle_##intern##array_t *) array; \
3082 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3083 exceptions_throw_arrayindexoutofboundsexception(); \
3085 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3088 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3089 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3090 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3091 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3092 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3093 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3094 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3095 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3098 /* Registering Native Methods *************************************************/
3100 /* RegisterNatives *************************************************************
3102 Registers native methods with the class specified by the clazz
3103 argument. The methods parameter specifies an array of
3104 JNINativeMethod structures that contain the names, signatures, and
3105 function pointers of the native methods. The nMethods parameter
3106 specifies the number of native methods in the array.
3108 *******************************************************************************/
3110 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3111 const JNINativeMethod *methods, jint nMethods)
3115 STATISTICS(jniinvokation());
3117 c = LLNI_classinfo_unwrap(clazz);
3119 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3120 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3123 native_method_register(c->name, methods, nMethods);
3129 /* UnregisterNatives ***********************************************************
3131 Unregisters native methods of a class. The class goes back to the
3132 state before it was linked or registered with its native method
3135 This function should not be used in normal native code. Instead, it
3136 provides special programs a way to reload and relink native
3139 *******************************************************************************/
3141 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3143 STATISTICS(jniinvokation());
3145 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3147 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3153 /* Monitor Operations *********************************************************/
3155 /* MonitorEnter ****************************************************************
3157 Enters the monitor associated with the underlying Java object
3160 *******************************************************************************/
3162 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3164 STATISTICS(jniinvokation());
3167 exceptions_throw_nullpointerexception();
3171 LOCK_MONITOR_ENTER(obj);
3177 /* MonitorExit *****************************************************************
3179 The current thread must be the owner of the monitor associated with
3180 the underlying Java object referred to by obj. The thread
3181 decrements the counter indicating the number of times it has
3182 entered this monitor. If the value of the counter becomes zero, the
3183 current thread releases the monitor.
3185 *******************************************************************************/
3187 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3189 STATISTICS(jniinvokation());
3192 exceptions_throw_nullpointerexception();
3196 LOCK_MONITOR_EXIT(obj);
3202 /* JavaVM Interface ***********************************************************/
3204 /* GetJavaVM *******************************************************************
3206 Returns the Java VM interface (used in the Invocation API)
3207 associated with the current thread. The result is placed at the
3208 location pointed to by the second argument, vm.
3210 *******************************************************************************/
3212 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3214 STATISTICS(jniinvokation());
3216 *vm = (JavaVM *) _Jv_jvm;
3222 /* GetStringRegion *************************************************************
3224 Copies len number of Unicode characters beginning at offset start
3225 to the given buffer buf.
3227 Throws StringIndexOutOfBoundsException on index overflow.
3229 *******************************************************************************/
3231 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3234 java_lang_String *s;
3235 java_handle_chararray_t *ca;
3237 STATISTICS(jniinvokation());
3239 s = (java_lang_String *) str;
3240 LLNI_field_get_ref(s, value, ca);
3242 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3243 (start + len > LLNI_field_direct(s, count))) {
3244 exceptions_throw_stringindexoutofboundsexception();
3248 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3252 /* GetStringUTFRegion **********************************************************
3254 Translates len number of Unicode characters beginning at offset
3255 start into UTF-8 format and place the result in the given buffer
3258 Throws StringIndexOutOfBoundsException on index overflow.
3260 *******************************************************************************/
3262 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3263 jsize len, char *buf)
3265 java_lang_String *s;
3266 java_handle_chararray_t *ca;
3271 TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
3273 s = (java_lang_String *) str;
3274 LLNI_field_get_ref(s, value, ca);
3275 LLNI_field_get_val(s, count, count);
3276 LLNI_field_get_val(s, offset, offset);
3278 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3279 exceptions_throw_stringindexoutofboundsexception();
3283 for (i = 0; i < len; i++)
3284 buf[i] = LLNI_array_direct(ca, offset + start + i);
3290 /* GetPrimitiveArrayCritical ***************************************************
3292 Obtain a direct pointer to array elements.
3294 *******************************************************************************/
3296 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3299 java_handle_bytearray_t *ba;
3302 ba = (java_handle_bytearray_t *) array;
3304 /* do the same as Kaffe does */
3306 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3312 /* ReleasePrimitiveArrayCritical ***********************************************
3314 No specific documentation.
3316 *******************************************************************************/
3318 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3319 void *carray, jint mode)
3321 STATISTICS(jniinvokation());
3323 /* do the same as Kaffe does */
3325 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3330 /* GetStringCritical ***********************************************************
3332 The semantics of these two functions are similar to the existing
3333 Get/ReleaseStringChars functions.
3335 *******************************************************************************/
3337 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3340 STATISTICS(jniinvokation());
3342 return _Jv_JNI_GetStringChars(env, string, isCopy);
3346 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3347 const jchar *cstring)
3349 STATISTICS(jniinvokation());
3351 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3355 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3357 STATISTICS(jniinvokation());
3359 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
3365 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3367 STATISTICS(jniinvokation());
3369 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
3373 /* NewGlobalRef ****************************************************************
3375 Creates a new global reference to the object referred to by the obj
3378 *******************************************************************************/
3380 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3382 hashtable_global_ref_entry *gre;
3383 u4 key; /* hashkey */
3384 u4 slot; /* slot in hashtable */
3387 STATISTICS(jniinvokation());
3389 o = (java_handle_t *) obj;
3391 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3393 LLNI_CRITICAL_START;
3395 /* normally addresses are aligned to 4, 8 or 16 bytes */
3397 #if defined(ENABLE_GC_CACAO)
3398 key = heap_get_hashcode(LLNI_DIRECT(o)) >> 4;
3400 key = ((u4) (ptrint) o) >> 4; /* align to 16-byte boundaries */
3402 slot = key & (hashtable_global_ref->size - 1);
3403 gre = hashtable_global_ref->ptr[slot];
3405 /* search external hash chain for the entry */
3408 if (gre->o == LLNI_DIRECT(o)) {
3409 /* global object found, increment the reference */
3416 gre = gre->hashlink; /* next element in external chain */
3419 /* global ref not found, create a new one */
3422 gre = NEW(hashtable_global_ref_entry);
3424 #if defined(ENABLE_GC_CACAO)
3425 /* register global ref with the GC */
3427 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3430 gre->o = LLNI_DIRECT(o);
3433 /* insert entry into hashtable */
3435 gre->hashlink = hashtable_global_ref->ptr[slot];
3437 hashtable_global_ref->ptr[slot] = gre;
3439 /* update number of hashtable-entries */
3441 hashtable_global_ref->entries++;
3446 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3448 #if defined(ENABLE_HANDLES)
3456 /* DeleteGlobalRef *************************************************************
3458 Deletes the global reference pointed to by globalRef.
3460 *******************************************************************************/
3462 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3464 hashtable_global_ref_entry *gre;
3465 hashtable_global_ref_entry *prevgre;
3466 u4 key; /* hashkey */
3467 u4 slot; /* slot in hashtable */
3470 STATISTICS(jniinvokation());
3472 o = (java_handle_t *) globalRef;
3474 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3476 LLNI_CRITICAL_START;
3478 /* normally addresses are aligned to 4, 8 or 16 bytes */
3480 #if defined(ENABLE_GC_CACAO)
3481 key = heap_get_hashcode(LLNI_DIRECT(o)) >> 4;
3483 key = ((u4) (ptrint) o) >> 4; /* align to 16-byte boundaries */
3485 slot = key & (hashtable_global_ref->size - 1);
3486 gre = hashtable_global_ref->ptr[slot];
3488 /* initialize prevgre */
3492 /* search external hash chain for the entry */
3495 if (gre->o == LLNI_DIRECT(o)) {
3496 /* global object found, decrement the reference count */
3500 /* if reference count is 0, remove the entry */
3502 if (gre->refs == 0) {
3503 /* special handling if it's the first in the chain */
3505 if (prevgre == NULL)
3506 hashtable_global_ref->ptr[slot] = gre->hashlink;
3508 prevgre->hashlink = gre->hashlink;
3510 #if defined(ENABLE_GC_CACAO)
3511 /* unregister global ref with the GC */
3513 gc_reference_unregister(&(gre->o));
3516 FREE(gre, hashtable_global_ref_entry);
3521 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3526 prevgre = gre; /* save current pointer for removal */
3527 gre = gre->hashlink; /* next element in external chain */
3530 log_println("JNI-DeleteGlobalRef: global reference not found");
3534 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3538 /* ExceptionCheck **************************************************************
3540 Returns JNI_TRUE when there is a pending exception; otherwise,
3543 *******************************************************************************/
3545 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3549 STATISTICS(jniinvokation());
3551 o = exceptions_get_exception();
3553 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3557 /* New JNI 1.4 functions ******************************************************/
3559 /* NewDirectByteBuffer *********************************************************
3561 Allocates and returns a direct java.nio.ByteBuffer referring to the
3562 block of memory starting at the memory address address and
3563 extending capacity bytes.
3565 *******************************************************************************/
3567 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3569 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3570 java_handle_t *nbuf;
3572 # if SIZEOF_VOID_P == 8
3573 gnu_classpath_Pointer64 *paddress;
3575 gnu_classpath_Pointer32 *paddress;
3578 STATISTICS(jniinvokation());
3580 /* alocate a gnu.classpath.Pointer{32,64} object */
3582 # if SIZEOF_VOID_P == 8
3583 if (!(paddress = (gnu_classpath_Pointer64 *)
3584 builtin_new(class_gnu_classpath_Pointer64)))
3586 if (!(paddress = (gnu_classpath_Pointer32 *)
3587 builtin_new(class_gnu_classpath_Pointer32)))
3591 /* fill gnu.classpath.Pointer{32,64} with address */
3593 LLNI_field_set_val(paddress, data, (ptrint) address);
3595 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3597 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3598 (jmethodID) dbbirw_init, NULL, paddress,
3599 (jint) capacity, (jint) capacity, (jint) 0);
3601 /* add local reference and return the value */
3603 return _Jv_JNI_NewLocalRef(env, nbuf);
3605 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3607 /* keep compiler happy */
3614 /* GetDirectBufferAddress ******************************************************
3616 Fetches and returns the starting address of the memory region
3617 referenced by the given direct java.nio.Buffer.
3619 *******************************************************************************/
3621 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3623 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3624 java_nio_DirectByteBufferImpl *nbuf;
3625 # if SIZEOF_VOID_P == 8
3626 gnu_classpath_Pointer64 *paddress;
3628 gnu_classpath_Pointer32 *paddress;
3632 STATISTICS(jniinvokation());
3634 if (!builtin_instanceof(buf, class_java_nio_Buffer))
3637 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3639 # if SIZEOF_VOID_P == 8
3640 LLNI_field_get_ref(nbuf, address, paddress);
3641 /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
3643 LLNI_field_get_ref(nbuf, address, paddress);
3644 /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
3647 if (paddress == NULL)
3650 LLNI_field_get_val(paddress, data, address);
3651 /* this was the cast to avaoid warning: (void *) paddress->data */
3655 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3657 /* keep compiler happy */
3664 /* GetDirectBufferCapacity *****************************************************
3666 Fetches and returns the capacity in bytes of the memory region
3667 referenced by the given direct java.nio.Buffer.
3669 *******************************************************************************/
3671 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3673 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3675 java_nio_Buffer *nbuf;
3678 STATISTICS(jniinvokation());
3680 o = (java_handle_t *) buf;
3682 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3685 nbuf = (java_nio_Buffer *) o;
3687 LLNI_field_get_val(nbuf, cap, capacity);
3691 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3693 /* keep compiler happy */
3700 /* DestroyJavaVM ***************************************************************
3702 Unloads a Java VM and reclaims its resources. Only the main thread
3703 can unload the VM. The system waits until the main thread is only
3704 remaining user thread before it destroys the VM.
3706 *******************************************************************************/
3708 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3712 STATISTICS(jniinvokation());
3714 status = vm_destroy(vm);
3720 /* AttachCurrentThread *********************************************************
3722 Attaches the current thread to a Java VM. Returns a JNI interface
3723 pointer in the JNIEnv argument.
3725 Trying to attach a thread that is already attached is a no-op.
3727 A native thread cannot be attached simultaneously to two Java VMs.
3729 When a thread is attached to the VM, the context class loader is
3730 the bootstrap loader.
3732 *******************************************************************************/
3734 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3736 JavaVMAttachArgs *vm_aargs;
3738 #if defined(ENABLE_THREADS)
3739 if (threads_get_current_threadobject() == NULL) {
3740 vm_aargs = (JavaVMAttachArgs *) thr_args;
3742 if (vm_aargs != NULL) {
3743 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3744 (vm_aargs->version != JNI_VERSION_1_4))
3745 return JNI_EVERSION;
3748 if (!threads_attach_current_thread(vm_aargs, false))
3751 if (!localref_table_init())
3762 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3764 STATISTICS(jniinvokation());
3766 return jni_attach_current_thread(p_env, thr_args, false);
3770 /* DetachCurrentThread *********************************************************
3772 Detaches the current thread from a Java VM. All Java monitors held
3773 by this thread are released. All Java threads waiting for this
3774 thread to die are notified.
3776 In JDK 1.1, the main thread cannot be detached from the VM. It must
3777 call DestroyJavaVM to unload the entire VM.
3779 In the JDK, the main thread can be detached from the VM.
3781 The main thread, which is the thread that created the Java VM,
3782 cannot be detached from the VM. Instead, the main thread must call
3783 JNI_DestroyJavaVM() to unload the entire VM.
3785 *******************************************************************************/
3787 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3789 #if defined(ENABLE_THREADS)
3790 threadobject *thread;
3792 STATISTICS(jniinvokation());
3794 thread = threads_get_current_threadobject();
3799 if (!localref_table_destroy())
3802 if (!threads_detach_thread(thread))
3810 /* GetEnv **********************************************************************
3812 If the current thread is not attached to the VM, sets *env to NULL,
3813 and returns JNI_EDETACHED. If the specified version is not
3814 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3815 sets *env to the appropriate interface, and returns JNI_OK.
3817 *******************************************************************************/
3819 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3821 STATISTICS(jniinvokation());
3823 #if defined(ENABLE_THREADS)
3824 if (threads_get_current_threadobject() == NULL) {
3827 return JNI_EDETACHED;
3831 /* check the JNI version */
3834 case JNI_VERSION_1_1:
3835 case JNI_VERSION_1_2:
3836 case JNI_VERSION_1_4:
3844 #if defined(ENABLE_JVMTI)
3845 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3846 == JVMTI_VERSION_INTERFACE_JVMTI) {
3848 *env = (void *) jvmti_new_environment();
3857 return JNI_EVERSION;
3861 /* AttachCurrentThreadAsDaemon *************************************************
3863 Same semantics as AttachCurrentThread, but the newly-created
3864 java.lang.Thread instance is a daemon.
3866 If the thread has already been attached via either
3867 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3868 simply sets the value pointed to by penv to the JNIEnv of the
3869 current thread. In this case neither AttachCurrentThread nor this
3870 routine have any effect on the daemon status of the thread.
3872 *******************************************************************************/
3874 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3876 STATISTICS(jniinvokation());
3878 return jni_attach_current_thread(penv, args, true);
3882 /* JNI invocation table *******************************************************/
3884 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3889 _Jv_JNI_DestroyJavaVM,
3890 _Jv_JNI_AttachCurrentThread,
3891 _Jv_JNI_DetachCurrentThread,
3893 _Jv_JNI_AttachCurrentThreadAsDaemon
3897 /* JNI function table *********************************************************/
3899 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3906 _Jv_JNI_DefineClass,
3908 _Jv_JNI_FromReflectedMethod,
3909 _Jv_JNI_FromReflectedField,
3910 _Jv_JNI_ToReflectedMethod,
3911 _Jv_JNI_GetSuperclass,
3912 _Jv_JNI_IsAssignableFrom,
3913 _Jv_JNI_ToReflectedField,
3917 _Jv_JNI_ExceptionOccurred,
3918 _Jv_JNI_ExceptionDescribe,
3919 _Jv_JNI_ExceptionClear,
3921 _Jv_JNI_PushLocalFrame,
3922 _Jv_JNI_PopLocalFrame,
3924 _Jv_JNI_NewGlobalRef,
3925 _Jv_JNI_DeleteGlobalRef,
3926 _Jv_JNI_DeleteLocalRef,
3927 _Jv_JNI_IsSameObject,
3928 _Jv_JNI_NewLocalRef,
3929 _Jv_JNI_EnsureLocalCapacity,
3931 _Jv_JNI_AllocObject,
3936 _Jv_JNI_GetObjectClass,
3937 _Jv_JNI_IsInstanceOf,
3939 _Jv_JNI_GetMethodID,
3941 _Jv_JNI_CallObjectMethod,
3942 _Jv_JNI_CallObjectMethodV,
3943 _Jv_JNI_CallObjectMethodA,
3944 _Jv_JNI_CallBooleanMethod,
3945 _Jv_JNI_CallBooleanMethodV,
3946 _Jv_JNI_CallBooleanMethodA,
3947 _Jv_JNI_CallByteMethod,
3948 _Jv_JNI_CallByteMethodV,
3949 _Jv_JNI_CallByteMethodA,
3950 _Jv_JNI_CallCharMethod,
3951 _Jv_JNI_CallCharMethodV,
3952 _Jv_JNI_CallCharMethodA,
3953 _Jv_JNI_CallShortMethod,
3954 _Jv_JNI_CallShortMethodV,
3955 _Jv_JNI_CallShortMethodA,
3956 _Jv_JNI_CallIntMethod,
3957 _Jv_JNI_CallIntMethodV,
3958 _Jv_JNI_CallIntMethodA,
3959 _Jv_JNI_CallLongMethod,
3960 _Jv_JNI_CallLongMethodV,
3961 _Jv_JNI_CallLongMethodA,
3962 _Jv_JNI_CallFloatMethod,
3963 _Jv_JNI_CallFloatMethodV,
3964 _Jv_JNI_CallFloatMethodA,
3965 _Jv_JNI_CallDoubleMethod,
3966 _Jv_JNI_CallDoubleMethodV,
3967 _Jv_JNI_CallDoubleMethodA,
3968 _Jv_JNI_CallVoidMethod,
3969 _Jv_JNI_CallVoidMethodV,
3970 _Jv_JNI_CallVoidMethodA,
3972 _Jv_JNI_CallNonvirtualObjectMethod,
3973 _Jv_JNI_CallNonvirtualObjectMethodV,
3974 _Jv_JNI_CallNonvirtualObjectMethodA,
3975 _Jv_JNI_CallNonvirtualBooleanMethod,
3976 _Jv_JNI_CallNonvirtualBooleanMethodV,
3977 _Jv_JNI_CallNonvirtualBooleanMethodA,
3978 _Jv_JNI_CallNonvirtualByteMethod,
3979 _Jv_JNI_CallNonvirtualByteMethodV,
3980 _Jv_JNI_CallNonvirtualByteMethodA,
3981 _Jv_JNI_CallNonvirtualCharMethod,
3982 _Jv_JNI_CallNonvirtualCharMethodV,
3983 _Jv_JNI_CallNonvirtualCharMethodA,
3984 _Jv_JNI_CallNonvirtualShortMethod,
3985 _Jv_JNI_CallNonvirtualShortMethodV,
3986 _Jv_JNI_CallNonvirtualShortMethodA,
3987 _Jv_JNI_CallNonvirtualIntMethod,
3988 _Jv_JNI_CallNonvirtualIntMethodV,
3989 _Jv_JNI_CallNonvirtualIntMethodA,
3990 _Jv_JNI_CallNonvirtualLongMethod,
3991 _Jv_JNI_CallNonvirtualLongMethodV,
3992 _Jv_JNI_CallNonvirtualLongMethodA,
3993 _Jv_JNI_CallNonvirtualFloatMethod,
3994 _Jv_JNI_CallNonvirtualFloatMethodV,
3995 _Jv_JNI_CallNonvirtualFloatMethodA,
3996 _Jv_JNI_CallNonvirtualDoubleMethod,
3997 _Jv_JNI_CallNonvirtualDoubleMethodV,
3998 _Jv_JNI_CallNonvirtualDoubleMethodA,
3999 _Jv_JNI_CallNonvirtualVoidMethod,
4000 _Jv_JNI_CallNonvirtualVoidMethodV,
4001 _Jv_JNI_CallNonvirtualVoidMethodA,
4005 _Jv_JNI_GetObjectField,
4006 _Jv_JNI_GetBooleanField,
4007 _Jv_JNI_GetByteField,
4008 _Jv_JNI_GetCharField,
4009 _Jv_JNI_GetShortField,
4010 _Jv_JNI_GetIntField,
4011 _Jv_JNI_GetLongField,
4012 _Jv_JNI_GetFloatField,
4013 _Jv_JNI_GetDoubleField,
4014 _Jv_JNI_SetObjectField,
4015 _Jv_JNI_SetBooleanField,
4016 _Jv_JNI_SetByteField,
4017 _Jv_JNI_SetCharField,
4018 _Jv_JNI_SetShortField,
4019 _Jv_JNI_SetIntField,
4020 _Jv_JNI_SetLongField,
4021 _Jv_JNI_SetFloatField,
4022 _Jv_JNI_SetDoubleField,
4024 _Jv_JNI_GetStaticMethodID,
4026 _Jv_JNI_CallStaticObjectMethod,
4027 _Jv_JNI_CallStaticObjectMethodV,
4028 _Jv_JNI_CallStaticObjectMethodA,
4029 _Jv_JNI_CallStaticBooleanMethod,
4030 _Jv_JNI_CallStaticBooleanMethodV,
4031 _Jv_JNI_CallStaticBooleanMethodA,
4032 _Jv_JNI_CallStaticByteMethod,
4033 _Jv_JNI_CallStaticByteMethodV,
4034 _Jv_JNI_CallStaticByteMethodA,
4035 _Jv_JNI_CallStaticCharMethod,
4036 _Jv_JNI_CallStaticCharMethodV,
4037 _Jv_JNI_CallStaticCharMethodA,
4038 _Jv_JNI_CallStaticShortMethod,
4039 _Jv_JNI_CallStaticShortMethodV,
4040 _Jv_JNI_CallStaticShortMethodA,
4041 _Jv_JNI_CallStaticIntMethod,
4042 _Jv_JNI_CallStaticIntMethodV,
4043 _Jv_JNI_CallStaticIntMethodA,
4044 _Jv_JNI_CallStaticLongMethod,
4045 _Jv_JNI_CallStaticLongMethodV,
4046 _Jv_JNI_CallStaticLongMethodA,
4047 _Jv_JNI_CallStaticFloatMethod,
4048 _Jv_JNI_CallStaticFloatMethodV,
4049 _Jv_JNI_CallStaticFloatMethodA,
4050 _Jv_JNI_CallStaticDoubleMethod,
4051 _Jv_JNI_CallStaticDoubleMethodV,
4052 _Jv_JNI_CallStaticDoubleMethodA,
4053 _Jv_JNI_CallStaticVoidMethod,
4054 _Jv_JNI_CallStaticVoidMethodV,
4055 _Jv_JNI_CallStaticVoidMethodA,
4057 _Jv_JNI_GetStaticFieldID,
4059 _Jv_JNI_GetStaticObjectField,
4060 _Jv_JNI_GetStaticBooleanField,
4061 _Jv_JNI_GetStaticByteField,
4062 _Jv_JNI_GetStaticCharField,
4063 _Jv_JNI_GetStaticShortField,
4064 _Jv_JNI_GetStaticIntField,
4065 _Jv_JNI_GetStaticLongField,
4066 _Jv_JNI_GetStaticFloatField,
4067 _Jv_JNI_GetStaticDoubleField,
4068 _Jv_JNI_SetStaticObjectField,
4069 _Jv_JNI_SetStaticBooleanField,
4070 _Jv_JNI_SetStaticByteField,
4071 _Jv_JNI_SetStaticCharField,
4072 _Jv_JNI_SetStaticShortField,
4073 _Jv_JNI_SetStaticIntField,
4074 _Jv_JNI_SetStaticLongField,
4075 _Jv_JNI_SetStaticFloatField,
4076 _Jv_JNI_SetStaticDoubleField,
4079 _Jv_JNI_GetStringLength,
4080 _Jv_JNI_GetStringChars,
4081 _Jv_JNI_ReleaseStringChars,
4083 _Jv_JNI_NewStringUTF,
4084 _Jv_JNI_GetStringUTFLength,
4085 _Jv_JNI_GetStringUTFChars,
4086 _Jv_JNI_ReleaseStringUTFChars,
4088 _Jv_JNI_GetArrayLength,
4090 _Jv_JNI_NewObjectArray,
4091 _Jv_JNI_GetObjectArrayElement,
4092 _Jv_JNI_SetObjectArrayElement,
4094 _Jv_JNI_NewBooleanArray,
4095 _Jv_JNI_NewByteArray,
4096 _Jv_JNI_NewCharArray,
4097 _Jv_JNI_NewShortArray,
4098 _Jv_JNI_NewIntArray,
4099 _Jv_JNI_NewLongArray,
4100 _Jv_JNI_NewFloatArray,
4101 _Jv_JNI_NewDoubleArray,
4103 _Jv_JNI_GetBooleanArrayElements,
4104 _Jv_JNI_GetByteArrayElements,
4105 _Jv_JNI_GetCharArrayElements,
4106 _Jv_JNI_GetShortArrayElements,
4107 _Jv_JNI_GetIntArrayElements,
4108 _Jv_JNI_GetLongArrayElements,
4109 _Jv_JNI_GetFloatArrayElements,
4110 _Jv_JNI_GetDoubleArrayElements,
4112 _Jv_JNI_ReleaseBooleanArrayElements,
4113 _Jv_JNI_ReleaseByteArrayElements,
4114 _Jv_JNI_ReleaseCharArrayElements,
4115 _Jv_JNI_ReleaseShortArrayElements,
4116 _Jv_JNI_ReleaseIntArrayElements,
4117 _Jv_JNI_ReleaseLongArrayElements,
4118 _Jv_JNI_ReleaseFloatArrayElements,
4119 _Jv_JNI_ReleaseDoubleArrayElements,
4121 _Jv_JNI_GetBooleanArrayRegion,
4122 _Jv_JNI_GetByteArrayRegion,
4123 _Jv_JNI_GetCharArrayRegion,
4124 _Jv_JNI_GetShortArrayRegion,
4125 _Jv_JNI_GetIntArrayRegion,
4126 _Jv_JNI_GetLongArrayRegion,
4127 _Jv_JNI_GetFloatArrayRegion,
4128 _Jv_JNI_GetDoubleArrayRegion,
4129 _Jv_JNI_SetBooleanArrayRegion,
4130 _Jv_JNI_SetByteArrayRegion,
4131 _Jv_JNI_SetCharArrayRegion,
4132 _Jv_JNI_SetShortArrayRegion,
4133 _Jv_JNI_SetIntArrayRegion,
4134 _Jv_JNI_SetLongArrayRegion,
4135 _Jv_JNI_SetFloatArrayRegion,
4136 _Jv_JNI_SetDoubleArrayRegion,
4138 _Jv_JNI_RegisterNatives,
4139 _Jv_JNI_UnregisterNatives,
4141 _Jv_JNI_MonitorEnter,
4142 _Jv_JNI_MonitorExit,
4146 /* new JNI 1.2 functions */
4148 _Jv_JNI_GetStringRegion,
4149 _Jv_JNI_GetStringUTFRegion,
4151 _Jv_JNI_GetPrimitiveArrayCritical,
4152 _Jv_JNI_ReleasePrimitiveArrayCritical,
4154 _Jv_JNI_GetStringCritical,
4155 _Jv_JNI_ReleaseStringCritical,
4157 _Jv_JNI_NewWeakGlobalRef,
4158 _Jv_JNI_DeleteWeakGlobalRef,
4160 _Jv_JNI_ExceptionCheck,
4162 /* new JNI 1.4 functions */
4164 _Jv_JNI_NewDirectByteBuffer,
4165 _Jv_JNI_GetDirectBufferAddress,
4166 _Jv_JNI_GetDirectBufferCapacity
4170 /* Invocation API Functions ***************************************************/
4172 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4174 Returns a default configuration for the Java VM.
4176 *******************************************************************************/
4178 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4180 JavaVMInitArgs *_vm_args;
4182 _vm_args = (JavaVMInitArgs *) vm_args;
4184 /* GNU classpath currently supports JNI 1.2 */
4186 switch (_vm_args->version) {
4187 case JNI_VERSION_1_1:
4188 _vm_args->version = JNI_VERSION_1_1;
4191 case JNI_VERSION_1_2:
4192 case JNI_VERSION_1_4:
4193 _vm_args->ignoreUnrecognized = JNI_FALSE;
4194 _vm_args->options = NULL;
4195 _vm_args->nOptions = 0;
4206 /* JNI_GetCreatedJavaVMs *******************************************************
4208 Returns all Java VMs that have been created. Pointers to VMs are written in
4209 the buffer vmBuf in the order they are created. At most bufLen number of
4210 entries will be written. The total number of created VMs is returned in
4213 *******************************************************************************/
4215 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4217 TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
4222 /* We currently only support 1 VM running. */
4224 vmBuf[0] = (JavaVM *) _Jv_jvm;
4231 /* JNI_CreateJavaVM ************************************************************
4233 Loads and initializes a Java VM. The current thread becomes the main thread.
4234 Sets the env argument to the JNI interface pointer of the main thread.
4236 *******************************************************************************/
4238 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4240 TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
4242 /* actually create the JVM */
4244 if (!vm_createjvm(p_vm, p_env, vm_args))
4252 * These are local overrides for various environment variables in Emacs.
4253 * Please do not remove this and leave it at the end of the file, where
4254 * Emacs will automagically detect them.
4255 * ---------------------------------------------------------------------
4258 * indent-tabs-mode: t
4262 * vim:noexpandtab:sw=4:ts=4: