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 8343 2007-08-17 21:39:32Z 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);
178 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity);
181 /* jni_init ********************************************************************
183 Initialize the JNI subsystem.
185 *******************************************************************************/
189 /* create global ref hashtable */
191 hashtable_global_ref = NEW(hashtable);
193 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
196 #if defined(ENABLE_JAVASE)
197 /* direct buffer stuff */
199 if (!(class_java_nio_Buffer =
200 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
201 !link_class(class_java_nio_Buffer))
204 # if defined(WITH_CLASSPATH_GNU)
205 if (!(class_java_nio_DirectByteBufferImpl =
206 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
207 !link_class(class_java_nio_DirectByteBufferImpl))
210 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
211 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
212 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
216 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
218 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
221 # if SIZEOF_VOID_P == 8
222 if (!(class_gnu_classpath_Pointer64 =
223 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
224 !link_class(class_gnu_classpath_Pointer64))
227 if (!(class_gnu_classpath_Pointer32 =
228 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
229 !link_class(class_gnu_classpath_Pointer32))
233 #endif /* defined(ENABLE_JAVASE) */
239 /* jni_init_localref_table *****************************************************
241 Frees the local references table of the current thread.
243 *******************************************************************************/
245 bool jni_free_localref_table(void)
249 #if defined(ENABLE_GC_CACAO)
253 assert(lrt->prev == NULL);
255 FREE(lrt, localref_table);
257 LOCALREFTABLE = NULL;
264 /* _Jv_jni_CallObjectMethod ****************************************************
266 Internal function to call Java Object methods.
268 *******************************************************************************/
270 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
272 methodinfo *m, va_list ap)
277 STATISTICS(jniinvokation());
280 exceptions_throw_nullpointerexception();
284 /* Class initialization is done by the JIT compiler. This is ok
285 since a static method always belongs to the declaring class. */
287 if (m->flags & ACC_STATIC) {
288 /* For static methods we reset the object. */
293 /* for convenience */
298 /* For instance methods we make a virtual function table lookup. */
300 resm = method_vftbl_lookup(vftbl, m);
303 STATISTICS(jnicallXmethodnvokation());
305 ro = vm_call_method_valist(resm, o, ap);
311 /* _Jv_jni_CallObjectMethodA ***************************************************
313 Internal function to call Java Object methods.
315 *******************************************************************************/
317 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
325 STATISTICS(jniinvokation());
328 exceptions_throw_nullpointerexception();
332 /* Class initialization is done by the JIT compiler. This is ok
333 since a static method always belongs to the declaring class. */
335 if (m->flags & ACC_STATIC) {
336 /* For static methods we reset the object. */
341 /* for convenience */
346 /* For instance methods we make a virtual function table lookup. */
348 resm = method_vftbl_lookup(vftbl, m);
351 STATISTICS(jnicallXmethodnvokation());
353 ro = vm_call_method_jvalue(resm, o, args);
359 /* _Jv_jni_CallIntMethod *******************************************************
361 Internal function to call Java integer class methods (boolean,
362 byte, char, short, int).
364 *******************************************************************************/
366 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
367 methodinfo *m, va_list ap)
372 STATISTICS(jniinvokation());
375 exceptions_throw_nullpointerexception();
379 /* Class initialization is done by the JIT compiler. This is ok
380 since a static method always belongs to the declaring class. */
382 if (m->flags & ACC_STATIC) {
383 /* For static methods we reset the object. */
388 /* for convenience */
393 /* For instance methods we make a virtual function table lookup. */
395 resm = method_vftbl_lookup(vftbl, m);
398 STATISTICS(jnicallXmethodnvokation());
400 i = vm_call_method_int_valist(resm, o, ap);
406 /* _Jv_jni_CallIntMethodA ******************************************************
408 Internal function to call Java integer class methods (boolean,
409 byte, char, short, int).
411 *******************************************************************************/
413 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
414 methodinfo *m, const jvalue *args)
419 STATISTICS(jniinvokation());
422 exceptions_throw_nullpointerexception();
426 /* Class initialization is done by the JIT compiler. This is ok
427 since a static method always belongs to the declaring class. */
429 if (m->flags & ACC_STATIC) {
430 /* For static methods we reset the object. */
435 /* for convenience */
440 /* For instance methods we make a virtual function table lookup. */
442 resm = method_vftbl_lookup(vftbl, m);
445 STATISTICS(jnicallXmethodnvokation());
447 i = vm_call_method_int_jvalue(resm, o, args);
453 /* _Jv_jni_CallLongMethod ******************************************************
455 Internal function to call Java long methods.
457 *******************************************************************************/
459 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
460 methodinfo *m, va_list ap)
465 STATISTICS(jniinvokation());
468 exceptions_throw_nullpointerexception();
472 /* Class initialization is done by the JIT compiler. This is ok
473 since a static method always belongs to the declaring class. */
475 if (m->flags & ACC_STATIC) {
476 /* For static methods we reset the object. */
481 /* for convenience */
486 /* For instance methods we make a virtual function table lookup. */
488 resm = method_vftbl_lookup(vftbl, m);
491 STATISTICS(jnicallXmethodnvokation());
493 l = vm_call_method_long_valist(resm, o, ap);
499 /* _Jv_jni_CallLongMethodA *****************************************************
501 Internal function to call Java long methods.
503 *******************************************************************************/
505 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
506 methodinfo *m, const jvalue *args)
511 STATISTICS(jniinvokation());
514 exceptions_throw_nullpointerexception();
518 /* Class initialization is done by the JIT compiler. This is ok
519 since a static method always belongs to the declaring class. */
521 if (m->flags & ACC_STATIC) {
522 /* For static methods we reset the object. */
527 /* for convenience */
532 /* For instance methods we make a virtual function table lookup. */
534 resm = method_vftbl_lookup(vftbl, m);
537 STATISTICS(jnicallXmethodnvokation());
539 l = vm_call_method_long_jvalue(resm, o, args);
545 /* _Jv_jni_CallFloatMethod *****************************************************
547 Internal function to call Java float methods.
549 *******************************************************************************/
551 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
552 methodinfo *m, va_list ap)
557 /* Class initialization is done by the JIT compiler. This is ok
558 since a static method always belongs to the declaring class. */
560 if (m->flags & ACC_STATIC) {
561 /* For static methods we reset the object. */
566 /* for convenience */
571 /* For instance methods we make a virtual function table lookup. */
573 resm = method_vftbl_lookup(vftbl, m);
576 STATISTICS(jnicallXmethodnvokation());
578 f = vm_call_method_float_valist(resm, o, ap);
584 /* _Jv_jni_CallFloatMethodA ****************************************************
586 Internal function to call Java float methods.
588 *******************************************************************************/
590 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
591 methodinfo *m, const jvalue *args)
596 /* Class initialization is done by the JIT compiler. This is ok
597 since a static method always belongs to the declaring class. */
599 if (m->flags & ACC_STATIC) {
600 /* For static methods we reset the object. */
605 /* for convenience */
610 /* For instance methods we make a virtual function table lookup. */
612 resm = method_vftbl_lookup(vftbl, m);
615 STATISTICS(jnicallXmethodnvokation());
617 f = vm_call_method_float_jvalue(resm, o, args);
623 /* _Jv_jni_CallDoubleMethod ****************************************************
625 Internal function to call Java double methods.
627 *******************************************************************************/
629 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
630 methodinfo *m, va_list ap)
635 /* Class initialization is done by the JIT compiler. This is ok
636 since a static method always belongs to the declaring class. */
638 if (m->flags & ACC_STATIC) {
639 /* For static methods we reset the object. */
644 /* for convenience */
649 /* For instance methods we make a virtual function table lookup. */
651 resm = method_vftbl_lookup(vftbl, m);
654 d = vm_call_method_double_valist(resm, o, ap);
660 /* _Jv_jni_CallDoubleMethodA ***************************************************
662 Internal function to call Java double methods.
664 *******************************************************************************/
666 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
667 methodinfo *m, const jvalue *args)
672 /* Class initialization is done by the JIT compiler. This is ok
673 since a static method always belongs to the declaring class. */
675 if (m->flags & ACC_STATIC) {
676 /* For static methods we reset the object. */
681 /* for convenience */
686 /* For instance methods we make a virtual function table lookup. */
688 resm = method_vftbl_lookup(vftbl, m);
691 d = vm_call_method_double_jvalue(resm, o, args);
697 /* _Jv_jni_CallVoidMethod ******************************************************
699 Internal function to call Java void methods.
701 *******************************************************************************/
703 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
704 methodinfo *m, va_list ap)
709 exceptions_throw_nullpointerexception();
713 /* Class initialization is done by the JIT compiler. This is ok
714 since a static method always belongs to the declaring class. */
716 if (m->flags & ACC_STATIC) {
717 /* For static methods we reset the object. */
722 /* for convenience */
727 /* For instance methods we make a virtual function table lookup. */
729 resm = method_vftbl_lookup(vftbl, m);
732 STATISTICS(jnicallXmethodnvokation());
734 (void) vm_call_method_valist(resm, o, ap);
738 /* _Jv_jni_CallVoidMethodA *****************************************************
740 Internal function to call Java void methods.
742 *******************************************************************************/
744 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
745 methodinfo *m, const jvalue *args)
750 exceptions_throw_nullpointerexception();
754 /* Class initialization is done by the JIT compiler. This is ok
755 since a static method always belongs to the declaring class. */
757 if (m->flags & ACC_STATIC) {
758 /* For static methods we reset the object. */
763 /* for convenience */
768 /* For instance methods we make a virtual function table lookup. */
770 resm = method_vftbl_lookup(vftbl, m);
773 STATISTICS(jnicallXmethodnvokation());
775 (void) vm_call_method_jvalue(resm, o, args);
779 /* _Jv_jni_invokeNative ********************************************************
781 Invoke a method on the given object with the given arguments.
783 For instance methods OBJ must be != NULL and the method is looked up
784 in the vftbl of the object.
786 For static methods, OBJ is ignored.
788 *******************************************************************************/
790 java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
791 java_handle_objectarray_t *params)
803 exceptions_throw_nullpointerexception();
807 argcount = m->parseddesc->paramcount;
808 paramcount = argcount;
810 /* if method is non-static, remove the `this' pointer */
812 if (!(m->flags & ACC_STATIC))
815 /* For instance methods the object has to be an instance of the
816 class the method belongs to. For static methods the obj
817 parameter is ignored. */
819 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
820 exceptions_throw_illegalargumentexception();
824 /* check if we got the right number of arguments */
826 if (((params == NULL) && (paramcount != 0)) ||
827 (params && (LLNI_array_size(params) != paramcount)))
829 exceptions_throw_illegalargumentexception();
833 /* for instance methods we need an object */
835 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
836 /* XXX not sure if that is the correct exception */
837 exceptions_throw_nullpointerexception();
841 /* for static methods, zero object to make subsequent code simpler */
842 if (m->flags & ACC_STATIC)
846 /* for instance methods we must do a vftbl lookup */
847 resm = method_vftbl_lookup(o->vftbl, m);
850 /* for static methods, just for convenience */
854 /* mark start of dump memory area */
856 dumpsize = dump_size();
858 /* Fill the argument array from a object-array. */
860 array = vm_array_from_objectarray(resm, o, params);
862 /* The array can be NULL if we don't have any arguments to pass
863 and the architecture does not have any argument registers
864 (e.g. i386). In that case we additionally check for an
867 if ((array == NULL) && (exceptions_get_exception() != NULL)) {
868 /* release dump area */
870 dump_release(dumpsize);
875 switch (resm->parseddesc->returntype.decltype) {
877 (void) vm_call_array(resm, array);
881 case PRIMITIVETYPE_BOOLEAN:
882 case PRIMITIVETYPE_BYTE:
883 case PRIMITIVETYPE_CHAR:
884 case PRIMITIVETYPE_SHORT:
885 case PRIMITIVETYPE_INT:
886 value.i = vm_call_int_array(resm, array);
887 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
890 case PRIMITIVETYPE_LONG:
891 value.l = vm_call_long_array(resm, array);
892 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
895 case PRIMITIVETYPE_FLOAT:
896 value.f = vm_call_float_array(resm, array);
897 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
900 case PRIMITIVETYPE_DOUBLE:
901 value.d = vm_call_double_array(resm, array);
902 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
906 ro = vm_call_array(resm, array);
910 vm_abort("_Jv_jni_invokeNative: invalid return type %d", resm->parseddesc->returntype.decltype);
913 xptr = exceptions_get_exception();
916 /* clear exception pointer, we are calling JIT code again */
918 exceptions_clear_exception();
920 exceptions_throw_invocationtargetexception(xptr);
923 /* release dump area */
925 dump_release(dumpsize);
931 /* GetVersion ******************************************************************
933 Returns the major version number in the higher 16 bits and the
934 minor version number in the lower 16 bits.
936 *******************************************************************************/
938 jint _Jv_JNI_GetVersion(JNIEnv *env)
940 STATISTICS(jniinvokation());
942 /* we support JNI 1.4 */
944 return JNI_VERSION_1_4;
948 /* Class Operations ***********************************************************/
950 /* DefineClass *****************************************************************
952 Loads a class from a buffer of raw class data. The buffer
953 containing the raw class data is not referenced by the VM after the
954 DefineClass call returns, and it may be discarded if desired.
956 *******************************************************************************/
958 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
959 const jbyte *buf, jsize bufLen)
961 #if defined(ENABLE_JAVASE)
966 TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d", env, name, loader, buf, bufLen);
968 u = utf_new_char(name);
969 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
971 c = class_define(u, cl, bufLen, (const uint8_t *) buf);
973 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
975 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
977 /* keep compiler happy */
984 /* FindClass *******************************************************************
986 This function loads a locally-defined class. It searches the
987 directories and zip files specified by the CLASSPATH environment
988 variable for the class with the specified name.
990 *******************************************************************************/
992 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
994 #if defined(ENABLE_JAVASE)
999 STATISTICS(jniinvokation());
1001 u = utf_new_char_classname((char *) name);
1003 /* Check stacktrace for classloader, if one found use it,
1004 otherwise use the system classloader. */
1006 /* Quote from the JNI documentation:
1008 In the Java 2 Platform, FindClass locates the class loader
1009 associated with the current native method. If the native code
1010 belongs to a system class, no class loader will be
1011 involved. Otherwise, the proper class loader will be invoked to
1012 load and link the named class. When FindClass is called through
1013 the Invocation Interface, there is no current native method or
1014 its associated class loader. In that case, the result of
1015 ClassLoader.getBaseClassLoader is used." */
1017 cc = stacktrace_getCurrentClass();
1020 c = load_class_from_sysloader(u);
1022 c = load_class_from_classloader(u, cc->classloader);
1030 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1032 vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1034 /* keep compiler happy */
1041 /* GetSuperclass ***************************************************************
1043 If clazz represents any class other than the class Object, then
1044 this function returns the object that represents the superclass of
1045 the class specified by clazz.
1047 *******************************************************************************/
1049 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1054 TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
1056 c = LLNI_classinfo_unwrap(sub);
1061 super = class_get_superclass(c);
1063 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) super);
1067 /* IsAssignableFrom ************************************************************
1069 Determines whether an object of sub can be safely cast to sup.
1071 *******************************************************************************/
1073 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1075 java_lang_Class *csup;
1076 java_lang_Class *csub;
1078 csup = (java_lang_Class *) sup;
1079 csub = (java_lang_Class *) sub;
1081 STATISTICS(jniinvokation());
1083 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1087 /* Throw ***********************************************************************
1089 Causes a java.lang.Throwable object to be thrown.
1091 *******************************************************************************/
1093 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1097 STATISTICS(jniinvokation());
1099 o = (java_handle_t *) obj;
1101 exceptions_set_exception(o);
1107 /* ThrowNew ********************************************************************
1109 Constructs an exception object from the specified class with the
1110 message specified by message and causes that exception to be
1113 *******************************************************************************/
1115 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1121 STATISTICS(jniinvokation());
1123 c = LLNI_classinfo_unwrap(clazz);
1126 s = javastring_new_from_utf_string(msg);
1128 /* instantiate exception object */
1130 o = native_new_and_init_string(c, s);
1135 exceptions_set_exception(o);
1141 /* ExceptionOccurred ***********************************************************
1143 Determines if an exception is being thrown. The exception stays
1144 being thrown until either the native code calls ExceptionClear(),
1145 or the Java code handles the exception.
1147 *******************************************************************************/
1149 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1153 STATISTICS(jniinvokation());
1155 o = exceptions_get_exception();
1157 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1161 /* ExceptionDescribe ***********************************************************
1163 Prints an exception and a backtrace of the stack to a system
1164 error-reporting channel, such as stderr. This is a convenience
1165 routine provided for debugging.
1167 *******************************************************************************/
1169 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1174 STATISTICS(jniinvokation());
1176 o = exceptions_get_exception();
1179 /* clear exception, because we are calling jit code again */
1181 exceptions_clear_exception();
1183 /* get printStackTrace method from exception class */
1185 m = class_resolveclassmethod(o->vftbl->class,
1186 utf_printStackTrace,
1192 /* XXX what should we do? */
1195 /* print the stacktrace */
1197 (void) vm_call_method(m, o);
1202 /* ExceptionClear **************************************************************
1204 Clears any exception that is currently being thrown. If no
1205 exception is currently being thrown, this routine has no effect.
1207 *******************************************************************************/
1209 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1211 STATISTICS(jniinvokation());
1213 exceptions_clear_exception();
1217 /* FatalError ******************************************************************
1219 Raises a fatal error and does not expect the VM to recover. This
1220 function does not return.
1222 *******************************************************************************/
1224 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1226 STATISTICS(jniinvokation());
1228 /* this seems to be the best way */
1230 vm_abort("JNI Fatal error: %s", msg);
1234 /* PushLocalFrame **************************************************************
1236 Creates a new local reference frame, in which at least a given
1237 number of local references can be created.
1239 *******************************************************************************/
1241 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1243 STATISTICS(jniinvokation());
1248 /* add new local reference frame to current table */
1250 if (!localref_frame_push(capacity))
1257 /* PopLocalFrame ***************************************************************
1259 Pops off the current local reference frame, frees all the local
1260 references, and returns a local reference in the previous local
1261 reference frame for the given result object.
1263 *******************************************************************************/
1265 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1267 STATISTICS(jniinvokation());
1269 /* release all current local frames */
1271 localref_frame_pop_all();
1273 /* add local reference and return the value */
1275 return _Jv_JNI_NewLocalRef(env, result);
1279 /* DeleteLocalRef **************************************************************
1281 Deletes the local reference pointed to by localRef.
1283 *******************************************************************************/
1285 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1288 localref_table *lrt;
1291 STATISTICS(jniinvokation());
1293 o = (java_handle_t *) localRef;
1295 /* get local reference table (thread specific) */
1297 lrt = LOCALREFTABLE;
1299 /* go through all local frames */
1301 for (; lrt != NULL; lrt = lrt->prev) {
1303 /* and try to remove the reference */
1305 for (i = 0; i < lrt->capacity; i++) {
1306 if (lrt->refs[i] == o) {
1307 lrt->refs[i] = NULL;
1315 /* this should not happen */
1317 /* if (opt_checkjni) */
1318 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1319 log_text("JNI-DeleteLocalRef: Local ref passed to JNI not found");
1323 /* IsSameObject ****************************************************************
1325 Tests whether two references refer to the same Java object.
1327 *******************************************************************************/
1329 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1331 STATISTICS(jniinvokation());
1340 /* NewLocalRef *****************************************************************
1342 Creates a new local reference that refers to the same object as ref.
1344 *******************************************************************************/
1346 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1348 localref_table *lrt;
1351 STATISTICS(jniinvokation());
1356 /* get local reference table (thread specific) */
1358 lrt = LOCALREFTABLE;
1360 /* Check if we have space for the requested reference? No,
1361 allocate a new frame. This is actually not what the spec says,
1362 but for compatibility reasons... */
1364 if (lrt->used == lrt->capacity) {
1365 if (_Jv_JNI_EnsureLocalCapacity(env, 16) != 0)
1368 /* get the new local reference table */
1370 lrt = LOCALREFTABLE;
1373 /* insert the reference */
1375 for (i = 0; i < lrt->capacity; i++) {
1376 if (lrt->refs[i] == NULL) {
1377 lrt->refs[i] = (java_handle_t *) ref;
1384 /* should not happen, just to be sure */
1388 /* keep compiler happy */
1394 /* EnsureLocalCapacity *********************************************************
1396 Ensures that at least a given number of local references can be
1397 created in the current thread
1399 *******************************************************************************/
1401 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1403 localref_table *lrt;
1405 STATISTICS(jniinvokation());
1407 /* get local reference table (thread specific) */
1409 lrt = LOCALREFTABLE;
1411 /* check if capacity elements are available in the local references table */
1413 if ((lrt->used + capacity) > lrt->capacity)
1414 return _Jv_JNI_PushLocalFrame(env, capacity);
1420 /* AllocObject *****************************************************************
1422 Allocates a new Java object without invoking any of the
1423 constructors for the object. Returns a reference to the object.
1425 *******************************************************************************/
1427 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1432 STATISTICS(jniinvokation());
1434 c = LLNI_classinfo_unwrap(clazz);
1436 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1437 exceptions_throw_instantiationexception(c);
1443 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1447 /* NewObject *******************************************************************
1449 Programmers place all arguments that are to be passed to the
1450 constructor immediately following the methodID
1451 argument. NewObject() accepts these arguments and passes them to
1452 the Java method that the programmer wishes to invoke.
1454 *******************************************************************************/
1456 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1463 STATISTICS(jniinvokation());
1465 c = LLNI_classinfo_unwrap(clazz);
1466 m = (methodinfo *) methodID;
1475 /* call constructor */
1477 va_start(ap, methodID);
1478 _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
1481 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1485 /* NewObjectV ******************************************************************
1487 Programmers place all arguments that are to be passed to the
1488 constructor in an args argument of type va_list that immediately
1489 follows the methodID argument. NewObjectV() accepts these
1490 arguments, and, in turn, passes them to the Java method that the
1491 programmer wishes to invoke.
1493 *******************************************************************************/
1495 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1502 STATISTICS(jniinvokation());
1504 c = LLNI_classinfo_unwrap(clazz);
1505 m = (methodinfo *) methodID;
1514 /* call constructor */
1516 _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
1518 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1522 /* NewObjectA *****************************************************************
1524 Programmers place all arguments that are to be passed to the
1525 constructor in an args array of jvalues that immediately follows
1526 the methodID argument. NewObjectA() accepts the arguments in this
1527 array, and, in turn, passes them to the Java method that the
1528 programmer wishes to invoke.
1530 *******************************************************************************/
1532 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1539 STATISTICS(jniinvokation());
1541 c = LLNI_classinfo_unwrap(clazz);
1542 m = (methodinfo *) methodID;
1551 /* call constructor */
1553 _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
1555 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1559 /* GetObjectClass **************************************************************
1561 Returns the class of an object.
1563 *******************************************************************************/
1565 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1570 STATISTICS(jniinvokation());
1572 o = (java_handle_t *) obj;
1574 if ((o == NULL) || (o->vftbl == NULL))
1577 c = o->vftbl->class;
1579 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1583 /* IsInstanceOf ****************************************************************
1585 Tests whether an object is an instance of a class.
1587 *******************************************************************************/
1589 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1592 java_lang_Object *o;
1594 STATISTICS(jniinvokation());
1596 c = (java_lang_Class *) clazz;
1597 o = (java_lang_Object *) obj;
1599 return _Jv_java_lang_Class_isInstance(c, o);
1603 /* Reflection Support *********************************************************/
1605 /* FromReflectedMethod *********************************************************
1607 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1608 object to a method ID.
1610 *******************************************************************************/
1612 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1614 #if defined(ENABLE_JAVASE)
1620 STATISTICS(jniinvokation());
1622 o = (java_handle_t *) method;
1627 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1628 java_lang_reflect_Method *rm;
1630 rm = (java_lang_reflect_Method *) method;
1631 LLNI_field_get_cls(rm, clazz, c);
1632 LLNI_field_get_val(rm, slot , slot);
1634 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1635 java_lang_reflect_Constructor *rc;
1637 rc = (java_lang_reflect_Constructor *) method;
1638 LLNI_field_get_cls(rc, clazz, c);
1639 LLNI_field_get_val(rc, slot , slot);
1644 m = &(c->methods[slot]);
1646 return (jmethodID) m;
1648 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1650 /* keep compiler happy */
1657 /* FromReflectedField **********************************************************
1659 Converts a java.lang.reflect.Field to a field ID.
1661 *******************************************************************************/
1663 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1665 #if defined(ENABLE_JAVASE)
1666 java_lang_reflect_Field *rf;
1671 STATISTICS(jniinvokation());
1673 rf = (java_lang_reflect_Field *) field;
1678 LLNI_field_get_cls(rf, clazz, c);
1679 LLNI_field_get_val(rf, slot , slot);
1680 f = &(c->fields[slot]);
1682 return (jfieldID) f;
1684 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1686 /* keep compiler happy */
1693 /* ToReflectedMethod ***********************************************************
1695 Converts a method ID derived from cls to an instance of the
1696 java.lang.reflect.Method class or to an instance of the
1697 java.lang.reflect.Constructor class.
1699 *******************************************************************************/
1701 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1704 #if defined(ENABLE_JAVASE)
1706 java_lang_reflect_Constructor *rc;
1707 java_lang_reflect_Method *rm;
1709 STATISTICS(jniinvokation());
1711 m = (methodinfo *) methodID;
1713 /* HotSpot does the same assert. */
1715 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1717 if (m->name == utf_init) {
1718 rc = reflect_constructor_new(m);
1720 return (jobject) rc;
1723 rm = reflect_method_new(m);
1725 return (jobject) rm;
1728 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1730 /* keep compiler happy */
1737 /* ToReflectedField ************************************************************
1739 Converts a field ID derived from cls to an instance of the
1740 java.lang.reflect.Field class.
1742 *******************************************************************************/
1744 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1747 STATISTICS(jniinvokation());
1749 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1755 /* Calling Instance Methods ***************************************************/
1757 /* GetMethodID *****************************************************************
1759 Returns the method ID for an instance (nonstatic) method of a class
1760 or interface. The method may be defined in one of the clazz's
1761 superclasses and inherited by clazz. The method is determined by
1762 its name and signature.
1764 GetMethodID() causes an uninitialized class to be initialized.
1766 *******************************************************************************/
1768 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1776 STATISTICS(jniinvokation());
1778 c = LLNI_classinfo_unwrap(clazz);
1783 if (!(c->state & CLASS_INITIALIZED))
1784 if (!initialize_class(c))
1787 /* try to get the method of the class or one of it's superclasses */
1789 uname = utf_new_char((char *) name);
1790 udesc = utf_new_char((char *) sig);
1792 m = class_resolvemethod(c, uname, udesc);
1794 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1795 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1800 return (jmethodID) m;
1804 /* JNI-functions for calling instance methods *********************************/
1806 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1807 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1808 jmethodID methodID, ...) \
1815 o = (java_handle_t *) obj; \
1816 m = (methodinfo *) methodID; \
1818 va_start(ap, methodID); \
1819 ret = _Jv_jni_Call##intern##Method(o, o->vftbl, m, ap); \
1825 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1826 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1827 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1828 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1829 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1830 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1831 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1832 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1835 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1836 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1837 jmethodID methodID, va_list args) \
1843 o = (java_handle_t *) obj; \
1844 m = (methodinfo *) methodID; \
1846 ret = _Jv_jni_Call##intern##Method(o, o->vftbl, m, args); \
1851 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1852 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1853 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1854 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1855 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1856 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1857 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1858 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1861 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1862 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1863 jmethodID methodID, \
1864 const jvalue *args) \
1870 o = (java_handle_t *) obj; \
1871 m = (methodinfo *) methodID; \
1873 ret = _Jv_jni_Call##intern##MethodA(o, o->vftbl, m, args); \
1878 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1879 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1880 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1881 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1882 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1883 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1884 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1885 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1888 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1896 o = (java_handle_t *) obj;
1897 m = (methodinfo *) methodID;
1899 va_start(ap, methodID);
1900 ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, ap);
1903 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1907 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1914 o = (java_handle_t *) obj;
1915 m = (methodinfo *) methodID;
1917 ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, args);
1919 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1923 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1930 o = (java_handle_t *) obj;
1931 m = (methodinfo *) methodID;
1933 ret = _Jv_jni_CallObjectMethodA(o, o->vftbl, m, args);
1935 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1940 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1946 o = (java_handle_t *) obj;
1947 m = (methodinfo *) methodID;
1949 va_start(ap, methodID);
1950 _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
1955 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1961 o = (java_handle_t *) obj;
1962 m = (methodinfo *) methodID;
1964 _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
1968 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1974 o = (java_handle_t *) obj;
1975 m = (methodinfo *) methodID;
1977 _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
1982 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1983 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1984 jclass clazz, jmethodID methodID, \
1993 o = (java_handle_t *) obj; \
1994 c = LLNI_classinfo_unwrap(clazz); \
1995 m = (methodinfo *) methodID; \
1997 va_start(ap, methodID); \
1998 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
2004 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
2005 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
2006 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
2007 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
2008 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
2009 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
2010 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
2011 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
2014 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
2015 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
2016 jclass clazz, jmethodID methodID, \
2024 o = (java_handle_t *) obj; \
2025 c = LLNI_classinfo_unwrap(clazz); \
2026 m = (methodinfo *) methodID; \
2028 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
2033 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
2034 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
2035 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
2036 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
2037 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
2038 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
2039 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
2040 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
2043 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
2044 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
2045 jclass clazz, jmethodID methodID, \
2046 const jvalue *args) \
2048 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
2053 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
2054 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
2055 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
2056 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
2057 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
2058 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
2059 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
2060 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
2062 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2063 jclass clazz, jmethodID methodID,
2072 o = (java_handle_t *) obj;
2073 c = LLNI_classinfo_unwrap(clazz);
2074 m = (methodinfo *) methodID;
2076 va_start(ap, methodID);
2077 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2080 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2084 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2085 jclass clazz, jmethodID methodID,
2093 o = (java_handle_t *) obj;
2094 c = LLNI_classinfo_unwrap(clazz);
2095 m = (methodinfo *) methodID;
2097 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2099 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2103 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2104 jclass clazz, jmethodID methodID,
2107 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2109 return _Jv_JNI_NewLocalRef(env, NULL);
2113 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2114 jmethodID methodID, ...)
2121 o = (java_handle_t *) obj;
2122 c = LLNI_classinfo_unwrap(clazz);
2123 m = (methodinfo *) methodID;
2125 va_start(ap, methodID);
2126 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2131 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2132 jmethodID methodID, va_list args)
2138 o = (java_handle_t *) obj;
2139 c = LLNI_classinfo_unwrap(clazz);
2140 m = (methodinfo *) methodID;
2142 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2146 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2147 jmethodID methodID, const jvalue * args)
2153 o = (java_handle_t *) obj;
2154 c = LLNI_classinfo_unwrap(clazz);
2155 m = (methodinfo *) methodID;
2157 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2161 /* Accessing Fields of Objects ************************************************/
2163 /* GetFieldID ******************************************************************
2165 Returns the field ID for an instance (nonstatic) field of a
2166 class. The field is specified by its name and signature. The
2167 Get<type>Field and Set<type>Field families of accessor functions
2168 use field IDs to retrieve object fields.
2170 *******************************************************************************/
2172 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2180 STATISTICS(jniinvokation());
2182 c = LLNI_classinfo_unwrap(clazz);
2184 /* XXX NPE check? */
2186 uname = utf_new_char((char *) name);
2187 udesc = utf_new_char((char *) sig);
2189 f = class_findfield(c, uname, udesc);
2192 exceptions_throw_nosuchfielderror(c, uname);
2194 return (jfieldID) f;
2198 /* Get<type>Field Routines *****************************************************
2200 This family of accessor routines returns the value of an instance
2201 (nonstatic) field of an object. The field to access is specified by
2202 a field ID obtained by calling GetFieldID().
2204 *******************************************************************************/
2206 #define JNI_GET_FIELD(name, type, intern) \
2207 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2211 STATISTICS(jniinvokation()); \
2213 ret = GET_FIELD(obj, intern, fieldID); \
2215 return (type) ret; \
2218 JNI_GET_FIELD(Boolean, jboolean, s4)
2219 JNI_GET_FIELD(Byte, jbyte, s4)
2220 JNI_GET_FIELD(Char, jchar, s4)
2221 JNI_GET_FIELD(Short, jshort, s4)
2222 JNI_GET_FIELD(Int, jint, s4)
2223 JNI_GET_FIELD(Long, jlong, s8)
2224 JNI_GET_FIELD(Float, jfloat, float)
2225 JNI_GET_FIELD(Double, jdouble, double)
2228 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2232 STATISTICS(jniinvokation());
2234 #warning this needs to be fixed
2235 o = GET_FIELD(obj, java_handle_t*, fieldID);
2237 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2241 /* Set<type>Field Routines *****************************************************
2243 This family of accessor routines sets the value of an instance
2244 (nonstatic) field of an object. The field to access is specified by
2245 a field ID obtained by calling GetFieldID().
2247 *******************************************************************************/
2249 #define JNI_SET_FIELD(name, type, intern) \
2250 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2253 STATISTICS(jniinvokation()); \
2255 SET_FIELD(obj, intern, fieldID, value); \
2258 JNI_SET_FIELD(Boolean, jboolean, s4)
2259 JNI_SET_FIELD(Byte, jbyte, s4)
2260 JNI_SET_FIELD(Char, jchar, s4)
2261 JNI_SET_FIELD(Short, jshort, s4)
2262 JNI_SET_FIELD(Int, jint, s4)
2263 JNI_SET_FIELD(Long, jlong, s8)
2264 JNI_SET_FIELD(Float, jfloat, float)
2265 JNI_SET_FIELD(Double, jdouble, double)
2268 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2271 STATISTICS(jniinvokation());
2273 #warning this needs to be fixed
2274 SET_FIELD(obj, java_handle_t*, fieldID, value);
2278 /* Calling Static Methods *****************************************************/
2280 /* GetStaticMethodID ***********************************************************
2282 Returns the method ID for a static method of a class. The method is
2283 specified by its name and signature.
2285 GetStaticMethodID() causes an uninitialized class to be
2288 *******************************************************************************/
2290 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2298 STATISTICS(jniinvokation());
2300 c = LLNI_classinfo_unwrap(clazz);
2305 if (!(c->state & CLASS_INITIALIZED))
2306 if (!initialize_class(c))
2309 /* try to get the static method of the class */
2311 uname = utf_new_char((char *) name);
2312 udesc = utf_new_char((char *) sig);
2314 m = class_resolvemethod(c, uname, udesc);
2316 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2317 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2322 return (jmethodID) m;
2326 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2327 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2328 jmethodID methodID, ...) \
2334 m = (methodinfo *) methodID; \
2336 va_start(ap, methodID); \
2337 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2343 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2344 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2345 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2346 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2347 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2348 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2349 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2350 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2353 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2354 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2355 jmethodID methodID, va_list args) \
2360 m = (methodinfo *) methodID; \
2362 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2367 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2368 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2369 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2370 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2371 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2372 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2373 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2374 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2377 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2378 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2379 jmethodID methodID, const jvalue *args) \
2384 m = (methodinfo *) methodID; \
2386 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2391 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2392 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2393 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2394 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2395 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2396 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2397 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2398 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2401 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2402 jmethodID methodID, ...)
2408 m = (methodinfo *) methodID;
2410 va_start(ap, methodID);
2411 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2414 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2418 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2419 jmethodID methodID, va_list args)
2424 m = (methodinfo *) methodID;
2426 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2428 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2432 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2433 jmethodID methodID, const jvalue *args)
2438 m = (methodinfo *) methodID;
2440 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2442 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2446 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2447 jmethodID methodID, ...)
2452 m = (methodinfo *) methodID;
2454 va_start(ap, methodID);
2455 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2460 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2461 jmethodID methodID, va_list args)
2465 m = (methodinfo *) methodID;
2467 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2471 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2472 jmethodID methodID, const jvalue * args)
2476 m = (methodinfo *) methodID;
2478 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2482 /* Accessing Static Fields ****************************************************/
2484 /* GetStaticFieldID ************************************************************
2486 Returns the field ID for a static field of a class. The field is
2487 specified by its name and signature. The GetStatic<type>Field and
2488 SetStatic<type>Field families of accessor functions use field IDs
2489 to retrieve static fields.
2491 *******************************************************************************/
2493 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2501 STATISTICS(jniinvokation());
2503 c = LLNI_classinfo_unwrap(clazz);
2505 uname = utf_new_char((char *) name);
2506 usig = utf_new_char((char *) sig);
2508 f = class_findfield(c, uname, usig);
2511 exceptions_throw_nosuchfielderror(c, uname);
2513 return (jfieldID) f;
2517 /* GetStatic<type>Field ********************************************************
2519 This family of accessor routines returns the value of a static
2522 *******************************************************************************/
2524 #define JNI_GET_STATIC_FIELD(name, type, field) \
2525 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2531 STATISTICS(jniinvokation()); \
2533 c = LLNI_classinfo_unwrap(clazz); \
2534 f = (fieldinfo *) fieldID; \
2536 if (!(c->state & CLASS_INITIALIZED)) \
2537 if (!initialize_class(c)) \
2540 return f->value->field; \
2543 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2544 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2545 JNI_GET_STATIC_FIELD(Char, jchar, i)
2546 JNI_GET_STATIC_FIELD(Short, jshort, i)
2547 JNI_GET_STATIC_FIELD(Int, jint, i)
2548 JNI_GET_STATIC_FIELD(Long, jlong, l)
2549 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2550 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2553 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2559 STATISTICS(jniinvokation());
2561 c = LLNI_classinfo_unwrap(clazz);
2562 f = (fieldinfo *) fieldID;
2564 if (!(c->state & CLASS_INITIALIZED))
2565 if (!initialize_class(c))
2568 return _Jv_JNI_NewLocalRef(env, f->value->a);
2572 /* SetStatic<type>Field *******************************************************
2574 This family of accessor routines sets the value of a static field
2577 *******************************************************************************/
2579 #define JNI_SET_STATIC_FIELD(name, type, field) \
2580 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2587 STATISTICS(jniinvokation()); \
2589 c = LLNI_classinfo_unwrap(clazz); \
2590 f = (fieldinfo *) fieldID; \
2592 if (!(c->state & CLASS_INITIALIZED)) \
2593 if (!initialize_class(c)) \
2596 f->value->field = value; \
2599 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2600 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2601 JNI_SET_STATIC_FIELD(Char, jchar, i)
2602 JNI_SET_STATIC_FIELD(Short, jshort, i)
2603 JNI_SET_STATIC_FIELD(Int, jint, i)
2604 JNI_SET_STATIC_FIELD(Long, jlong, l)
2605 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2606 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2609 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2615 STATISTICS(jniinvokation());
2617 c = LLNI_classinfo_unwrap(clazz);
2618 f = (fieldinfo *) fieldID;
2620 if (!(c->state & CLASS_INITIALIZED))
2621 if (!initialize_class(c))
2624 f->value->a = value;
2628 /* String Operations **********************************************************/
2630 /* NewString *******************************************************************
2632 Create new java.lang.String object from an array of Unicode
2635 *******************************************************************************/
2637 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2639 java_lang_String *s;
2640 java_handle_chararray_t *a;
2643 STATISTICS(jniinvokation());
2645 s = (java_lang_String *) builtin_new(class_java_lang_String);
2646 a = builtin_newarray_char(len);
2648 /* javastring or characterarray could not be created */
2649 if ((a == NULL) || (s == NULL))
2653 for (i = 0; i < len; i++)
2654 LLNI_array_direct(a, i) = buf[i];
2656 LLNI_field_set_ref(s, value , a);
2657 LLNI_field_set_val(s, offset, 0);
2658 LLNI_field_set_val(s, count , len);
2660 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2664 static jchar emptyStringJ[]={0,0};
2666 /* GetStringLength *************************************************************
2668 Returns the length (the count of Unicode characters) of a Java
2671 *******************************************************************************/
2673 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2675 java_lang_String *s;
2678 TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
2680 s = (java_lang_String *) str;
2682 LLNI_field_get_val(s, count, len);
2688 /******************** convertes javastring to u2-array ****************************/
2690 u2 *javastring_tou2(jstring so)
2692 java_lang_String *s;
2693 java_handle_chararray_t *a;
2699 STATISTICS(jniinvokation());
2701 s = (java_lang_String *) so;
2706 LLNI_field_get_ref(s, value, a);
2711 LLNI_field_get_val(s, count, count);
2712 LLNI_field_get_val(s, offset, offset);
2714 /* allocate memory */
2716 stringbuffer = MNEW(u2, count + 1);
2720 for (i = 0; i < count; i++)
2721 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2723 /* terminate string */
2725 stringbuffer[i] = '\0';
2727 return stringbuffer;
2731 /* GetStringChars **************************************************************
2733 Returns a pointer to the array of Unicode characters of the
2734 string. This pointer is valid until ReleaseStringChars() is called.
2736 *******************************************************************************/
2738 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2742 STATISTICS(jniinvokation());
2744 jc = javastring_tou2(str);
2756 return emptyStringJ;
2760 /* ReleaseStringChars **********************************************************
2762 Informs the VM that the native code no longer needs access to
2763 chars. The chars argument is a pointer obtained from string using
2766 *******************************************************************************/
2768 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2770 java_lang_String *s;
2772 STATISTICS(jniinvokation());
2774 if (chars == emptyStringJ)
2777 s = (java_lang_String *) str;
2779 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2783 /* NewStringUTF ****************************************************************
2785 Constructs a new java.lang.String object from an array of UTF-8
2788 *******************************************************************************/
2790 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2792 java_lang_String *s;
2794 TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
2796 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2798 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2802 /****************** returns the utf8 length in bytes of a string *******************/
2804 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2806 java_lang_String *s;
2809 TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
2811 s = (java_lang_String *) string;
2813 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2819 /* GetStringUTFChars ***********************************************************
2821 Returns a pointer to an array of UTF-8 characters of the
2822 string. This array is valid until it is released by
2823 ReleaseStringUTFChars().
2825 *******************************************************************************/
2827 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2832 STATISTICS(jniinvokation());
2840 u = javastring_toutf((java_handle_t *) string, false);
2849 /* ReleaseStringUTFChars *******************************************************
2851 Informs the VM that the native code no longer needs access to
2852 utf. The utf argument is a pointer derived from string using
2853 GetStringUTFChars().
2855 *******************************************************************************/
2857 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2859 STATISTICS(jniinvokation());
2861 /* XXX we don't release utf chars right now, perhaps that should be done
2862 later. Since there is always one reference the garbage collector will
2867 /* Array Operations ***********************************************************/
2869 /* GetArrayLength **************************************************************
2871 Returns the number of elements in the array.
2873 *******************************************************************************/
2875 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2880 STATISTICS(jniinvokation());
2882 a = (java_handle_t *) array;
2884 size = LLNI_array_size(a);
2890 /* NewObjectArray **************************************************************
2892 Constructs a new array holding objects in class elementClass. All
2893 elements are initially set to initialElement.
2895 *******************************************************************************/
2897 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2898 jclass elementClass, jobject initialElement)
2902 java_handle_objectarray_t *oa;
2905 STATISTICS(jniinvokation());
2907 c = LLNI_classinfo_unwrap(elementClass);
2908 o = (java_handle_t *) initialElement;
2911 exceptions_throw_negativearraysizeexception();
2915 oa = builtin_anewarray(length, c);
2920 /* set all elements to initialElement */
2922 for (i = 0; i < length; i++)
2923 LLNI_objectarray_element_set(oa, i, o);
2925 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2929 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2932 java_handle_objectarray_t *oa;
2935 STATISTICS(jniinvokation());
2937 oa = (java_handle_objectarray_t *) array;
2939 if (index >= LLNI_array_size(oa)) {
2940 exceptions_throw_arrayindexoutofboundsexception();
2944 LLNI_objectarray_element_get(oa, index, o);
2946 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2950 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2951 jsize index, jobject val)
2953 java_handle_objectarray_t *oa;
2956 STATISTICS(jniinvokation());
2958 oa = (java_handle_objectarray_t *) array;
2959 o = (java_handle_t *) val;
2961 if (index >= LLNI_array_size(oa)) {
2962 exceptions_throw_arrayindexoutofboundsexception();
2966 /* check if the class of value is a subclass of the element class
2969 if (!builtin_canstore(oa, o))
2972 LLNI_objectarray_element_set(oa, index, o);
2976 #define JNI_NEW_ARRAY(name, type, intern) \
2977 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2979 java_handle_##intern##array_t *a; \
2981 STATISTICS(jniinvokation()); \
2984 exceptions_throw_negativearraysizeexception(); \
2988 a = builtin_newarray_##intern(len); \
2990 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2993 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2994 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2995 JNI_NEW_ARRAY(Char, jcharArray, char)
2996 JNI_NEW_ARRAY(Short, jshortArray, byte)
2997 JNI_NEW_ARRAY(Int, jintArray, int)
2998 JNI_NEW_ARRAY(Long, jlongArray, long)
2999 JNI_NEW_ARRAY(Float, jfloatArray, float)
3000 JNI_NEW_ARRAY(Double, jdoubleArray, double)
3003 /* Get<PrimitiveType>ArrayElements *********************************************
3005 A family of functions that returns the body of the primitive array.
3007 *******************************************************************************/
3009 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
3010 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
3013 java_handle_##intern##array_t *a; \
3015 STATISTICS(jniinvokation()); \
3017 a = (java_handle_##intern##array_t *) array; \
3020 *isCopy = JNI_FALSE; \
3022 return LLNI_array_data(a); \
3025 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
3026 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
3027 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
3028 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
3029 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
3030 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
3031 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
3032 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
3035 /* Release<PrimitiveType>ArrayElements *****************************************
3037 A family of functions that informs the VM that the native code no
3038 longer needs access to elems. The elems argument is a pointer
3039 derived from array using the corresponding
3040 Get<PrimitiveType>ArrayElements() function. If necessary, this
3041 function copies back all changes made to elems to the original
3044 *******************************************************************************/
3046 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
3047 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
3048 type *elems, jint mode) \
3050 java_handle_##intern##array_t *a; \
3052 STATISTICS(jniinvokation()); \
3054 a = (java_handle_##intern##array_t *) array; \
3056 if (elems != LLNI_array_data(a)) { \
3059 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3062 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3063 /* XXX TWISTI how should it be freed? */ \
3066 /* XXX TWISTI how should it be freed? */ \
3072 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3073 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3074 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3075 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3076 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3077 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3078 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3079 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3082 /* Get<PrimitiveType>ArrayRegion **********************************************
3084 A family of functions that copies a region of a primitive array
3087 *******************************************************************************/
3089 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3090 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3091 jsize start, jsize len, type *buf) \
3093 java_handle_##intern##array_t *a; \
3095 STATISTICS(jniinvokation()); \
3097 a = (java_handle_##intern##array_t *) array; \
3099 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3100 exceptions_throw_arrayindexoutofboundsexception(); \
3102 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3105 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3106 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3107 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3108 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3109 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3110 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3111 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3112 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3115 /* Set<PrimitiveType>ArrayRegion **********************************************
3117 A family of functions that copies back a region of a primitive
3118 array from a buffer.
3120 *******************************************************************************/
3122 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3123 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3124 jsize start, jsize len, const type *buf) \
3126 java_handle_##intern##array_t *a; \
3128 STATISTICS(jniinvokation()); \
3130 a = (java_handle_##intern##array_t *) array; \
3132 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3133 exceptions_throw_arrayindexoutofboundsexception(); \
3135 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3138 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3139 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3140 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3141 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3142 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3143 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3144 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3145 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3148 /* Registering Native Methods *************************************************/
3150 /* RegisterNatives *************************************************************
3152 Registers native methods with the class specified by the clazz
3153 argument. The methods parameter specifies an array of
3154 JNINativeMethod structures that contain the names, signatures, and
3155 function pointers of the native methods. The nMethods parameter
3156 specifies the number of native methods in the array.
3158 *******************************************************************************/
3160 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3161 const JNINativeMethod *methods, jint nMethods)
3165 STATISTICS(jniinvokation());
3167 c = LLNI_classinfo_unwrap(clazz);
3169 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3170 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3173 native_method_register(c->name, methods, nMethods);
3179 /* UnregisterNatives ***********************************************************
3181 Unregisters native methods of a class. The class goes back to the
3182 state before it was linked or registered with its native method
3185 This function should not be used in normal native code. Instead, it
3186 provides special programs a way to reload and relink native
3189 *******************************************************************************/
3191 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3193 STATISTICS(jniinvokation());
3195 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3197 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3203 /* Monitor Operations *********************************************************/
3205 /* MonitorEnter ****************************************************************
3207 Enters the monitor associated with the underlying Java object
3210 *******************************************************************************/
3212 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3214 STATISTICS(jniinvokation());
3217 exceptions_throw_nullpointerexception();
3221 LOCK_MONITOR_ENTER(obj);
3227 /* MonitorExit *****************************************************************
3229 The current thread must be the owner of the monitor associated with
3230 the underlying Java object referred to by obj. The thread
3231 decrements the counter indicating the number of times it has
3232 entered this monitor. If the value of the counter becomes zero, the
3233 current thread releases the monitor.
3235 *******************************************************************************/
3237 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3239 STATISTICS(jniinvokation());
3242 exceptions_throw_nullpointerexception();
3246 LOCK_MONITOR_EXIT(obj);
3252 /* JavaVM Interface ***********************************************************/
3254 /* GetJavaVM *******************************************************************
3256 Returns the Java VM interface (used in the Invocation API)
3257 associated with the current thread. The result is placed at the
3258 location pointed to by the second argument, vm.
3260 *******************************************************************************/
3262 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3264 STATISTICS(jniinvokation());
3266 *vm = (JavaVM *) _Jv_jvm;
3272 /* GetStringRegion *************************************************************
3274 Copies len number of Unicode characters beginning at offset start
3275 to the given buffer buf.
3277 Throws StringIndexOutOfBoundsException on index overflow.
3279 *******************************************************************************/
3281 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3284 java_lang_String *s;
3285 java_handle_chararray_t *ca;
3287 STATISTICS(jniinvokation());
3289 s = (java_lang_String *) str;
3290 LLNI_field_get_ref(s, value, ca);
3292 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3293 (start + len > LLNI_field_direct(s, count))) {
3294 exceptions_throw_stringindexoutofboundsexception();
3298 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3302 /* GetStringUTFRegion **********************************************************
3304 Translates len number of Unicode characters beginning at offset
3305 start into UTF-8 format and place the result in the given buffer
3308 Throws StringIndexOutOfBoundsException on index overflow.
3310 *******************************************************************************/
3312 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3313 jsize len, char *buf)
3315 java_lang_String *s;
3316 java_handle_chararray_t *ca;
3321 TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
3323 s = (java_lang_String *) str;
3324 LLNI_field_get_ref(s, value, ca);
3325 LLNI_field_get_val(s, count, count);
3326 LLNI_field_get_val(s, offset, offset);
3328 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3329 exceptions_throw_stringindexoutofboundsexception();
3333 for (i = 0; i < len; i++)
3334 buf[i] = LLNI_array_direct(ca, offset + start + i);
3340 /* GetPrimitiveArrayCritical ***************************************************
3342 Obtain a direct pointer to array elements.
3344 *******************************************************************************/
3346 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3349 java_handle_bytearray_t *ba;
3352 ba = (java_handle_bytearray_t *) array;
3354 /* do the same as Kaffe does */
3356 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3362 /* ReleasePrimitiveArrayCritical ***********************************************
3364 No specific documentation.
3366 *******************************************************************************/
3368 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3369 void *carray, jint mode)
3371 STATISTICS(jniinvokation());
3373 /* do the same as Kaffe does */
3375 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3380 /* GetStringCritical ***********************************************************
3382 The semantics of these two functions are similar to the existing
3383 Get/ReleaseStringChars functions.
3385 *******************************************************************************/
3387 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3390 STATISTICS(jniinvokation());
3392 return _Jv_JNI_GetStringChars(env, string, isCopy);
3396 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3397 const jchar *cstring)
3399 STATISTICS(jniinvokation());
3401 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3405 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3407 STATISTICS(jniinvokation());
3409 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
3415 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3417 STATISTICS(jniinvokation());
3419 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
3423 /* NewGlobalRef ****************************************************************
3425 Creates a new global reference to the object referred to by the obj
3428 *******************************************************************************/
3430 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3432 hashtable_global_ref_entry *gre;
3433 u4 key; /* hashkey */
3434 u4 slot; /* slot in hashtable */
3437 STATISTICS(jniinvokation());
3439 o = (java_handle_t *) obj;
3441 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3443 /* normally addresses are aligned to 4, 8 or 16 bytes */
3445 key = ((u4) (ptrint) obj) >> 4; /* align to 16-byte boundaries */
3446 slot = key & (hashtable_global_ref->size - 1);
3447 gre = hashtable_global_ref->ptr[slot];
3449 /* search external hash chain for the entry */
3453 /* global object found, increment the reference */
3457 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3462 gre = gre->hashlink; /* next element in external chain */
3465 /* global ref not found, create a new one */
3467 gre = NEW(hashtable_global_ref_entry);
3469 #if defined(ENABLE_GC_CACAO)
3470 /* register global ref with the GC */
3472 gc_reference_register(&(gre->o));
3478 /* insert entry into hashtable */
3480 gre->hashlink = hashtable_global_ref->ptr[slot];
3482 hashtable_global_ref->ptr[slot] = gre;
3484 /* update number of hashtable-entries */
3486 hashtable_global_ref->entries++;
3488 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3494 /* DeleteGlobalRef *************************************************************
3496 Deletes the global reference pointed to by globalRef.
3498 *******************************************************************************/
3500 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3502 hashtable_global_ref_entry *gre;
3503 hashtable_global_ref_entry *prevgre;
3504 u4 key; /* hashkey */
3505 u4 slot; /* slot in hashtable */
3508 STATISTICS(jniinvokation());
3510 o = (java_handle_t *) globalRef;
3512 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3514 /* normally addresses are aligned to 4, 8 or 16 bytes */
3516 key = ((u4) (ptrint) globalRef) >> 4; /* align to 16-byte boundaries */
3517 slot = key & (hashtable_global_ref->size - 1);
3518 gre = hashtable_global_ref->ptr[slot];
3520 /* initialize prevgre */
3524 /* search external hash chain for the entry */
3528 /* global object found, decrement the reference count */
3532 /* if reference count is 0, remove the entry */
3534 if (gre->refs == 0) {
3535 /* special handling if it's the first in the chain */
3537 if (prevgre == NULL)
3538 hashtable_global_ref->ptr[slot] = gre->hashlink;
3540 prevgre->hashlink = gre->hashlink;
3542 #if defined(ENABLE_GC_CACAO)
3543 /* unregister global ref with the GC */
3545 gc_reference_unregister(&(gre->o));
3548 FREE(gre, hashtable_global_ref_entry);
3551 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3556 prevgre = gre; /* save current pointer for removal */
3557 gre = gre->hashlink; /* next element in external chain */
3560 log_println("JNI-DeleteGlobalRef: global reference not found");
3562 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3566 /* ExceptionCheck **************************************************************
3568 Returns JNI_TRUE when there is a pending exception; otherwise,
3571 *******************************************************************************/
3573 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3577 STATISTICS(jniinvokation());
3579 o = exceptions_get_exception();
3581 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3585 /* New JNI 1.4 functions ******************************************************/
3587 /* NewDirectByteBuffer *********************************************************
3589 Allocates and returns a direct java.nio.ByteBuffer referring to the
3590 block of memory starting at the memory address address and
3591 extending capacity bytes.
3593 *******************************************************************************/
3595 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3597 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3598 java_handle_t *nbuf;
3600 # if SIZEOF_VOID_P == 8
3601 gnu_classpath_Pointer64 *paddress;
3603 gnu_classpath_Pointer32 *paddress;
3606 STATISTICS(jniinvokation());
3608 /* alocate a gnu.classpath.Pointer{32,64} object */
3610 # if SIZEOF_VOID_P == 8
3611 if (!(paddress = (gnu_classpath_Pointer64 *)
3612 builtin_new(class_gnu_classpath_Pointer64)))
3614 if (!(paddress = (gnu_classpath_Pointer32 *)
3615 builtin_new(class_gnu_classpath_Pointer32)))
3619 /* fill gnu.classpath.Pointer{32,64} with address */
3621 LLNI_field_set_val(paddress, data, (ptrint) address);
3623 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3625 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3626 (jmethodID) dbbirw_init, NULL, paddress,
3627 (jint) capacity, (jint) capacity, (jint) 0);
3629 /* add local reference and return the value */
3631 return _Jv_JNI_NewLocalRef(env, nbuf);
3633 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3635 /* keep compiler happy */
3642 /* GetDirectBufferAddress ******************************************************
3644 Fetches and returns the starting address of the memory region
3645 referenced by the given direct java.nio.Buffer.
3647 *******************************************************************************/
3649 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3651 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3652 java_nio_DirectByteBufferImpl *nbuf;
3653 # if SIZEOF_VOID_P == 8
3654 gnu_classpath_Pointer64 *paddress;
3656 gnu_classpath_Pointer32 *paddress;
3660 STATISTICS(jniinvokation());
3662 if (!builtin_instanceof(buf, class_java_nio_Buffer))
3665 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3667 # if SIZEOF_VOID_P == 8
3668 LLNI_field_get_ref(nbuf, address, paddress);
3669 /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
3671 LLNI_field_get_ref(nbuf, address, paddress);
3672 /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
3675 if (paddress == NULL)
3678 LLNI_field_get_val(paddress, data, address);
3679 /* this was the cast to avaoid warning: (void *) paddress->data */
3683 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3685 /* keep compiler happy */
3692 /* GetDirectBufferCapacity *****************************************************
3694 Fetches and returns the capacity in bytes of the memory region
3695 referenced by the given direct java.nio.Buffer.
3697 *******************************************************************************/
3699 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3701 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3703 java_nio_Buffer *nbuf;
3706 STATISTICS(jniinvokation());
3708 o = (java_handle_t *) buf;
3710 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3713 nbuf = (java_nio_Buffer *) o;
3715 LLNI_field_get_val(nbuf, cap, capacity);
3719 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3721 /* keep compiler happy */
3728 /* DestroyJavaVM ***************************************************************
3730 Unloads a Java VM and reclaims its resources. Only the main thread
3731 can unload the VM. The system waits until the main thread is only
3732 remaining user thread before it destroys the VM.
3734 *******************************************************************************/
3736 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3740 STATISTICS(jniinvokation());
3742 status = vm_destroy(vm);
3748 /* AttachCurrentThread *********************************************************
3750 Attaches the current thread to a Java VM. Returns a JNI interface
3751 pointer in the JNIEnv argument.
3753 Trying to attach a thread that is already attached is a no-op.
3755 A native thread cannot be attached simultaneously to two Java VMs.
3757 When a thread is attached to the VM, the context class loader is
3758 the bootstrap loader.
3760 *******************************************************************************/
3762 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3764 JavaVMAttachArgs *vm_aargs;
3766 #if defined(ENABLE_THREADS)
3767 if (threads_get_current_threadobject() == NULL) {
3768 vm_aargs = (JavaVMAttachArgs *) thr_args;
3770 if (vm_aargs != NULL) {
3771 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3772 (vm_aargs->version != JNI_VERSION_1_4))
3773 return JNI_EVERSION;
3776 if (!threads_attach_current_thread(vm_aargs, false))
3779 if (!localref_table_init())
3790 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3792 STATISTICS(jniinvokation());
3794 return jni_attach_current_thread(p_env, thr_args, false);
3798 /* DetachCurrentThread *********************************************************
3800 Detaches the current thread from a Java VM. All Java monitors held
3801 by this thread are released. All Java threads waiting for this
3802 thread to die are notified.
3804 In JDK 1.1, the main thread cannot be detached from the VM. It must
3805 call DestroyJavaVM to unload the entire VM.
3807 In the JDK, the main thread can be detached from the VM.
3809 The main thread, which is the thread that created the Java VM,
3810 cannot be detached from the VM. Instead, the main thread must call
3811 JNI_DestroyJavaVM() to unload the entire VM.
3813 *******************************************************************************/
3815 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3817 #if defined(ENABLE_THREADS)
3818 threadobject *thread;
3820 STATISTICS(jniinvokation());
3822 thread = threads_get_current_threadobject();
3827 if (!jni_free_localref_table())
3830 if (!threads_detach_thread(thread))
3838 /* GetEnv **********************************************************************
3840 If the current thread is not attached to the VM, sets *env to NULL,
3841 and returns JNI_EDETACHED. If the specified version is not
3842 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3843 sets *env to the appropriate interface, and returns JNI_OK.
3845 *******************************************************************************/
3847 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3849 STATISTICS(jniinvokation());
3851 #if defined(ENABLE_THREADS)
3852 if (threads_get_current_threadobject() == NULL) {
3855 return JNI_EDETACHED;
3859 /* check the JNI version */
3862 case JNI_VERSION_1_1:
3863 case JNI_VERSION_1_2:
3864 case JNI_VERSION_1_4:
3872 #if defined(ENABLE_JVMTI)
3873 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3874 == JVMTI_VERSION_INTERFACE_JVMTI) {
3876 *env = (void *) jvmti_new_environment();
3885 return JNI_EVERSION;
3889 /* AttachCurrentThreadAsDaemon *************************************************
3891 Same semantics as AttachCurrentThread, but the newly-created
3892 java.lang.Thread instance is a daemon.
3894 If the thread has already been attached via either
3895 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3896 simply sets the value pointed to by penv to the JNIEnv of the
3897 current thread. In this case neither AttachCurrentThread nor this
3898 routine have any effect on the daemon status of the thread.
3900 *******************************************************************************/
3902 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3904 STATISTICS(jniinvokation());
3906 return jni_attach_current_thread(penv, args, true);
3910 /* JNI invocation table *******************************************************/
3912 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3917 _Jv_JNI_DestroyJavaVM,
3918 _Jv_JNI_AttachCurrentThread,
3919 _Jv_JNI_DetachCurrentThread,
3921 _Jv_JNI_AttachCurrentThreadAsDaemon
3925 /* JNI function table *********************************************************/
3927 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3934 _Jv_JNI_DefineClass,
3936 _Jv_JNI_FromReflectedMethod,
3937 _Jv_JNI_FromReflectedField,
3938 _Jv_JNI_ToReflectedMethod,
3939 _Jv_JNI_GetSuperclass,
3940 _Jv_JNI_IsAssignableFrom,
3941 _Jv_JNI_ToReflectedField,
3945 _Jv_JNI_ExceptionOccurred,
3946 _Jv_JNI_ExceptionDescribe,
3947 _Jv_JNI_ExceptionClear,
3949 _Jv_JNI_PushLocalFrame,
3950 _Jv_JNI_PopLocalFrame,
3952 _Jv_JNI_NewGlobalRef,
3953 _Jv_JNI_DeleteGlobalRef,
3954 _Jv_JNI_DeleteLocalRef,
3955 _Jv_JNI_IsSameObject,
3956 _Jv_JNI_NewLocalRef,
3957 _Jv_JNI_EnsureLocalCapacity,
3959 _Jv_JNI_AllocObject,
3964 _Jv_JNI_GetObjectClass,
3965 _Jv_JNI_IsInstanceOf,
3967 _Jv_JNI_GetMethodID,
3969 _Jv_JNI_CallObjectMethod,
3970 _Jv_JNI_CallObjectMethodV,
3971 _Jv_JNI_CallObjectMethodA,
3972 _Jv_JNI_CallBooleanMethod,
3973 _Jv_JNI_CallBooleanMethodV,
3974 _Jv_JNI_CallBooleanMethodA,
3975 _Jv_JNI_CallByteMethod,
3976 _Jv_JNI_CallByteMethodV,
3977 _Jv_JNI_CallByteMethodA,
3978 _Jv_JNI_CallCharMethod,
3979 _Jv_JNI_CallCharMethodV,
3980 _Jv_JNI_CallCharMethodA,
3981 _Jv_JNI_CallShortMethod,
3982 _Jv_JNI_CallShortMethodV,
3983 _Jv_JNI_CallShortMethodA,
3984 _Jv_JNI_CallIntMethod,
3985 _Jv_JNI_CallIntMethodV,
3986 _Jv_JNI_CallIntMethodA,
3987 _Jv_JNI_CallLongMethod,
3988 _Jv_JNI_CallLongMethodV,
3989 _Jv_JNI_CallLongMethodA,
3990 _Jv_JNI_CallFloatMethod,
3991 _Jv_JNI_CallFloatMethodV,
3992 _Jv_JNI_CallFloatMethodA,
3993 _Jv_JNI_CallDoubleMethod,
3994 _Jv_JNI_CallDoubleMethodV,
3995 _Jv_JNI_CallDoubleMethodA,
3996 _Jv_JNI_CallVoidMethod,
3997 _Jv_JNI_CallVoidMethodV,
3998 _Jv_JNI_CallVoidMethodA,
4000 _Jv_JNI_CallNonvirtualObjectMethod,
4001 _Jv_JNI_CallNonvirtualObjectMethodV,
4002 _Jv_JNI_CallNonvirtualObjectMethodA,
4003 _Jv_JNI_CallNonvirtualBooleanMethod,
4004 _Jv_JNI_CallNonvirtualBooleanMethodV,
4005 _Jv_JNI_CallNonvirtualBooleanMethodA,
4006 _Jv_JNI_CallNonvirtualByteMethod,
4007 _Jv_JNI_CallNonvirtualByteMethodV,
4008 _Jv_JNI_CallNonvirtualByteMethodA,
4009 _Jv_JNI_CallNonvirtualCharMethod,
4010 _Jv_JNI_CallNonvirtualCharMethodV,
4011 _Jv_JNI_CallNonvirtualCharMethodA,
4012 _Jv_JNI_CallNonvirtualShortMethod,
4013 _Jv_JNI_CallNonvirtualShortMethodV,
4014 _Jv_JNI_CallNonvirtualShortMethodA,
4015 _Jv_JNI_CallNonvirtualIntMethod,
4016 _Jv_JNI_CallNonvirtualIntMethodV,
4017 _Jv_JNI_CallNonvirtualIntMethodA,
4018 _Jv_JNI_CallNonvirtualLongMethod,
4019 _Jv_JNI_CallNonvirtualLongMethodV,
4020 _Jv_JNI_CallNonvirtualLongMethodA,
4021 _Jv_JNI_CallNonvirtualFloatMethod,
4022 _Jv_JNI_CallNonvirtualFloatMethodV,
4023 _Jv_JNI_CallNonvirtualFloatMethodA,
4024 _Jv_JNI_CallNonvirtualDoubleMethod,
4025 _Jv_JNI_CallNonvirtualDoubleMethodV,
4026 _Jv_JNI_CallNonvirtualDoubleMethodA,
4027 _Jv_JNI_CallNonvirtualVoidMethod,
4028 _Jv_JNI_CallNonvirtualVoidMethodV,
4029 _Jv_JNI_CallNonvirtualVoidMethodA,
4033 _Jv_JNI_GetObjectField,
4034 _Jv_JNI_GetBooleanField,
4035 _Jv_JNI_GetByteField,
4036 _Jv_JNI_GetCharField,
4037 _Jv_JNI_GetShortField,
4038 _Jv_JNI_GetIntField,
4039 _Jv_JNI_GetLongField,
4040 _Jv_JNI_GetFloatField,
4041 _Jv_JNI_GetDoubleField,
4042 _Jv_JNI_SetObjectField,
4043 _Jv_JNI_SetBooleanField,
4044 _Jv_JNI_SetByteField,
4045 _Jv_JNI_SetCharField,
4046 _Jv_JNI_SetShortField,
4047 _Jv_JNI_SetIntField,
4048 _Jv_JNI_SetLongField,
4049 _Jv_JNI_SetFloatField,
4050 _Jv_JNI_SetDoubleField,
4052 _Jv_JNI_GetStaticMethodID,
4054 _Jv_JNI_CallStaticObjectMethod,
4055 _Jv_JNI_CallStaticObjectMethodV,
4056 _Jv_JNI_CallStaticObjectMethodA,
4057 _Jv_JNI_CallStaticBooleanMethod,
4058 _Jv_JNI_CallStaticBooleanMethodV,
4059 _Jv_JNI_CallStaticBooleanMethodA,
4060 _Jv_JNI_CallStaticByteMethod,
4061 _Jv_JNI_CallStaticByteMethodV,
4062 _Jv_JNI_CallStaticByteMethodA,
4063 _Jv_JNI_CallStaticCharMethod,
4064 _Jv_JNI_CallStaticCharMethodV,
4065 _Jv_JNI_CallStaticCharMethodA,
4066 _Jv_JNI_CallStaticShortMethod,
4067 _Jv_JNI_CallStaticShortMethodV,
4068 _Jv_JNI_CallStaticShortMethodA,
4069 _Jv_JNI_CallStaticIntMethod,
4070 _Jv_JNI_CallStaticIntMethodV,
4071 _Jv_JNI_CallStaticIntMethodA,
4072 _Jv_JNI_CallStaticLongMethod,
4073 _Jv_JNI_CallStaticLongMethodV,
4074 _Jv_JNI_CallStaticLongMethodA,
4075 _Jv_JNI_CallStaticFloatMethod,
4076 _Jv_JNI_CallStaticFloatMethodV,
4077 _Jv_JNI_CallStaticFloatMethodA,
4078 _Jv_JNI_CallStaticDoubleMethod,
4079 _Jv_JNI_CallStaticDoubleMethodV,
4080 _Jv_JNI_CallStaticDoubleMethodA,
4081 _Jv_JNI_CallStaticVoidMethod,
4082 _Jv_JNI_CallStaticVoidMethodV,
4083 _Jv_JNI_CallStaticVoidMethodA,
4085 _Jv_JNI_GetStaticFieldID,
4087 _Jv_JNI_GetStaticObjectField,
4088 _Jv_JNI_GetStaticBooleanField,
4089 _Jv_JNI_GetStaticByteField,
4090 _Jv_JNI_GetStaticCharField,
4091 _Jv_JNI_GetStaticShortField,
4092 _Jv_JNI_GetStaticIntField,
4093 _Jv_JNI_GetStaticLongField,
4094 _Jv_JNI_GetStaticFloatField,
4095 _Jv_JNI_GetStaticDoubleField,
4096 _Jv_JNI_SetStaticObjectField,
4097 _Jv_JNI_SetStaticBooleanField,
4098 _Jv_JNI_SetStaticByteField,
4099 _Jv_JNI_SetStaticCharField,
4100 _Jv_JNI_SetStaticShortField,
4101 _Jv_JNI_SetStaticIntField,
4102 _Jv_JNI_SetStaticLongField,
4103 _Jv_JNI_SetStaticFloatField,
4104 _Jv_JNI_SetStaticDoubleField,
4107 _Jv_JNI_GetStringLength,
4108 _Jv_JNI_GetStringChars,
4109 _Jv_JNI_ReleaseStringChars,
4111 _Jv_JNI_NewStringUTF,
4112 _Jv_JNI_GetStringUTFLength,
4113 _Jv_JNI_GetStringUTFChars,
4114 _Jv_JNI_ReleaseStringUTFChars,
4116 _Jv_JNI_GetArrayLength,
4118 _Jv_JNI_NewObjectArray,
4119 _Jv_JNI_GetObjectArrayElement,
4120 _Jv_JNI_SetObjectArrayElement,
4122 _Jv_JNI_NewBooleanArray,
4123 _Jv_JNI_NewByteArray,
4124 _Jv_JNI_NewCharArray,
4125 _Jv_JNI_NewShortArray,
4126 _Jv_JNI_NewIntArray,
4127 _Jv_JNI_NewLongArray,
4128 _Jv_JNI_NewFloatArray,
4129 _Jv_JNI_NewDoubleArray,
4131 _Jv_JNI_GetBooleanArrayElements,
4132 _Jv_JNI_GetByteArrayElements,
4133 _Jv_JNI_GetCharArrayElements,
4134 _Jv_JNI_GetShortArrayElements,
4135 _Jv_JNI_GetIntArrayElements,
4136 _Jv_JNI_GetLongArrayElements,
4137 _Jv_JNI_GetFloatArrayElements,
4138 _Jv_JNI_GetDoubleArrayElements,
4140 _Jv_JNI_ReleaseBooleanArrayElements,
4141 _Jv_JNI_ReleaseByteArrayElements,
4142 _Jv_JNI_ReleaseCharArrayElements,
4143 _Jv_JNI_ReleaseShortArrayElements,
4144 _Jv_JNI_ReleaseIntArrayElements,
4145 _Jv_JNI_ReleaseLongArrayElements,
4146 _Jv_JNI_ReleaseFloatArrayElements,
4147 _Jv_JNI_ReleaseDoubleArrayElements,
4149 _Jv_JNI_GetBooleanArrayRegion,
4150 _Jv_JNI_GetByteArrayRegion,
4151 _Jv_JNI_GetCharArrayRegion,
4152 _Jv_JNI_GetShortArrayRegion,
4153 _Jv_JNI_GetIntArrayRegion,
4154 _Jv_JNI_GetLongArrayRegion,
4155 _Jv_JNI_GetFloatArrayRegion,
4156 _Jv_JNI_GetDoubleArrayRegion,
4157 _Jv_JNI_SetBooleanArrayRegion,
4158 _Jv_JNI_SetByteArrayRegion,
4159 _Jv_JNI_SetCharArrayRegion,
4160 _Jv_JNI_SetShortArrayRegion,
4161 _Jv_JNI_SetIntArrayRegion,
4162 _Jv_JNI_SetLongArrayRegion,
4163 _Jv_JNI_SetFloatArrayRegion,
4164 _Jv_JNI_SetDoubleArrayRegion,
4166 _Jv_JNI_RegisterNatives,
4167 _Jv_JNI_UnregisterNatives,
4169 _Jv_JNI_MonitorEnter,
4170 _Jv_JNI_MonitorExit,
4174 /* new JNI 1.2 functions */
4176 _Jv_JNI_GetStringRegion,
4177 _Jv_JNI_GetStringUTFRegion,
4179 _Jv_JNI_GetPrimitiveArrayCritical,
4180 _Jv_JNI_ReleasePrimitiveArrayCritical,
4182 _Jv_JNI_GetStringCritical,
4183 _Jv_JNI_ReleaseStringCritical,
4185 _Jv_JNI_NewWeakGlobalRef,
4186 _Jv_JNI_DeleteWeakGlobalRef,
4188 _Jv_JNI_ExceptionCheck,
4190 /* new JNI 1.4 functions */
4192 _Jv_JNI_NewDirectByteBuffer,
4193 _Jv_JNI_GetDirectBufferAddress,
4194 _Jv_JNI_GetDirectBufferCapacity
4198 /* Invocation API Functions ***************************************************/
4200 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4202 Returns a default configuration for the Java VM.
4204 *******************************************************************************/
4206 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4208 JavaVMInitArgs *_vm_args;
4210 _vm_args = (JavaVMInitArgs *) vm_args;
4212 /* GNU classpath currently supports JNI 1.2 */
4214 switch (_vm_args->version) {
4215 case JNI_VERSION_1_1:
4216 _vm_args->version = JNI_VERSION_1_1;
4219 case JNI_VERSION_1_2:
4220 case JNI_VERSION_1_4:
4221 _vm_args->ignoreUnrecognized = JNI_FALSE;
4222 _vm_args->options = NULL;
4223 _vm_args->nOptions = 0;
4234 /* JNI_GetCreatedJavaVMs *******************************************************
4236 Returns all Java VMs that have been created. Pointers to VMs are written in
4237 the buffer vmBuf in the order they are created. At most bufLen number of
4238 entries will be written. The total number of created VMs is returned in
4241 *******************************************************************************/
4243 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4245 TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
4250 /* We currently only support 1 VM running. */
4252 vmBuf[0] = (JavaVM *) _Jv_jvm;
4259 /* JNI_CreateJavaVM ************************************************************
4261 Loads and initializes a Java VM. The current thread becomes the main thread.
4262 Sets the env argument to the JNI interface pointer of the main thread.
4264 *******************************************************************************/
4266 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4268 TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
4270 /* actually create the JVM */
4272 if (!vm_createjvm(p_vm, p_env, vm_args))
4280 * These are local overrides for various environment variables in Emacs.
4281 * Please do not remove this and leave it at the end of the file, where
4282 * Emacs will automagically detect them.
4283 * ---------------------------------------------------------------------
4286 * indent-tabs-mode: t
4290 * vim:noexpandtab:sw=4:ts=4: