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 8170 2007-06-30 14:03:18Z twisti $
38 #include "mm/gc-common.h"
39 #include "mm/memory.h"
40 #include "native/jni.h"
41 #include "native/native.h"
43 #if defined(ENABLE_JAVASE)
44 # if defined(WITH_CLASSPATH_GNU)
45 # include "native/include/gnu_classpath_Pointer.h"
47 # if SIZEOF_VOID_P == 8
48 # include "native/include/gnu_classpath_Pointer64.h"
50 # include "native/include/gnu_classpath_Pointer32.h"
55 #include "native/include/java_lang_Object.h"
56 #include "native/include/java_lang_Byte.h"
57 #include "native/include/java_lang_Character.h"
58 #include "native/include/java_lang_Short.h"
59 #include "native/include/java_lang_Integer.h"
60 #include "native/include/java_lang_Boolean.h"
61 #include "native/include/java_lang_Long.h"
62 #include "native/include/java_lang_Float.h"
63 #include "native/include/java_lang_Double.h"
64 #include "native/include/java_lang_String.h"
65 #include "native/include/java_lang_Throwable.h"
67 #if defined(ENABLE_JAVASE)
68 # if defined(WITH_CLASSPATH_SUN)
69 # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
72 # include "native/include/java_lang_ClassLoader.h"
74 # include "native/include/java_lang_reflect_Constructor.h"
75 # include "native/include/java_lang_reflect_Field.h"
76 # include "native/include/java_lang_reflect_Method.h"
78 # include "native/include/java_nio_Buffer.h"
80 # if defined(WITH_CLASSPATH_GNU)
81 # include "native/include/java_nio_DirectByteBufferImpl.h"
85 #if defined(ENABLE_JVMTI)
86 # include "native/jvmti/cacaodbg.h"
89 #include "native/vm/java_lang_Class.h"
91 #if defined(ENABLE_JAVASE)
92 # include "native/vm/java_lang_ClassLoader.h"
93 # include "native/vm/reflect.h"
96 #include "threads/lock-common.h"
97 #include "threads/threads-common.h"
99 #include "toolbox/logging.h"
101 #include "vm/builtin.h"
102 #include "vm/exceptions.h"
103 #include "vm/global.h"
104 #include "vm/initialize.h"
105 #include "vm/resolve.h"
106 #include "vm/stringlocal.h"
109 #include "vm/jit/asmpart.h"
110 #include "vm/jit/jit.h"
111 #include "vm/jit/stacktrace.h"
113 #include "vmcore/loader.h"
114 #include "vmcore/options.h"
115 #include "vmcore/primitive.h"
116 #include "vmcore/statistics.h"
119 /* global variables ***********************************************************/
121 /* global reference table *****************************************************/
123 /* hashsize must be power of 2 */
125 #define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
127 static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
130 /* direct buffer stuff ********************************************************/
132 #if defined(ENABLE_JAVASE)
133 static classinfo *class_java_nio_Buffer;
134 static classinfo *class_java_nio_DirectByteBufferImpl;
135 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
137 # if defined(WITH_CLASSPATH_GNU)
138 # if SIZEOF_VOID_P == 8
139 static classinfo *class_gnu_classpath_Pointer64;
141 static classinfo *class_gnu_classpath_Pointer32;
145 static methodinfo *dbbirw_init;
149 /* local reference table ******************************************************/
151 #if !defined(ENABLE_THREADS)
152 localref_table *_no_threads_localref_table;
156 /* accessing instance fields macros *******************************************/
158 #define SET_FIELD(o,type,f,value) \
159 *((type *) ((ptrint) (o) + (ptrint) ((fieldinfo *) (f))->offset)) = (type) (value)
161 #define GET_FIELD(o,type,f) \
162 *((type *) ((ptrint) (o) + (ptrint) ((fieldinfo *) (f))->offset))
165 /* some forward declarations **************************************************/
167 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
168 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity);
171 /* jni_init ********************************************************************
173 Initialize the JNI subsystem.
175 *******************************************************************************/
179 /* create global ref hashtable */
181 hashtable_global_ref = NEW(hashtable);
183 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
186 #if defined(ENABLE_JAVASE)
187 /* direct buffer stuff */
189 if (!(class_java_nio_Buffer =
190 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
191 !link_class(class_java_nio_Buffer))
194 # if defined(WITH_CLASSPATH_GNU)
195 if (!(class_java_nio_DirectByteBufferImpl =
196 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
197 !link_class(class_java_nio_DirectByteBufferImpl))
200 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
201 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
202 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
206 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
208 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
211 # if SIZEOF_VOID_P == 8
212 if (!(class_gnu_classpath_Pointer64 =
213 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
214 !link_class(class_gnu_classpath_Pointer64))
217 if (!(class_gnu_classpath_Pointer32 =
218 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
219 !link_class(class_gnu_classpath_Pointer32))
223 #endif /* defined(ENABLE_JAVASE) */
229 /* jni_init_localref_table *****************************************************
231 Initializes the local references table of the current thread.
233 *******************************************************************************/
235 bool jni_init_localref_table(void)
239 lrt = GCNEW(localref_table);
244 lrt->capacity = LOCALREFTABLE_CAPACITY;
246 lrt->localframes = 1;
247 lrt->prev = LOCALREFTABLE;
249 /* clear the references array (memset is faster then a for-loop) */
251 MSET(lrt->refs, 0, java_objectheader*, LOCALREFTABLE_CAPACITY);
259 /* _Jv_jni_CallObjectMethod ****************************************************
261 Internal function to call Java Object methods.
263 *******************************************************************************/
265 static java_objectheader *_Jv_jni_CallObjectMethod(java_objectheader *o,
267 methodinfo *m, va_list ap)
270 java_objectheader *ro;
272 STATISTICS(jniinvokation());
275 exceptions_throw_nullpointerexception();
279 /* Class initialization is done by the JIT compiler. This is ok
280 since a static method always belongs to the declaring class. */
282 if (m->flags & ACC_STATIC) {
283 /* For static methods we reset the object. */
288 /* for convenience */
293 /* For instance methods we make a virtual function table lookup. */
295 resm = method_vftbl_lookup(vftbl, m);
298 STATISTICS(jnicallXmethodnvokation());
300 ro = vm_call_method_valist(resm, o, ap);
306 /* _Jv_jni_CallObjectMethodA ***************************************************
308 Internal function to call Java Object methods.
310 *******************************************************************************/
312 static java_objectheader *_Jv_jni_CallObjectMethodA(java_objectheader *o,
318 java_objectheader *ro;
320 STATISTICS(jniinvokation());
323 exceptions_throw_nullpointerexception();
327 /* Class initialization is done by the JIT compiler. This is ok
328 since a static method always belongs to the declaring class. */
330 if (m->flags & ACC_STATIC) {
331 /* For static methods we reset the object. */
336 /* for convenience */
341 /* For instance methods we make a virtual function table lookup. */
343 resm = method_vftbl_lookup(vftbl, m);
346 STATISTICS(jnicallXmethodnvokation());
348 ro = vm_call_method_jvalue(resm, o, args);
354 /* _Jv_jni_CallIntMethod *******************************************************
356 Internal function to call Java integer class methods (boolean,
357 byte, char, short, int).
359 *******************************************************************************/
361 static jint _Jv_jni_CallIntMethod(java_objectheader *o, vftbl_t *vftbl,
362 methodinfo *m, va_list ap)
367 STATISTICS(jniinvokation());
370 exceptions_throw_nullpointerexception();
374 /* Class initialization is done by the JIT compiler. This is ok
375 since a static method always belongs to the declaring class. */
377 if (m->flags & ACC_STATIC) {
378 /* For static methods we reset the object. */
383 /* for convenience */
388 /* For instance methods we make a virtual function table lookup. */
390 resm = method_vftbl_lookup(vftbl, m);
393 STATISTICS(jnicallXmethodnvokation());
395 i = vm_call_method_int_valist(resm, o, ap);
401 /* _Jv_jni_CallIntMethodA ******************************************************
403 Internal function to call Java integer class methods (boolean,
404 byte, char, short, int).
406 *******************************************************************************/
408 static jint _Jv_jni_CallIntMethodA(java_objectheader *o, vftbl_t *vftbl,
409 methodinfo *m, const jvalue *args)
414 STATISTICS(jniinvokation());
417 exceptions_throw_nullpointerexception();
421 /* Class initialization is done by the JIT compiler. This is ok
422 since a static method always belongs to the declaring class. */
424 if (m->flags & ACC_STATIC) {
425 /* For static methods we reset the object. */
430 /* for convenience */
435 /* For instance methods we make a virtual function table lookup. */
437 resm = method_vftbl_lookup(vftbl, m);
440 STATISTICS(jnicallXmethodnvokation());
442 i = vm_call_method_int_jvalue(resm, o, args);
448 /* _Jv_jni_CallLongMethod ******************************************************
450 Internal function to call Java long methods.
452 *******************************************************************************/
454 static jlong _Jv_jni_CallLongMethod(java_objectheader *o, vftbl_t *vftbl,
455 methodinfo *m, va_list ap)
460 STATISTICS(jniinvokation());
463 exceptions_throw_nullpointerexception();
467 /* Class initialization is done by the JIT compiler. This is ok
468 since a static method always belongs to the declaring class. */
470 if (m->flags & ACC_STATIC) {
471 /* For static methods we reset the object. */
476 /* for convenience */
481 /* For instance methods we make a virtual function table lookup. */
483 resm = method_vftbl_lookup(vftbl, m);
486 STATISTICS(jnicallXmethodnvokation());
488 l = vm_call_method_long_valist(resm, o, ap);
494 /* _Jv_jni_CallLongMethodA *****************************************************
496 Internal function to call Java long methods.
498 *******************************************************************************/
500 static jlong _Jv_jni_CallLongMethodA(java_objectheader *o, vftbl_t *vftbl,
501 methodinfo *m, const jvalue *args)
506 STATISTICS(jniinvokation());
509 exceptions_throw_nullpointerexception();
513 /* Class initialization is done by the JIT compiler. This is ok
514 since a static method always belongs to the declaring class. */
516 if (m->flags & ACC_STATIC) {
517 /* For static methods we reset the object. */
522 /* for convenience */
527 /* For instance methods we make a virtual function table lookup. */
529 resm = method_vftbl_lookup(vftbl, m);
532 STATISTICS(jnicallXmethodnvokation());
534 l = vm_call_method_long_jvalue(resm, o, args);
540 /* _Jv_jni_CallFloatMethod *****************************************************
542 Internal function to call Java float methods.
544 *******************************************************************************/
546 static jfloat _Jv_jni_CallFloatMethod(java_objectheader *o, vftbl_t *vftbl,
547 methodinfo *m, va_list ap)
552 /* Class initialization is done by the JIT compiler. This is ok
553 since a static method always belongs to the declaring class. */
555 if (m->flags & ACC_STATIC) {
556 /* For static methods we reset the object. */
561 /* for convenience */
566 /* For instance methods we make a virtual function table lookup. */
568 resm = method_vftbl_lookup(vftbl, m);
571 STATISTICS(jnicallXmethodnvokation());
573 f = vm_call_method_float_valist(resm, o, ap);
579 /* _Jv_jni_CallFloatMethodA ****************************************************
581 Internal function to call Java float methods.
583 *******************************************************************************/
585 static jfloat _Jv_jni_CallFloatMethodA(java_objectheader *o, vftbl_t *vftbl,
586 methodinfo *m, const jvalue *args)
591 /* Class initialization is done by the JIT compiler. This is ok
592 since a static method always belongs to the declaring class. */
594 if (m->flags & ACC_STATIC) {
595 /* For static methods we reset the object. */
600 /* for convenience */
605 /* For instance methods we make a virtual function table lookup. */
607 resm = method_vftbl_lookup(vftbl, m);
610 STATISTICS(jnicallXmethodnvokation());
612 f = vm_call_method_float_jvalue(resm, o, args);
618 /* _Jv_jni_CallDoubleMethod ****************************************************
620 Internal function to call Java double methods.
622 *******************************************************************************/
624 static jdouble _Jv_jni_CallDoubleMethod(java_objectheader *o, vftbl_t *vftbl,
625 methodinfo *m, va_list ap)
630 /* Class initialization is done by the JIT compiler. This is ok
631 since a static method always belongs to the declaring class. */
633 if (m->flags & ACC_STATIC) {
634 /* For static methods we reset the object. */
639 /* for convenience */
644 /* For instance methods we make a virtual function table lookup. */
646 resm = method_vftbl_lookup(vftbl, m);
649 d = vm_call_method_double_valist(resm, o, ap);
655 /* _Jv_jni_CallDoubleMethodA ***************************************************
657 Internal function to call Java double methods.
659 *******************************************************************************/
661 static jdouble _Jv_jni_CallDoubleMethodA(java_objectheader *o, vftbl_t *vftbl,
662 methodinfo *m, const jvalue *args)
667 /* Class initialization is done by the JIT compiler. This is ok
668 since a static method always belongs to the declaring class. */
670 if (m->flags & ACC_STATIC) {
671 /* For static methods we reset the object. */
676 /* for convenience */
681 /* For instance methods we make a virtual function table lookup. */
683 resm = method_vftbl_lookup(vftbl, m);
686 d = vm_call_method_double_jvalue(resm, o, args);
692 /* _Jv_jni_CallVoidMethod ******************************************************
694 Internal function to call Java void methods.
696 *******************************************************************************/
698 static void _Jv_jni_CallVoidMethod(java_objectheader *o, vftbl_t *vftbl,
699 methodinfo *m, va_list ap)
704 exceptions_throw_nullpointerexception();
708 /* Class initialization is done by the JIT compiler. This is ok
709 since a static method always belongs to the declaring class. */
711 if (m->flags & ACC_STATIC) {
712 /* For static methods we reset the object. */
717 /* for convenience */
722 /* For instance methods we make a virtual function table lookup. */
724 resm = method_vftbl_lookup(vftbl, m);
727 STATISTICS(jnicallXmethodnvokation());
729 (void) vm_call_method_valist(resm, o, ap);
733 /* _Jv_jni_CallVoidMethodA *****************************************************
735 Internal function to call Java void methods.
737 *******************************************************************************/
739 static void _Jv_jni_CallVoidMethodA(java_objectheader *o, vftbl_t *vftbl,
740 methodinfo *m, const jvalue *args)
745 exceptions_throw_nullpointerexception();
749 /* Class initialization is done by the JIT compiler. This is ok
750 since a static method always belongs to the declaring class. */
752 if (m->flags & ACC_STATIC) {
753 /* For static methods we reset the object. */
758 /* for convenience */
763 /* For instance methods we make a virtual function table lookup. */
765 resm = method_vftbl_lookup(vftbl, m);
768 STATISTICS(jnicallXmethodnvokation());
770 (void) vm_call_method_jvalue(resm, o, args);
774 /* _Jv_jni_invokeNative ********************************************************
776 Invoke a method on the given object with the given arguments.
778 For instance methods OBJ must be != NULL and the method is looked up
779 in the vftbl of the object.
781 For static methods, OBJ is ignored.
783 *******************************************************************************/
785 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) \
786 && !defined(__M68K__) && !defined(__ARM__) && !defined(__SPARC_64__)
787 java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
788 java_objectarray *params)
792 java_objectheader *ro;
795 java_objectheader *xptr;
798 exceptions_throw_nullpointerexception();
802 argcount = m->parseddesc->paramcount;
803 paramcount = argcount;
805 /* if method is non-static, remove the `this' pointer */
807 if (!(m->flags & ACC_STATIC))
810 /* For instance methods the object has to be an instance of the
811 class the method belongs to. For static methods the obj
812 parameter is ignored. */
814 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
815 exceptions_throw_illegalargumentexception();
819 /* check if we got the right number of arguments */
821 if (((params == NULL) && (paramcount != 0)) ||
822 (params && (params->header.size != paramcount)))
824 exceptions_throw_illegalargumentexception();
828 /* for instance methods we need an object */
830 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
831 /* XXX not sure if that is the correct exception */
832 exceptions_throw_nullpointerexception();
836 /* for static methods, zero object to make subsequent code simpler */
837 if (m->flags & ACC_STATIC)
841 /* for instance methods we must do a vftbl lookup */
842 resm = method_vftbl_lookup(o->vftbl, m);
845 /* for static methods, just for convenience */
849 vmargs = MNEW(vm_arg, argcount);
851 if (!vm_vmargs_from_objectarray(resm, o, vmargs, params)) {
852 MFREE(vmargs, vm_arg, argcount);
856 switch (resm->parseddesc->returntype.decltype) {
858 (void) vm_call_method_vmarg(resm, argcount, vmargs);
863 case PRIMITIVETYPE_BOOLEAN: {
865 java_lang_Boolean *bo;
867 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
869 ro = builtin_new(class_java_lang_Boolean);
871 /* setting the value of the object direct */
873 bo = (java_lang_Boolean *) ro;
878 case PRIMITIVETYPE_BYTE: {
882 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
884 ro = builtin_new(class_java_lang_Byte);
886 /* setting the value of the object direct */
888 bo = (java_lang_Byte *) ro;
893 case PRIMITIVETYPE_CHAR: {
895 java_lang_Character *co;
897 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
899 ro = builtin_new(class_java_lang_Character);
901 /* setting the value of the object direct */
903 co = (java_lang_Character *) ro;
908 case PRIMITIVETYPE_SHORT: {
912 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
914 ro = builtin_new(class_java_lang_Short);
916 /* setting the value of the object direct */
918 so = (java_lang_Short *) ro;
923 case PRIMITIVETYPE_INT: {
925 java_lang_Integer *io;
927 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
929 ro = builtin_new(class_java_lang_Integer);
931 /* setting the value of the object direct */
933 io = (java_lang_Integer *) ro;
938 case PRIMITIVETYPE_LONG: {
942 l = vm_call_method_long_vmarg(resm, argcount, vmargs);
944 ro = builtin_new(class_java_lang_Long);
946 /* setting the value of the object direct */
948 lo = (java_lang_Long *) ro;
953 case PRIMITIVETYPE_FLOAT: {
957 f = vm_call_method_float_vmarg(resm, argcount, vmargs);
959 ro = builtin_new(class_java_lang_Float);
961 /* setting the value of the object direct */
963 fo = (java_lang_Float *) ro;
968 case PRIMITIVETYPE_DOUBLE: {
970 java_lang_Double *_do;
972 d = vm_call_method_double_vmarg(resm, argcount, vmargs);
974 ro = builtin_new(class_java_lang_Double);
976 /* setting the value of the object direct */
978 _do = (java_lang_Double *) ro;
984 ro = vm_call_method_vmarg(resm, argcount, vmargs);
988 /* if this happens the exception has already been set by
989 fill_callblock_from_objectarray */
991 MFREE(vmargs, vm_arg, argcount);
996 MFREE(vmargs, vm_arg, argcount);
998 xptr = exceptions_get_exception();
1001 /* clear exception pointer, we are calling JIT code again */
1003 exceptions_clear_exception();
1005 exceptions_throw_invocationtargetexception(xptr);
1011 java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
1012 java_objectarray *params)
1015 java_objectheader *ro;
1018 java_objectheader *xptr;
1023 exceptions_throw_nullpointerexception();
1027 argcount = m->parseddesc->paramcount;
1028 paramcount = argcount;
1030 /* if method is non-static, remove the `this' pointer */
1032 if (!(m->flags & ACC_STATIC))
1035 /* For instance methods the object has to be an instance of the
1036 class the method belongs to. For static methods the obj
1037 parameter is ignored. */
1039 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
1040 exceptions_throw_illegalargumentexception();
1044 /* check if we got the right number of arguments */
1046 if (((params == NULL) && (paramcount != 0)) ||
1047 (params && (params->header.size != paramcount)))
1049 exceptions_throw_illegalargumentexception();
1053 /* for instance methods we need an object */
1055 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
1056 /* XXX not sure if that is the correct exception */
1057 exceptions_throw_nullpointerexception();
1061 /* for static methods, zero object to make subsequent code simpler */
1062 if (m->flags & ACC_STATIC)
1066 /* for instance methods we must do a vftbl lookup */
1067 resm = method_vftbl_lookup(o->vftbl, m);
1070 /* for static methods, just for convenience */
1074 /* mark start of dump memory area */
1076 dumpsize = dump_size();
1078 /* fill the argument array from a object-array */
1080 array = vm_array_from_objectarray(resm, o, params);
1082 if (array == NULL) {
1083 /* release dump area */
1085 dump_release(dumpsize);
1090 switch (resm->parseddesc->returntype.decltype) {
1092 (void) vm_call_array(resm, array);
1097 case PRIMITIVETYPE_BOOLEAN: {
1099 java_lang_Boolean *bo;
1101 i = vm_call_int_array(resm, array);
1103 ro = builtin_new(class_java_lang_Boolean);
1105 /* setting the value of the object direct */
1107 bo = (java_lang_Boolean *) ro;
1112 case PRIMITIVETYPE_BYTE: {
1116 i = vm_call_int_array(resm, array);
1118 ro = builtin_new(class_java_lang_Byte);
1120 /* setting the value of the object direct */
1122 bo = (java_lang_Byte *) ro;
1127 case PRIMITIVETYPE_CHAR: {
1129 java_lang_Character *co;
1131 i = vm_call_int_array(resm, array);
1133 ro = builtin_new(class_java_lang_Character);
1135 /* setting the value of the object direct */
1137 co = (java_lang_Character *) ro;
1142 case PRIMITIVETYPE_SHORT: {
1144 java_lang_Short *so;
1146 i = vm_call_int_array(resm, array);
1148 ro = builtin_new(class_java_lang_Short);
1150 /* setting the value of the object direct */
1152 so = (java_lang_Short *) ro;
1157 case PRIMITIVETYPE_INT: {
1159 java_lang_Integer *io;
1161 i = vm_call_int_array(resm, array);
1163 ro = builtin_new(class_java_lang_Integer);
1165 /* setting the value of the object direct */
1167 io = (java_lang_Integer *) ro;
1172 case PRIMITIVETYPE_LONG: {
1176 l = vm_call_long_array(resm, array);
1178 ro = builtin_new(class_java_lang_Long);
1180 /* setting the value of the object direct */
1182 lo = (java_lang_Long *) ro;
1187 case PRIMITIVETYPE_FLOAT: {
1189 java_lang_Float *fo;
1191 f = vm_call_float_array(resm, array);
1193 ro = builtin_new(class_java_lang_Float);
1195 /* setting the value of the object direct */
1197 fo = (java_lang_Float *) ro;
1202 case PRIMITIVETYPE_DOUBLE: {
1204 java_lang_Double *_do;
1206 d = vm_call_double_array(resm, array);
1208 ro = builtin_new(class_java_lang_Double);
1210 /* setting the value of the object direct */
1212 _do = (java_lang_Double *) ro;
1218 ro = vm_call_array(resm, array);
1222 /* if this happens the exception has already been set by
1223 fill_callblock_from_objectarray */
1225 /* release dump area */
1227 dump_release(dumpsize);
1232 xptr = exceptions_get_exception();
1235 /* clear exception pointer, we are calling JIT code again */
1237 exceptions_clear_exception();
1239 exceptions_throw_invocationtargetexception(xptr);
1242 /* release dump area */
1244 dump_release(dumpsize);
1251 /* GetVersion ******************************************************************
1253 Returns the major version number in the higher 16 bits and the
1254 minor version number in the lower 16 bits.
1256 *******************************************************************************/
1258 jint _Jv_JNI_GetVersion(JNIEnv *env)
1260 STATISTICS(jniinvokation());
1262 /* we support JNI 1.4 */
1264 return JNI_VERSION_1_4;
1268 /* Class Operations ***********************************************************/
1270 /* DefineClass *****************************************************************
1272 Loads a class from a buffer of raw class data. The buffer
1273 containing the raw class data is not referenced by the VM after the
1274 DefineClass call returns, and it may be discarded if desired.
1276 *******************************************************************************/
1278 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
1279 const jbyte *buf, jsize bufLen)
1281 #if defined(ENABLE_JAVASE)
1282 java_lang_ClassLoader *cl;
1283 java_lang_String *s;
1287 STATISTICS(jniinvokation());
1289 cl = (java_lang_ClassLoader *) loader;
1290 s = (java_lang_String *) javastring_new_from_utf_string(name);
1291 ba = (java_bytearray *) buf;
1293 c = (jclass) _Jv_java_lang_ClassLoader_defineClass(cl, s, ba, 0, bufLen,
1296 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1298 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
1300 /* keep compiler happy */
1307 /* FindClass *******************************************************************
1309 This function loads a locally-defined class. It searches the
1310 directories and zip files specified by the CLASSPATH environment
1311 variable for the class with the specified name.
1313 *******************************************************************************/
1315 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
1317 #if defined(ENABLE_JAVASE)
1322 STATISTICS(jniinvokation());
1324 u = utf_new_char_classname((char *) name);
1326 /* Check stacktrace for classloader, if one found use it,
1327 otherwise use the system classloader. */
1329 /* Quote from the JNI documentation:
1331 In the Java 2 Platform, FindClass locates the class loader
1332 associated with the current native method. If the native code
1333 belongs to a system class, no class loader will be
1334 involved. Otherwise, the proper class loader will be invoked to
1335 load and link the named class. When FindClass is called through
1336 the Invocation Interface, there is no current native method or
1337 its associated class loader. In that case, the result of
1338 ClassLoader.getBaseClassLoader is used." */
1340 cc = stacktrace_getCurrentClass();
1343 c = load_class_from_sysloader(u);
1345 c = load_class_from_classloader(u, cc->classloader);
1353 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1355 vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1357 /* keep compiler happy */
1364 /* GetSuperclass ***************************************************************
1366 If clazz represents any class other than the class Object, then
1367 this function returns the object that represents the superclass of
1368 the class specified by clazz.
1370 *******************************************************************************/
1372 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1376 STATISTICS(jniinvokation());
1378 c = ((classinfo *) sub)->super.cls;
1383 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1387 /* IsAssignableFrom ************************************************************
1389 Determines whether an object of sub can be safely cast to sup.
1391 *******************************************************************************/
1393 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1395 java_lang_Class *csup;
1396 java_lang_Class *csub;
1398 csup = (java_lang_Class *) sup;
1399 csub = (java_lang_Class *) sub;
1401 STATISTICS(jniinvokation());
1403 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1407 /* Throw ***********************************************************************
1409 Causes a java.lang.Throwable object to be thrown.
1411 *******************************************************************************/
1413 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1415 java_objectheader *o;
1417 STATISTICS(jniinvokation());
1419 o = (java_objectheader *) obj;
1421 exceptions_set_exception(o);
1427 /* ThrowNew ********************************************************************
1429 Constructs an exception object from the specified class with the
1430 message specified by message and causes that exception to be
1433 *******************************************************************************/
1435 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1438 java_objectheader *o;
1439 java_objectheader *s;
1441 STATISTICS(jniinvokation());
1443 c = (classinfo *) clazz;
1446 s = javastring_new_from_utf_string(msg);
1448 /* instantiate exception object */
1450 o = native_new_and_init_string(c, s);
1455 exceptions_set_exception(o);
1461 /* ExceptionOccurred ***********************************************************
1463 Determines if an exception is being thrown. The exception stays
1464 being thrown until either the native code calls ExceptionClear(),
1465 or the Java code handles the exception.
1467 *******************************************************************************/
1469 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1471 java_objectheader *o;
1473 STATISTICS(jniinvokation());
1475 o = exceptions_get_exception();
1477 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1481 /* ExceptionDescribe ***********************************************************
1483 Prints an exception and a backtrace of the stack to a system
1484 error-reporting channel, such as stderr. This is a convenience
1485 routine provided for debugging.
1487 *******************************************************************************/
1489 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1491 java_objectheader *o;
1494 STATISTICS(jniinvokation());
1496 o = exceptions_get_exception();
1499 /* clear exception, because we are calling jit code again */
1501 exceptions_clear_exception();
1503 /* get printStackTrace method from exception class */
1505 m = class_resolveclassmethod(o->vftbl->class,
1506 utf_printStackTrace,
1512 /* XXX what should we do? */
1515 /* print the stacktrace */
1517 (void) vm_call_method(m, o);
1522 /* ExceptionClear **************************************************************
1524 Clears any exception that is currently being thrown. If no
1525 exception is currently being thrown, this routine has no effect.
1527 *******************************************************************************/
1529 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1531 STATISTICS(jniinvokation());
1533 exceptions_clear_exception();
1537 /* FatalError ******************************************************************
1539 Raises a fatal error and does not expect the VM to recover. This
1540 function does not return.
1542 *******************************************************************************/
1544 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1546 STATISTICS(jniinvokation());
1548 /* this seems to be the best way */
1550 vm_abort("JNI Fatal error: %s", msg);
1554 /* PushLocalFrame **************************************************************
1556 Creates a new local reference frame, in which at least a given
1557 number of local references can be created.
1559 *******************************************************************************/
1561 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1564 localref_table *lrt;
1565 localref_table *nlrt;
1567 STATISTICS(jniinvokation());
1572 /* Allocate new local reference table on Java heap. Calculate the
1573 additional memory we have to allocate. */
1575 if (capacity > LOCALREFTABLE_CAPACITY)
1576 additionalrefs = capacity - LOCALREFTABLE_CAPACITY;
1580 nlrt = GCMNEW(u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
1585 /* get current local reference table from thread */
1587 lrt = LOCALREFTABLE;
1589 /* Set up the new local reference table and add it to the local
1592 nlrt->capacity = capacity;
1594 nlrt->localframes = lrt->localframes + 1;
1597 /* store new local reference table in thread */
1599 LOCALREFTABLE = nlrt;
1605 /* PopLocalFrame ***************************************************************
1607 Pops off the current local reference frame, frees all the local
1608 references, and returns a local reference in the previous local
1609 reference frame for the given result object.
1611 *******************************************************************************/
1613 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1615 localref_table *lrt;
1616 localref_table *plrt;
1619 STATISTICS(jniinvokation());
1621 /* get current local reference table from thread */
1623 lrt = LOCALREFTABLE;
1625 localframes = lrt->localframes;
1627 /* Don't delete the top local frame, as this one is allocated in
1628 the native stub on the stack and is freed automagically on
1631 if (localframes == 1)
1632 return _Jv_JNI_NewLocalRef(env, result);
1634 /* release all current local frames */
1636 for (; localframes >= 1; localframes--) {
1637 /* get previous frame */
1641 /* clear all reference entries */
1643 MSET(&lrt->refs[0], 0, java_objectheader*, lrt->capacity);
1647 /* set new local references table */
1652 /* store new local reference table in thread */
1654 LOCALREFTABLE = lrt;
1656 /* add local reference and return the value */
1658 return _Jv_JNI_NewLocalRef(env, result);
1662 /* DeleteLocalRef **************************************************************
1664 Deletes the local reference pointed to by localRef.
1666 *******************************************************************************/
1668 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1670 java_objectheader *o;
1671 localref_table *lrt;
1674 STATISTICS(jniinvokation());
1676 o = (java_objectheader *) localRef;
1678 /* get local reference table (thread specific) */
1680 lrt = LOCALREFTABLE;
1682 /* go through all local frames */
1684 for (; lrt != NULL; lrt = lrt->prev) {
1686 /* and try to remove the reference */
1688 for (i = 0; i < lrt->capacity; i++) {
1689 if (lrt->refs[i] == o) {
1690 lrt->refs[i] = NULL;
1698 /* this should not happen */
1700 /* if (opt_checkjni) */
1701 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1702 log_text("JNI-DeleteLocalRef: Local ref passed to JNI not found");
1706 /* IsSameObject ****************************************************************
1708 Tests whether two references refer to the same Java object.
1710 *******************************************************************************/
1712 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1714 STATISTICS(jniinvokation());
1723 /* NewLocalRef *****************************************************************
1725 Creates a new local reference that refers to the same object as ref.
1727 *******************************************************************************/
1729 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1731 localref_table *lrt;
1734 STATISTICS(jniinvokation());
1739 /* get local reference table (thread specific) */
1741 lrt = LOCALREFTABLE;
1743 /* Check if we have space for the requested reference? No,
1744 allocate a new frame. This is actually not what the spec says,
1745 but for compatibility reasons... */
1747 if (lrt->used == lrt->capacity) {
1748 if (_Jv_JNI_EnsureLocalCapacity(env, 16) != 0)
1751 /* get the new local reference table */
1753 lrt = LOCALREFTABLE;
1756 /* insert the reference */
1758 for (i = 0; i < lrt->capacity; i++) {
1759 if (lrt->refs[i] == NULL) {
1760 lrt->refs[i] = (java_objectheader *) ref;
1767 /* should not happen, just to be sure */
1771 /* keep compiler happy */
1777 /* EnsureLocalCapacity *********************************************************
1779 Ensures that at least a given number of local references can be
1780 created in the current thread
1782 *******************************************************************************/
1784 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1786 localref_table *lrt;
1788 STATISTICS(jniinvokation());
1790 /* get local reference table (thread specific) */
1792 lrt = LOCALREFTABLE;
1794 /* check if capacity elements are available in the local references table */
1796 if ((lrt->used + capacity) > lrt->capacity)
1797 return _Jv_JNI_PushLocalFrame(env, capacity);
1803 /* AllocObject *****************************************************************
1805 Allocates a new Java object without invoking any of the
1806 constructors for the object. Returns a reference to the object.
1808 *******************************************************************************/
1810 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1813 java_objectheader *o;
1815 STATISTICS(jniinvokation());
1817 c = (classinfo *) clazz;
1819 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1820 exceptions_throw_instantiationexception(c);
1826 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1830 /* NewObject *******************************************************************
1832 Programmers place all arguments that are to be passed to the
1833 constructor immediately following the methodID
1834 argument. NewObject() accepts these arguments and passes them to
1835 the Java method that the programmer wishes to invoke.
1837 *******************************************************************************/
1839 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1841 java_objectheader *o;
1846 STATISTICS(jniinvokation());
1848 c = (classinfo *) clazz;
1849 m = (methodinfo *) methodID;
1858 /* call constructor */
1860 va_start(ap, methodID);
1861 _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
1864 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1868 /* NewObjectV ******************************************************************
1870 Programmers place all arguments that are to be passed to the
1871 constructor in an args argument of type va_list that immediately
1872 follows the methodID argument. NewObjectV() accepts these
1873 arguments, and, in turn, passes them to the Java method that the
1874 programmer wishes to invoke.
1876 *******************************************************************************/
1878 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1881 java_objectheader *o;
1885 STATISTICS(jniinvokation());
1887 c = (classinfo *) clazz;
1888 m = (methodinfo *) methodID;
1897 /* call constructor */
1899 _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
1901 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1905 /* NewObjectA *****************************************************************
1907 Programmers place all arguments that are to be passed to the
1908 constructor in an args array of jvalues that immediately follows
1909 the methodID argument. NewObjectA() accepts the arguments in this
1910 array, and, in turn, passes them to the Java method that the
1911 programmer wishes to invoke.
1913 *******************************************************************************/
1915 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1918 java_objectheader *o;
1922 STATISTICS(jniinvokation());
1924 c = (classinfo *) clazz;
1925 m = (methodinfo *) methodID;
1934 /* call constructor */
1936 _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
1938 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1942 /* GetObjectClass **************************************************************
1944 Returns the class of an object.
1946 *******************************************************************************/
1948 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1950 java_objectheader *o;
1953 STATISTICS(jniinvokation());
1955 o = (java_objectheader *) obj;
1957 if ((o == NULL) || (o->vftbl == NULL))
1960 c = o->vftbl->class;
1962 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1966 /* IsInstanceOf ****************************************************************
1968 Tests whether an object is an instance of a class.
1970 *******************************************************************************/
1972 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1975 java_lang_Object *o;
1977 STATISTICS(jniinvokation());
1979 c = (java_lang_Class *) clazz;
1980 o = (java_lang_Object *) obj;
1982 return _Jv_java_lang_Class_isInstance(c, o);
1986 /* Reflection Support *********************************************************/
1988 /* FromReflectedMethod *********************************************************
1990 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1991 object to a method ID.
1993 *******************************************************************************/
1995 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1997 #if defined(ENABLE_JAVASE)
1998 java_objectheader *o;
2003 STATISTICS(jniinvokation());
2005 o = (java_objectheader *) method;
2010 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
2011 java_lang_reflect_Method *rm;
2013 rm = (java_lang_reflect_Method *) method;
2014 c = (classinfo *) (rm->clazz);
2017 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
2018 java_lang_reflect_Constructor *rc;
2020 rc = (java_lang_reflect_Constructor *) method;
2021 c = (classinfo *) (rc->clazz);
2027 m = &(c->methods[slot]);
2029 return (jmethodID) m;
2031 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
2033 /* keep compiler happy */
2040 /* FromReflectedField **********************************************************
2042 Converts a java.lang.reflect.Field to a field ID.
2044 *******************************************************************************/
2046 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
2048 #if defined(ENABLE_JAVASE)
2049 java_lang_reflect_Field *rf;
2053 STATISTICS(jniinvokation());
2055 rf = (java_lang_reflect_Field *) field;
2060 c = (classinfo *) rf->clazz;
2061 f = &(c->fields[rf->slot]);
2063 return (jfieldID) f;
2065 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
2067 /* keep compiler happy */
2074 /* ToReflectedMethod ***********************************************************
2076 Converts a method ID derived from cls to an instance of the
2077 java.lang.reflect.Method class or to an instance of the
2078 java.lang.reflect.Constructor class.
2080 *******************************************************************************/
2082 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
2085 #if defined(ENABLE_JAVASE)
2087 java_lang_reflect_Constructor *rc;
2088 java_lang_reflect_Method *rm;
2090 STATISTICS(jniinvokation());
2092 m = (methodinfo *) methodID;
2094 /* HotSpot does the same assert. */
2096 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
2098 if (m->name == utf_init) {
2099 rc = reflect_constructor_new(m);
2101 return (jobject) rc;
2104 rm = reflect_method_new(m);
2106 return (jobject) rm;
2109 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
2111 /* keep compiler happy */
2118 /* ToReflectedField ************************************************************
2120 Converts a field ID derived from cls to an instance of the
2121 java.lang.reflect.Field class.
2123 *******************************************************************************/
2125 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
2128 STATISTICS(jniinvokation());
2130 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
2136 /* Calling Instance Methods ***************************************************/
2138 /* GetMethodID *****************************************************************
2140 Returns the method ID for an instance (nonstatic) method of a class
2141 or interface. The method may be defined in one of the clazz's
2142 superclasses and inherited by clazz. The method is determined by
2143 its name and signature.
2145 GetMethodID() causes an uninitialized class to be initialized.
2147 *******************************************************************************/
2149 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
2157 STATISTICS(jniinvokation());
2159 c = (classinfo *) clazz;
2164 if (!(c->state & CLASS_INITIALIZED))
2165 if (!initialize_class(c))
2168 /* try to get the method of the class or one of it's superclasses */
2170 uname = utf_new_char((char *) name);
2171 udesc = utf_new_char((char *) sig);
2173 m = class_resolvemethod(c, uname, udesc);
2175 if ((m == NULL) || (m->flags & ACC_STATIC)) {
2176 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2181 return (jmethodID) m;
2185 /* JNI-functions for calling instance methods *********************************/
2187 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
2190 java_objectheader *o;
2192 java_objectheader *ret;
2195 o = (java_objectheader *) obj;
2196 m = (methodinfo *) methodID;
2198 va_start(ap, methodID);
2199 ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, ap);
2202 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
2206 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2209 java_objectheader *o;
2211 java_objectheader *ret;
2213 o = (java_objectheader *) obj;
2214 m = (methodinfo *) methodID;
2216 ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, args);
2218 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
2222 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2225 java_objectheader *o;
2227 java_objectheader *ret;
2229 o = (java_objectheader *) obj;
2230 m = (methodinfo *) methodID;
2232 ret = _Jv_jni_CallObjectMethodA(o, o->vftbl, m, args);
2234 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
2238 jboolean _Jv_JNI_CallBooleanMethod(JNIEnv *env, jobject obj, jmethodID methodID,
2241 java_objectheader *o;
2246 o = (java_objectheader *) obj;
2247 m = (methodinfo *) methodID;
2249 va_start(ap, methodID);
2250 b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2257 jboolean _Jv_JNI_CallBooleanMethodV(JNIEnv *env, jobject obj,
2258 jmethodID methodID, va_list args)
2260 java_objectheader *o;
2264 o = (java_objectheader *) obj;
2265 m = (methodinfo *) methodID;
2267 b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2273 jboolean _Jv_JNI_CallBooleanMethodA(JNIEnv *env, jobject obj,
2274 jmethodID methodID, const jvalue *args)
2276 java_objectheader *o;
2280 o = (java_objectheader *) obj;
2281 m = (methodinfo *) methodID;
2283 b = _Jv_jni_CallIntMethodA(o, o->vftbl, m, args);
2289 jbyte _Jv_JNI_CallByteMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2291 java_objectheader *o;
2296 o = (java_objectheader *) obj;
2297 m = (methodinfo *) methodID;
2299 va_start(ap, methodID);
2300 b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2308 jbyte _Jv_JNI_CallByteMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2311 java_objectheader *o;
2315 o = (java_objectheader *) obj;
2316 m = (methodinfo *) methodID;
2318 b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2324 jbyte _Jv_JNI_CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2327 log_text("JNI-Call: CallByteMethodA: IMPLEMENT ME!");
2333 jchar _Jv_JNI_CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2335 java_objectheader *o;
2340 o = (java_objectheader *) obj;
2341 m = (methodinfo *) methodID;
2343 va_start(ap, methodID);
2344 c = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2351 jchar _Jv_JNI_CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2354 java_objectheader *o;
2358 o = (java_objectheader *) obj;
2359 m = (methodinfo *) methodID;
2361 c = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2367 jchar _Jv_JNI_CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2370 log_text("JNI-Call: CallCharMethodA: IMPLEMENT ME!");
2376 jshort _Jv_JNI_CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID,
2379 java_objectheader *o;
2384 o = (java_objectheader *) obj;
2385 m = (methodinfo *) methodID;
2387 va_start(ap, methodID);
2388 s = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2395 jshort _Jv_JNI_CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2398 java_objectheader *o;
2402 o = (java_objectheader *) obj;
2403 m = (methodinfo *) methodID;
2405 s = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2411 jshort _Jv_JNI_CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2414 log_text("JNI-Call: CallShortMethodA: IMPLEMENT ME!");
2421 jint _Jv_JNI_CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2423 java_objectheader *o;
2428 o = (java_objectheader *) obj;
2429 m = (methodinfo *) methodID;
2431 va_start(ap, methodID);
2432 i = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2439 jint _Jv_JNI_CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2442 java_objectheader *o;
2446 o = (java_objectheader *) obj;
2447 m = (methodinfo *) methodID;
2449 i = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2455 jint _Jv_JNI_CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2458 log_text("JNI-Call: CallIntMethodA: IMPLEMENT ME!");
2465 jlong _Jv_JNI_CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2467 java_objectheader *o;
2472 o = (java_objectheader *) obj;
2473 m = (methodinfo *) methodID;
2475 va_start(ap, methodID);
2476 l = _Jv_jni_CallLongMethod(o, o->vftbl, m, ap);
2483 jlong _Jv_JNI_CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2486 java_objectheader *o;
2490 o = (java_objectheader *) obj;
2491 m = (methodinfo *) methodID;
2493 l = _Jv_jni_CallLongMethod(o, o->vftbl, m, args);
2499 jlong _Jv_JNI_CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2502 log_text("JNI-Call: CallLongMethodA: IMPLEMENT ME!");
2509 jfloat _Jv_JNI_CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID,
2512 java_objectheader *o;
2517 o = (java_objectheader *) obj;
2518 m = (methodinfo *) methodID;
2520 va_start(ap, methodID);
2521 f = _Jv_jni_CallFloatMethod(o, o->vftbl, m, ap);
2528 jfloat _Jv_JNI_CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2531 java_objectheader *o;
2535 o = (java_objectheader *) obj;
2536 m = (methodinfo *) methodID;
2538 f = _Jv_jni_CallFloatMethod(o, o->vftbl, m, args);
2544 jfloat _Jv_JNI_CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2547 log_text("JNI-Call: CallFloatMethodA: IMPLEMENT ME!");
2554 jdouble _Jv_JNI_CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID,
2557 java_objectheader *o;
2562 o = (java_objectheader *) obj;
2563 m = (methodinfo *) methodID;
2565 va_start(ap, methodID);
2566 d = _Jv_jni_CallDoubleMethod(o, o->vftbl, m, ap);
2573 jdouble _Jv_JNI_CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2576 java_objectheader *o;
2580 o = (java_objectheader *) obj;
2581 m = (methodinfo *) methodID;
2583 d = _Jv_jni_CallDoubleMethod(o, o->vftbl, m, args);
2589 jdouble _Jv_JNI_CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2592 log_text("JNI-Call: CallDoubleMethodA: IMPLEMENT ME!");
2599 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2601 java_objectheader *o;
2605 o = (java_objectheader *) obj;
2606 m = (methodinfo *) methodID;
2608 va_start(ap, methodID);
2609 _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
2614 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2617 java_objectheader *o;
2620 o = (java_objectheader *) obj;
2621 m = (methodinfo *) methodID;
2623 _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
2627 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2630 java_objectheader *o;
2633 o = (java_objectheader *) obj;
2634 m = (methodinfo *) methodID;
2636 _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
2641 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2642 jclass clazz, jmethodID methodID,
2645 java_objectheader *o;
2648 java_objectheader *r;
2651 o = (java_objectheader *) obj;
2652 c = (classinfo *) clazz;
2653 m = (methodinfo *) methodID;
2655 va_start(ap, methodID);
2656 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2659 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2663 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2664 jclass clazz, jmethodID methodID,
2667 java_objectheader *o;
2670 java_objectheader *r;
2672 o = (java_objectheader *) obj;
2673 c = (classinfo *) clazz;
2674 m = (methodinfo *) methodID;
2676 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2678 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2682 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2683 jclass clazz, jmethodID methodID,
2686 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2688 return _Jv_JNI_NewLocalRef(env, NULL);
2693 jboolean _Jv_JNI_CallNonvirtualBooleanMethod(JNIEnv *env, jobject obj,
2694 jclass clazz, jmethodID methodID,
2697 java_objectheader *o;
2703 o = (java_objectheader *) obj;
2704 c = (classinfo *) clazz;
2705 m = (methodinfo *) methodID;
2707 va_start(ap, methodID);
2708 b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2715 jboolean _Jv_JNI_CallNonvirtualBooleanMethodV(JNIEnv *env, jobject obj,
2716 jclass clazz, jmethodID methodID,
2719 java_objectheader *o;
2724 o = (java_objectheader *) obj;
2725 c = (classinfo *) clazz;
2726 m = (methodinfo *) methodID;
2728 b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2734 jboolean _Jv_JNI_CallNonvirtualBooleanMethodA(JNIEnv *env, jobject obj,
2735 jclass clazz, jmethodID methodID,
2738 log_text("JNI-Call: CallNonvirtualBooleanMethodA: IMPLEMENT ME!");
2744 jbyte _Jv_JNI_CallNonvirtualByteMethod(JNIEnv *env, jobject obj, jclass clazz,
2745 jmethodID methodID, ...)
2747 java_objectheader *o;
2753 o = (java_objectheader *) obj;
2754 c = (classinfo *) clazz;
2755 m = (methodinfo *) methodID;
2757 va_start(ap, methodID);
2758 b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2765 jbyte _Jv_JNI_CallNonvirtualByteMethodV(JNIEnv *env, jobject obj, jclass clazz,
2766 jmethodID methodID, va_list args)
2768 java_objectheader *o;
2773 o = (java_objectheader *) obj;
2774 c = (classinfo *) clazz;
2775 m = (methodinfo *) methodID;
2777 b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2783 jbyte _Jv_JNI_CallNonvirtualByteMethodA(JNIEnv *env, jobject obj, jclass clazz,
2784 jmethodID methodID, const jvalue *args)
2786 log_text("JNI-Call: CallNonvirtualByteMethodA: IMPLEMENT ME!");
2793 jchar _Jv_JNI_CallNonvirtualCharMethod(JNIEnv *env, jobject obj, jclass clazz,
2794 jmethodID methodID, ...)
2796 java_objectheader *o;
2802 o = (java_objectheader *) obj;
2803 c = (classinfo *) clazz;
2804 m = (methodinfo *) methodID;
2806 va_start(ap, methodID);
2807 ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2814 jchar _Jv_JNI_CallNonvirtualCharMethodV(JNIEnv *env, jobject obj, jclass clazz,
2815 jmethodID methodID, va_list args)
2817 java_objectheader *o;
2822 o = (java_objectheader *) obj;
2823 c = (classinfo *) clazz;
2824 m = (methodinfo *) methodID;
2826 ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2832 jchar _Jv_JNI_CallNonvirtualCharMethodA(JNIEnv *env, jobject obj, jclass clazz,
2833 jmethodID methodID, const jvalue *args)
2835 log_text("JNI-Call: CallNonvirtualCharMethodA: IMPLEMENT ME!");
2842 jshort _Jv_JNI_CallNonvirtualShortMethod(JNIEnv *env, jobject obj,
2843 jclass clazz, jmethodID methodID, ...)
2845 java_objectheader *o;
2851 o = (java_objectheader *) obj;
2852 c = (classinfo *) clazz;
2853 m = (methodinfo *) methodID;
2855 va_start(ap, methodID);
2856 s = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2863 jshort _Jv_JNI_CallNonvirtualShortMethodV(JNIEnv *env, jobject obj,
2864 jclass clazz, jmethodID methodID,
2867 java_objectheader *o;
2872 o = (java_objectheader *) obj;
2873 c = (classinfo *) clazz;
2874 m = (methodinfo *) methodID;
2876 s = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2882 jshort _Jv_JNI_CallNonvirtualShortMethodA(JNIEnv *env, jobject obj,
2883 jclass clazz, jmethodID methodID,
2886 log_text("JNI-Call: CallNonvirtualShortMethodA: IMPLEMENT ME!");
2893 jint _Jv_JNI_CallNonvirtualIntMethod(JNIEnv *env, jobject obj, jclass clazz,
2894 jmethodID methodID, ...)
2896 java_objectheader *o;
2902 o = (java_objectheader *) obj;
2903 c = (classinfo *) clazz;
2904 m = (methodinfo *) methodID;
2906 va_start(ap, methodID);
2907 i = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2914 jint _Jv_JNI_CallNonvirtualIntMethodV(JNIEnv *env, jobject obj, jclass clazz,
2915 jmethodID methodID, va_list args)
2917 java_objectheader *o;
2922 o = (java_objectheader *) obj;
2923 c = (classinfo *) clazz;
2924 m = (methodinfo *) methodID;
2926 i = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2932 jint _Jv_JNI_CallNonvirtualIntMethodA(JNIEnv *env, jobject obj, jclass clazz,
2933 jmethodID methodID, const jvalue *args)
2935 log_text("JNI-Call: CallNonvirtualIntMethodA: IMPLEMENT ME!");
2942 jlong _Jv_JNI_CallNonvirtualLongMethod(JNIEnv *env, jobject obj, jclass clazz,
2943 jmethodID methodID, ...)
2945 java_objectheader *o;
2951 o = (java_objectheader *) obj;
2952 c = (classinfo *) clazz;
2953 m = (methodinfo *) methodID;
2955 va_start(ap, methodID);
2956 l = _Jv_jni_CallLongMethod(o, c->vftbl, m, ap);
2963 jlong _Jv_JNI_CallNonvirtualLongMethodV(JNIEnv *env, jobject obj, jclass clazz,
2964 jmethodID methodID, va_list args)
2966 java_objectheader *o;
2971 o = (java_objectheader *) obj;
2972 c = (classinfo *) clazz;
2973 m = (methodinfo *) methodID;
2975 l = _Jv_jni_CallLongMethod(o, c->vftbl, m, args);
2981 jlong _Jv_JNI_CallNonvirtualLongMethodA(JNIEnv *env, jobject obj, jclass clazz,
2982 jmethodID methodID, const jvalue *args)
2984 log_text("JNI-Call: CallNonvirtualLongMethodA: IMPLEMENT ME!");
2991 jfloat _Jv_JNI_CallNonvirtualFloatMethod(JNIEnv *env, jobject obj,
2992 jclass clazz, jmethodID methodID, ...)
2994 java_objectheader *o;
3000 o = (java_objectheader *) obj;
3001 c = (classinfo *) clazz;
3002 m = (methodinfo *) methodID;
3004 va_start(ap, methodID);
3005 f = _Jv_jni_CallFloatMethod(o, c->vftbl, m, ap);
3012 jfloat _Jv_JNI_CallNonvirtualFloatMethodV(JNIEnv *env, jobject obj,
3013 jclass clazz, jmethodID methodID,
3016 java_objectheader *o;
3021 o = (java_objectheader *) obj;
3022 c = (classinfo *) clazz;
3023 m = (methodinfo *) methodID;
3025 f = _Jv_jni_CallFloatMethod(o, c->vftbl, m, args);
3031 jfloat _Jv_JNI_CallNonvirtualFloatMethodA(JNIEnv *env, jobject obj,
3032 jclass clazz, jmethodID methodID,
3035 log_text("JNI-Call: CallNonvirtualFloatMethodA: IMPLEMENT ME!");
3042 jdouble _Jv_JNI_CallNonvirtualDoubleMethod(JNIEnv *env, jobject obj,
3043 jclass clazz, jmethodID methodID,
3046 java_objectheader *o;
3052 o = (java_objectheader *) obj;
3053 c = (classinfo *) clazz;
3054 m = (methodinfo *) methodID;
3056 va_start(ap, methodID);
3057 d = _Jv_jni_CallDoubleMethod(o, c->vftbl, m, ap);
3064 jdouble _Jv_JNI_CallNonvirtualDoubleMethodV(JNIEnv *env, jobject obj,
3065 jclass clazz, jmethodID methodID,
3068 java_objectheader *o;
3073 o = (java_objectheader *) obj;
3074 c = (classinfo *) clazz;
3075 m = (methodinfo *) methodID;
3077 d = _Jv_jni_CallDoubleMethod(o, c->vftbl, m, args);
3083 jdouble _Jv_JNI_CallNonvirtualDoubleMethodA(JNIEnv *env, jobject obj,
3084 jclass clazz, jmethodID methodID,
3087 log_text("JNI-Call: CallNonvirtualDoubleMethodA: IMPLEMENT ME!");
3094 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
3095 jmethodID methodID, ...)
3097 java_objectheader *o;
3102 o = (java_objectheader *) obj;
3103 c = (classinfo *) clazz;
3104 m = (methodinfo *) methodID;
3106 va_start(ap, methodID);
3107 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
3112 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
3113 jmethodID methodID, va_list args)
3115 java_objectheader *o;
3119 o = (java_objectheader *) obj;
3120 c = (classinfo *) clazz;
3121 m = (methodinfo *) methodID;
3123 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
3127 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
3128 jmethodID methodID, const jvalue * args)
3130 java_objectheader *o;
3134 o = (java_objectheader *) obj;
3135 c = (classinfo *) clazz;
3136 m = (methodinfo *) methodID;
3138 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
3142 /* Accessing Fields of Objects ************************************************/
3144 /* GetFieldID ******************************************************************
3146 Returns the field ID for an instance (nonstatic) field of a
3147 class. The field is specified by its name and signature. The
3148 Get<type>Field and Set<type>Field families of accessor functions
3149 use field IDs to retrieve object fields.
3151 *******************************************************************************/
3153 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
3161 STATISTICS(jniinvokation());
3163 c = (classinfo *) clazz;
3165 /* XXX NPE check? */
3167 uname = utf_new_char((char *) name);
3168 udesc = utf_new_char((char *) sig);
3170 f = class_findfield(c, uname, udesc);
3173 exceptions_throw_nosuchfielderror(c, uname);
3175 return (jfieldID) f;
3179 /* Get<type>Field Routines *****************************************************
3181 This family of accessor routines returns the value of an instance
3182 (nonstatic) field of an object. The field to access is specified by
3183 a field ID obtained by calling GetFieldID().
3185 *******************************************************************************/
3187 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
3189 java_objectheader *o;
3191 STATISTICS(jniinvokation());
3193 o = GET_FIELD(obj, java_objectheader*, fieldID);
3195 return _Jv_JNI_NewLocalRef(env, (jobject) o);
3199 jboolean _Jv_JNI_GetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID)
3203 STATISTICS(jniinvokation());
3205 i = GET_FIELD(obj, s4, fieldID);
3207 return (jboolean) i;
3211 jbyte _Jv_JNI_GetByteField(JNIEnv *env, jobject obj, jfieldID fieldID)
3215 STATISTICS(jniinvokation());
3217 i = GET_FIELD(obj, s4, fieldID);
3223 jchar _Jv_JNI_GetCharField(JNIEnv *env, jobject obj, jfieldID fieldID)
3227 STATISTICS(jniinvokation());
3229 i = GET_FIELD(obj, s4, fieldID);
3235 jshort _Jv_JNI_GetShortField(JNIEnv *env, jobject obj, jfieldID fieldID)
3239 STATISTICS(jniinvokation());
3241 i = GET_FIELD(obj, s4, fieldID);
3247 jint _Jv_JNI_GetIntField(JNIEnv *env, jobject obj, jfieldID fieldID)
3249 java_objectheader *o;
3253 STATISTICS(jniinvokation());
3255 o = (java_objectheader *) obj;
3256 f = (fieldinfo *) fieldID;
3258 i = GET_FIELD(o, s4, f);
3264 jlong _Jv_JNI_GetLongField(JNIEnv *env, jobject obj, jfieldID fieldID)
3268 STATISTICS(jniinvokation());
3270 l = GET_FIELD(obj, s8, fieldID);
3276 jfloat _Jv_JNI_GetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID)
3280 STATISTICS(jniinvokation());
3282 f = GET_FIELD(obj, float, fieldID);
3288 jdouble _Jv_JNI_GetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID)
3292 STATISTICS(jniinvokation());
3294 d = GET_FIELD(obj, double, fieldID);
3300 /* Set<type>Field Routines *****************************************************
3302 This family of accessor routines sets the value of an instance
3303 (nonstatic) field of an object. The field to access is specified by
3304 a field ID obtained by calling GetFieldID().
3306 *******************************************************************************/
3308 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
3311 STATISTICS(jniinvokation());
3313 SET_FIELD(obj, java_objectheader*, fieldID, value);
3317 void _Jv_JNI_SetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID,
3320 STATISTICS(jniinvokation());
3322 SET_FIELD(obj, s4, fieldID, value);
3326 void _Jv_JNI_SetByteField(JNIEnv *env, jobject obj, jfieldID fieldID,
3329 STATISTICS(jniinvokation());
3331 SET_FIELD(obj, s4, fieldID, value);
3335 void _Jv_JNI_SetCharField(JNIEnv *env, jobject obj, jfieldID fieldID,
3338 STATISTICS(jniinvokation());
3340 SET_FIELD(obj, s4, fieldID, value);
3344 void _Jv_JNI_SetShortField(JNIEnv *env, jobject obj, jfieldID fieldID,
3347 STATISTICS(jniinvokation());
3349 SET_FIELD(obj, s4, fieldID, value);
3353 void _Jv_JNI_SetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint value)
3355 STATISTICS(jniinvokation());
3357 SET_FIELD(obj, s4, fieldID, value);
3361 void _Jv_JNI_SetLongField(JNIEnv *env, jobject obj, jfieldID fieldID,
3364 STATISTICS(jniinvokation());
3366 SET_FIELD(obj, s8, fieldID, value);
3370 void _Jv_JNI_SetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID,
3373 STATISTICS(jniinvokation());
3375 SET_FIELD(obj, float, fieldID, value);
3379 void _Jv_JNI_SetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID,
3382 STATISTICS(jniinvokation());
3384 SET_FIELD(obj, double, fieldID, value);
3388 /* Calling Static Methods *****************************************************/
3390 /* GetStaticMethodID ***********************************************************
3392 Returns the method ID for a static method of a class. The method is
3393 specified by its name and signature.
3395 GetStaticMethodID() causes an uninitialized class to be
3398 *******************************************************************************/
3400 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
3408 STATISTICS(jniinvokation());
3410 c = (classinfo *) clazz;
3415 if (!(c->state & CLASS_INITIALIZED))
3416 if (!initialize_class(c))
3419 /* try to get the static method of the class */
3421 uname = utf_new_char((char *) name);
3422 udesc = utf_new_char((char *) sig);
3424 m = class_resolvemethod(c, uname, udesc);
3426 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
3427 exceptions_throw_nosuchmethoderror(c, uname, udesc);
3432 return (jmethodID) m;
3436 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
3437 jmethodID methodID, ...)
3440 java_objectheader *o;
3443 m = (methodinfo *) methodID;
3445 va_start(ap, methodID);
3446 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
3449 return _Jv_JNI_NewLocalRef(env, (jobject) o);
3453 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
3454 jmethodID methodID, va_list args)
3457 java_objectheader *o;
3459 m = (methodinfo *) methodID;
3461 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
3463 return _Jv_JNI_NewLocalRef(env, (jobject) o);
3467 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
3468 jmethodID methodID, const jvalue *args)
3471 java_objectheader *o;
3473 m = (methodinfo *) methodID;
3475 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
3477 return _Jv_JNI_NewLocalRef(env, (jobject) o);
3481 jboolean _Jv_JNI_CallStaticBooleanMethod(JNIEnv *env, jclass clazz,
3482 jmethodID methodID, ...)
3488 m = (methodinfo *) methodID;
3490 va_start(ap, methodID);
3491 b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3498 jboolean _Jv_JNI_CallStaticBooleanMethodV(JNIEnv *env, jclass clazz,
3499 jmethodID methodID, va_list args)
3504 m = (methodinfo *) methodID;
3506 b = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3512 jboolean _Jv_JNI_CallStaticBooleanMethodA(JNIEnv *env, jclass clazz,
3513 jmethodID methodID, const jvalue *args)
3518 m = (methodinfo *) methodID;
3520 b = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
3526 jbyte _Jv_JNI_CallStaticByteMethod(JNIEnv *env, jclass clazz,
3527 jmethodID methodID, ...)
3533 m = (methodinfo *) methodID;
3535 va_start(ap, methodID);
3536 b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3543 jbyte _Jv_JNI_CallStaticByteMethodV(JNIEnv *env, jclass clazz,
3544 jmethodID methodID, va_list args)
3549 m = (methodinfo *) methodID;
3551 b = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3557 jbyte _Jv_JNI_CallStaticByteMethodA(JNIEnv *env, jclass clazz,
3558 jmethodID methodID, const jvalue *args)
3563 m = (methodinfo *) methodID;
3565 b = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
3571 jchar _Jv_JNI_CallStaticCharMethod(JNIEnv *env, jclass clazz,
3572 jmethodID methodID, ...)
3578 m = (methodinfo *) methodID;
3580 va_start(ap, methodID);
3581 c = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3588 jchar _Jv_JNI_CallStaticCharMethodV(JNIEnv *env, jclass clazz,
3589 jmethodID methodID, va_list args)
3594 m = (methodinfo *) methodID;
3596 c = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3602 jchar _Jv_JNI_CallStaticCharMethodA(JNIEnv *env, jclass clazz,
3603 jmethodID methodID, const jvalue *args)
3608 m = (methodinfo *) methodID;
3610 c = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
3616 jshort _Jv_JNI_CallStaticShortMethod(JNIEnv *env, jclass clazz,
3617 jmethodID methodID, ...)
3623 m = (methodinfo *) methodID;
3625 va_start(ap, methodID);
3626 s = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3633 jshort _Jv_JNI_CallStaticShortMethodV(JNIEnv *env, jclass clazz,
3634 jmethodID methodID, va_list args)
3639 m = (methodinfo *) methodID;
3641 s = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3647 jshort _Jv_JNI_CallStaticShortMethodA(JNIEnv *env, jclass clazz,
3648 jmethodID methodID, const jvalue *args)
3653 m = (methodinfo *) methodID;
3655 s = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
3661 jint _Jv_JNI_CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID,
3668 m = (methodinfo *) methodID;
3670 va_start(ap, methodID);
3671 i = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3678 jint _Jv_JNI_CallStaticIntMethodV(JNIEnv *env, jclass clazz,
3679 jmethodID methodID, va_list args)
3684 m = (methodinfo *) methodID;
3686 i = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3692 jint _Jv_JNI_CallStaticIntMethodA(JNIEnv *env, jclass clazz,
3693 jmethodID methodID, const jvalue *args)
3698 m = (methodinfo *) methodID;
3700 i = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
3706 jlong _Jv_JNI_CallStaticLongMethod(JNIEnv *env, jclass clazz,
3707 jmethodID methodID, ...)
3713 m = (methodinfo *) methodID;
3715 va_start(ap, methodID);
3716 l = _Jv_jni_CallLongMethod(NULL, NULL, m, ap);
3723 jlong _Jv_JNI_CallStaticLongMethodV(JNIEnv *env, jclass clazz,
3724 jmethodID methodID, va_list args)
3729 m = (methodinfo *) methodID;
3731 l = _Jv_jni_CallLongMethod(NULL, NULL, m, args);
3737 jlong _Jv_JNI_CallStaticLongMethodA(JNIEnv *env, jclass clazz,
3738 jmethodID methodID, const jvalue *args)
3743 m = (methodinfo *) methodID;
3745 l = _Jv_jni_CallLongMethodA(NULL, NULL, m, args);
3752 jfloat _Jv_JNI_CallStaticFloatMethod(JNIEnv *env, jclass clazz,
3753 jmethodID methodID, ...)
3759 m = (methodinfo *) methodID;
3761 va_start(ap, methodID);
3762 f = _Jv_jni_CallFloatMethod(NULL, NULL, m, ap);
3769 jfloat _Jv_JNI_CallStaticFloatMethodV(JNIEnv *env, jclass clazz,
3770 jmethodID methodID, va_list args)
3775 m = (methodinfo *) methodID;
3777 f = _Jv_jni_CallFloatMethod(NULL, NULL, m, args);
3783 jfloat _Jv_JNI_CallStaticFloatMethodA(JNIEnv *env, jclass clazz,
3784 jmethodID methodID, const jvalue *args)
3789 m = (methodinfo *) methodID;
3791 f = _Jv_jni_CallFloatMethodA(NULL, NULL, m, args);
3797 jdouble _Jv_JNI_CallStaticDoubleMethod(JNIEnv *env, jclass clazz,
3798 jmethodID methodID, ...)
3804 m = (methodinfo *) methodID;
3806 va_start(ap, methodID);
3807 d = _Jv_jni_CallDoubleMethod(NULL, NULL, m, ap);
3814 jdouble _Jv_JNI_CallStaticDoubleMethodV(JNIEnv *env, jclass clazz,
3815 jmethodID methodID, va_list args)
3820 m = (methodinfo *) methodID;
3822 d = _Jv_jni_CallDoubleMethod(NULL, NULL, m, args);
3828 jdouble _Jv_JNI_CallStaticDoubleMethodA(JNIEnv *env, jclass clazz,
3829 jmethodID methodID, const jvalue *args)
3834 m = (methodinfo *) methodID;
3836 d = _Jv_jni_CallDoubleMethodA(NULL, NULL, m, args);
3842 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
3843 jmethodID methodID, ...)
3848 m = (methodinfo *) methodID;
3850 va_start(ap, methodID);
3851 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
3856 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
3857 jmethodID methodID, va_list args)
3861 m = (methodinfo *) methodID;
3863 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
3867 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
3868 jmethodID methodID, const jvalue * args)
3872 m = (methodinfo *) methodID;
3874 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
3878 /* Accessing Static Fields ****************************************************/
3880 /* GetStaticFieldID ************************************************************
3882 Returns the field ID for a static field of a class. The field is
3883 specified by its name and signature. The GetStatic<type>Field and
3884 SetStatic<type>Field families of accessor functions use field IDs
3885 to retrieve static fields.
3887 *******************************************************************************/
3889 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
3897 STATISTICS(jniinvokation());
3899 c = (classinfo *) clazz;
3901 uname = utf_new_char((char *) name);
3902 usig = utf_new_char((char *) sig);
3904 f = class_findfield(c, uname, usig);
3907 exceptions_throw_nosuchfielderror(c, uname);
3909 return (jfieldID) f;
3913 /* GetStatic<type>Field ********************************************************
3915 This family of accessor routines returns the value of a static
3918 *******************************************************************************/
3920 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
3926 STATISTICS(jniinvokation());
3928 c = (classinfo *) clazz;
3929 f = (fieldinfo *) fieldID;
3931 if (!(c->state & CLASS_INITIALIZED))
3932 if (!initialize_class(c))
3935 return _Jv_JNI_NewLocalRef(env, f->value.a);
3939 jboolean _Jv_JNI_GetStaticBooleanField(JNIEnv *env, jclass clazz,
3945 STATISTICS(jniinvokation());
3947 c = (classinfo *) clazz;
3948 f = (fieldinfo *) fieldID;
3950 if (!(c->state & CLASS_INITIALIZED))
3951 if (!initialize_class(c))
3958 jbyte _Jv_JNI_GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3963 STATISTICS(jniinvokation());
3965 c = (classinfo *) clazz;
3966 f = (fieldinfo *) fieldID;
3968 if (!(c->state & CLASS_INITIALIZED))
3969 if (!initialize_class(c))
3976 jchar _Jv_JNI_GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3981 STATISTICS(jniinvokation());
3983 c = (classinfo *) clazz;
3984 f = (fieldinfo *) fieldID;
3986 if (!(c->state & CLASS_INITIALIZED))
3987 if (!initialize_class(c))
3994 jshort _Jv_JNI_GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3999 STATISTICS(jniinvokation());
4001 c = (classinfo *) clazz;
4002 f = (fieldinfo *) fieldID;
4004 if (!(c->state & CLASS_INITIALIZED))
4005 if (!initialize_class(c))
4012 jint _Jv_JNI_GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
4017 STATISTICS(jniinvokation());
4019 c = (classinfo *) clazz;
4020 f = (fieldinfo *) fieldID;
4022 if (!(c->state & CLASS_INITIALIZED))
4023 if (!initialize_class(c))
4030 jlong _Jv_JNI_GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
4035 STATISTICS(jniinvokation());
4037 c = (classinfo *) clazz;
4038 f = (fieldinfo *) fieldID;
4040 if (!(c->state & CLASS_INITIALIZED))
4041 if (!initialize_class(c))
4048 jfloat _Jv_JNI_GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
4053 STATISTICS(jniinvokation());
4055 c = (classinfo *) clazz;
4056 f = (fieldinfo *) fieldID;
4058 if (!(c->state & CLASS_INITIALIZED))
4059 if (!initialize_class(c))
4066 jdouble _Jv_JNI_GetStaticDoubleField(JNIEnv *env, jclass clazz,
4072 STATISTICS(jniinvokation());
4074 c = (classinfo *) clazz;
4075 f = (fieldinfo *) fieldID;
4077 if (!(c->state & CLASS_INITIALIZED))
4078 if (!initialize_class(c))
4085 /* SetStatic<type>Field *******************************************************
4087 This family of accessor routines sets the value of a static field
4090 *******************************************************************************/
4092 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4098 STATISTICS(jniinvokation());
4100 c = (classinfo *) clazz;
4101 f = (fieldinfo *) fieldID;
4103 if (!(c->state & CLASS_INITIALIZED))
4104 if (!initialize_class(c))
4111 void _Jv_JNI_SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4117 STATISTICS(jniinvokation());
4119 c = (classinfo *) clazz;
4120 f = (fieldinfo *) fieldID;
4122 if (!(c->state & CLASS_INITIALIZED))
4123 if (!initialize_class(c))
4130 void _Jv_JNI_SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4136 STATISTICS(jniinvokation());
4138 c = (classinfo *) clazz;
4139 f = (fieldinfo *) fieldID;
4141 if (!(c->state & CLASS_INITIALIZED))
4142 if (!initialize_class(c))
4149 void _Jv_JNI_SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4155 STATISTICS(jniinvokation());
4157 c = (classinfo *) clazz;
4158 f = (fieldinfo *) fieldID;
4160 if (!(c->state & CLASS_INITIALIZED))
4161 if (!initialize_class(c))
4168 void _Jv_JNI_SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4174 STATISTICS(jniinvokation());
4176 c = (classinfo *) clazz;
4177 f = (fieldinfo *) fieldID;
4179 if (!(c->state & CLASS_INITIALIZED))
4180 if (!initialize_class(c))
4187 void _Jv_JNI_SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4193 STATISTICS(jniinvokation());
4195 c = (classinfo *) clazz;
4196 f = (fieldinfo *) fieldID;
4198 if (!(c->state & CLASS_INITIALIZED))
4199 if (!initialize_class(c))
4206 void _Jv_JNI_SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4212 STATISTICS(jniinvokation());
4214 c = (classinfo *) clazz;
4215 f = (fieldinfo *) fieldID;
4217 if (!(c->state & CLASS_INITIALIZED))
4218 if (!initialize_class(c))
4225 void _Jv_JNI_SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4231 STATISTICS(jniinvokation());
4233 c = (classinfo *) clazz;
4234 f = (fieldinfo *) fieldID;
4236 if (!(c->state & CLASS_INITIALIZED))
4237 if (!initialize_class(c))
4244 void _Jv_JNI_SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4250 STATISTICS(jniinvokation());
4252 c = (classinfo *) clazz;
4253 f = (fieldinfo *) fieldID;
4255 if (!(c->state & CLASS_INITIALIZED))
4256 if (!initialize_class(c))
4263 /* String Operations **********************************************************/
4265 /* NewString *******************************************************************
4267 Create new java.lang.String object from an array of Unicode
4270 *******************************************************************************/
4272 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
4274 java_lang_String *s;
4278 STATISTICS(jniinvokation());
4280 s = (java_lang_String *) builtin_new(class_java_lang_String);
4281 a = builtin_newarray_char(len);
4283 /* javastring or characterarray could not be created */
4284 if ((a == NULL) || (s == NULL))
4288 for (i = 0; i < len; i++)
4289 a->data[i] = buf[i];
4295 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
4299 static jchar emptyStringJ[]={0,0};
4301 /* GetStringLength *************************************************************
4303 Returns the length (the count of Unicode characters) of a Java
4306 *******************************************************************************/
4308 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
4310 java_lang_String *s;
4312 s = (java_lang_String *) str;
4318 /******************** convertes javastring to u2-array ****************************/
4320 u2 *javastring_tou2(jstring so)
4322 java_lang_String *s;
4327 STATISTICS(jniinvokation());
4329 s = (java_lang_String *) so;
4339 /* allocate memory */
4341 stringbuffer = MNEW(u2, s->count + 1);
4345 for (i = 0; i < s->count; i++)
4346 stringbuffer[i] = a->data[s->offset + i];
4348 /* terminate string */
4350 stringbuffer[i] = '\0';
4352 return stringbuffer;
4356 /* GetStringChars **************************************************************
4358 Returns a pointer to the array of Unicode characters of the
4359 string. This pointer is valid until ReleaseStringChars() is called.
4361 *******************************************************************************/
4363 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
4367 STATISTICS(jniinvokation());
4369 jc = javastring_tou2(str);
4381 return emptyStringJ;
4385 /* ReleaseStringChars **********************************************************
4387 Informs the VM that the native code no longer needs access to
4388 chars. The chars argument is a pointer obtained from string using
4391 *******************************************************************************/
4393 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
4395 STATISTICS(jniinvokation());
4397 if (chars == emptyStringJ)
4400 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
4404 /* NewStringUTF ****************************************************************
4406 Constructs a new java.lang.String object from an array of UTF-8
4409 *******************************************************************************/
4411 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
4413 java_lang_String *s;
4415 STATISTICS(jniinvokation());
4417 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
4419 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
4423 /****************** returns the utf8 length in bytes of a string *******************/
4425 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
4427 java_lang_String *s;
4430 STATISTICS(jniinvokation());
4432 s = (java_lang_String *) string;
4434 length = u2_utflength(s->value->data, s->count);
4440 /* GetStringUTFChars ***********************************************************
4442 Returns a pointer to an array of UTF-8 characters of the
4443 string. This array is valid until it is released by
4444 ReleaseStringUTFChars().
4446 *******************************************************************************/
4448 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
4453 STATISTICS(jniinvokation());
4461 u = javastring_toutf((java_objectheader *) string, false);
4470 /* ReleaseStringUTFChars *******************************************************
4472 Informs the VM that the native code no longer needs access to
4473 utf. The utf argument is a pointer derived from string using
4474 GetStringUTFChars().
4476 *******************************************************************************/
4478 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
4480 STATISTICS(jniinvokation());
4482 /* XXX we don't release utf chars right now, perhaps that should be done
4483 later. Since there is always one reference the garbage collector will
4488 /* Array Operations ***********************************************************/
4490 /* GetArrayLength **************************************************************
4492 Returns the number of elements in the array.
4494 *******************************************************************************/
4496 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
4498 java_arrayheader *a;
4500 STATISTICS(jniinvokation());
4502 a = (java_arrayheader *) array;
4508 /* NewObjectArray **************************************************************
4510 Constructs a new array holding objects in class elementClass. All
4511 elements are initially set to initialElement.
4513 *******************************************************************************/
4515 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
4516 jclass elementClass, jobject initialElement)
4519 java_objectheader *o;
4520 java_objectarray *oa;
4523 STATISTICS(jniinvokation());
4525 c = (classinfo *) elementClass;
4526 o = (java_objectheader *) initialElement;
4529 exceptions_throw_negativearraysizeexception();
4533 oa = builtin_anewarray(length, c);
4538 /* set all elements to initialElement */
4540 for (i = 0; i < length; i++)
4543 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
4547 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
4550 java_objectarray *oa;
4551 java_objectheader *o;
4553 STATISTICS(jniinvokation());
4555 oa = (java_objectarray *) array;
4557 if (index >= oa->header.size) {
4558 exceptions_throw_arrayindexoutofboundsexception();
4562 o = oa->data[index];
4564 return _Jv_JNI_NewLocalRef(env, (jobject) o);
4568 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
4569 jsize index, jobject val)
4571 java_objectarray *oa;
4572 java_objectheader *o;
4574 STATISTICS(jniinvokation());
4576 oa = (java_objectarray *) array;
4577 o = (java_objectheader *) val;
4579 if (index >= oa->header.size) {
4580 exceptions_throw_arrayindexoutofboundsexception();
4584 /* check if the class of value is a subclass of the element class
4587 if (!builtin_canstore(oa, o))
4590 oa->data[index] = o;
4594 jbooleanArray _Jv_JNI_NewBooleanArray(JNIEnv *env, jsize len)
4596 java_booleanarray *ba;
4598 STATISTICS(jniinvokation());
4601 exceptions_throw_negativearraysizeexception();
4605 ba = builtin_newarray_boolean(len);
4607 return (jbooleanArray) _Jv_JNI_NewLocalRef(env, (jobject) ba);
4611 jbyteArray _Jv_JNI_NewByteArray(JNIEnv *env, jsize len)
4615 STATISTICS(jniinvokation());
4618 exceptions_throw_negativearraysizeexception();
4622 ba = builtin_newarray_byte(len);
4624 return (jbyteArray) _Jv_JNI_NewLocalRef(env, (jobject) ba);
4628 jcharArray _Jv_JNI_NewCharArray(JNIEnv *env, jsize len)
4632 STATISTICS(jniinvokation());
4635 exceptions_throw_negativearraysizeexception();
4639 ca = builtin_newarray_char(len);
4641 return (jcharArray) _Jv_JNI_NewLocalRef(env, (jobject) ca);
4645 jshortArray _Jv_JNI_NewShortArray(JNIEnv *env, jsize len)
4647 java_shortarray *sa;
4649 STATISTICS(jniinvokation());
4652 exceptions_throw_negativearraysizeexception();
4656 sa = builtin_newarray_short(len);
4658 return (jshortArray) _Jv_JNI_NewLocalRef(env, (jobject) sa);
4662 jintArray _Jv_JNI_NewIntArray(JNIEnv *env, jsize len)
4666 STATISTICS(jniinvokation());
4669 exceptions_throw_negativearraysizeexception();
4673 ia = builtin_newarray_int(len);
4675 return (jintArray) _Jv_JNI_NewLocalRef(env, (jobject) ia);
4679 jlongArray _Jv_JNI_NewLongArray(JNIEnv *env, jsize len)
4683 STATISTICS(jniinvokation());
4686 exceptions_throw_negativearraysizeexception();
4690 la = builtin_newarray_long(len);
4692 return (jlongArray) _Jv_JNI_NewLocalRef(env, (jobject) la);
4696 jfloatArray _Jv_JNI_NewFloatArray(JNIEnv *env, jsize len)
4698 java_floatarray *fa;
4700 STATISTICS(jniinvokation());
4703 exceptions_throw_negativearraysizeexception();
4707 fa = builtin_newarray_float(len);
4709 return (jfloatArray) _Jv_JNI_NewLocalRef(env, (jobject) fa);
4713 jdoubleArray _Jv_JNI_NewDoubleArray(JNIEnv *env, jsize len)
4715 java_doublearray *da;
4717 STATISTICS(jniinvokation());
4720 exceptions_throw_negativearraysizeexception();
4724 da = builtin_newarray_double(len);
4726 return (jdoubleArray) _Jv_JNI_NewLocalRef(env, (jobject) da);
4730 /* Get<PrimitiveType>ArrayElements *********************************************
4732 A family of functions that returns the body of the primitive array.
4734 *******************************************************************************/
4736 jboolean *_Jv_JNI_GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
4739 java_booleanarray *ba;
4741 STATISTICS(jniinvokation());
4743 ba = (java_booleanarray *) array;
4746 *isCopy = JNI_FALSE;
4752 jbyte *_Jv_JNI_GetByteArrayElements(JNIEnv *env, jbyteArray array,
4757 STATISTICS(jniinvokation());
4759 ba = (java_bytearray *) array;
4762 *isCopy = JNI_FALSE;
4768 jchar *_Jv_JNI_GetCharArrayElements(JNIEnv *env, jcharArray array,
4773 STATISTICS(jniinvokation());
4775 ca = (java_chararray *) array;
4778 *isCopy = JNI_FALSE;
4784 jshort *_Jv_JNI_GetShortArrayElements(JNIEnv *env, jshortArray array,
4787 java_shortarray *sa;
4789 STATISTICS(jniinvokation());
4791 sa = (java_shortarray *) array;
4794 *isCopy = JNI_FALSE;
4800 jint *_Jv_JNI_GetIntArrayElements(JNIEnv *env, jintArray array,
4805 STATISTICS(jniinvokation());
4807 ia = (java_intarray *) array;
4810 *isCopy = JNI_FALSE;
4816 jlong *_Jv_JNI_GetLongArrayElements(JNIEnv *env, jlongArray array,
4821 STATISTICS(jniinvokation());
4823 la = (java_longarray *) array;
4826 *isCopy = JNI_FALSE;
4828 /* We cast this one to prevent a compiler warning on 64-bit
4829 systems since GNU Classpath typedef jlong to long long. */
4831 return (jlong *) la->data;
4835 jfloat *_Jv_JNI_GetFloatArrayElements(JNIEnv *env, jfloatArray array,
4838 java_floatarray *fa;
4840 STATISTICS(jniinvokation());
4842 fa = (java_floatarray *) array;
4845 *isCopy = JNI_FALSE;
4851 jdouble *_Jv_JNI_GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
4854 java_doublearray *da;
4856 STATISTICS(jniinvokation());
4858 da = (java_doublearray *) array;
4861 *isCopy = JNI_FALSE;
4867 /* Release<PrimitiveType>ArrayElements *****************************************
4869 A family of functions that informs the VM that the native code no
4870 longer needs access to elems. The elems argument is a pointer
4871 derived from array using the corresponding
4872 Get<PrimitiveType>ArrayElements() function. If necessary, this
4873 function copies back all changes made to elems to the original
4876 *******************************************************************************/
4878 void _Jv_JNI_ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
4879 jboolean *elems, jint mode)
4881 java_booleanarray *ba;
4883 STATISTICS(jniinvokation());
4885 ba = (java_booleanarray *) array;
4887 if (elems != ba->data) {
4890 MCOPY(ba->data, elems, u1, ba->header.size);
4893 MCOPY(ba->data, elems, u1, ba->header.size);
4894 /* XXX TWISTI how should it be freed? */
4897 /* XXX TWISTI how should it be freed? */
4904 void _Jv_JNI_ReleaseByteArrayElements(JNIEnv *env, jbyteArray array,
4905 jbyte *elems, jint mode)
4909 STATISTICS(jniinvokation());
4911 ba = (java_bytearray *) array;
4913 if (elems != ba->data) {
4916 MCOPY(ba->data, elems, s1, ba->header.size);
4919 MCOPY(ba->data, elems, s1, ba->header.size);
4920 /* XXX TWISTI how should it be freed? */
4923 /* XXX TWISTI how should it be freed? */
4930 void _Jv_JNI_ReleaseCharArrayElements(JNIEnv *env, jcharArray array,
4931 jchar *elems, jint mode)
4935 STATISTICS(jniinvokation());
4937 ca = (java_chararray *) array;
4939 if (elems != ca->data) {
4942 MCOPY(ca->data, elems, u2, ca->header.size);
4945 MCOPY(ca->data, elems, u2, ca->header.size);
4946 /* XXX TWISTI how should it be freed? */
4949 /* XXX TWISTI how should it be freed? */
4956 void _Jv_JNI_ReleaseShortArrayElements(JNIEnv *env, jshortArray array,
4957 jshort *elems, jint mode)
4959 java_shortarray *sa;
4961 STATISTICS(jniinvokation());
4963 sa = (java_shortarray *) array;
4965 if (elems != sa->data) {
4968 MCOPY(sa->data, elems, s2, sa->header.size);
4971 MCOPY(sa->data, elems, s2, sa->header.size);
4972 /* XXX TWISTI how should it be freed? */
4975 /* XXX TWISTI how should it be freed? */
4982 void _Jv_JNI_ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
4987 STATISTICS(jniinvokation());
4989 ia = (java_intarray *) array;
4991 if (elems != ia->data) {
4994 MCOPY(ia->data, elems, s4, ia->header.size);
4997 MCOPY(ia->data, elems, s4, ia->header.size);
4998 /* XXX TWISTI how should it be freed? */
5001 /* XXX TWISTI how should it be freed? */
5008 void _Jv_JNI_ReleaseLongArrayElements(JNIEnv *env, jlongArray array,
5009 jlong *elems, jint mode)
5013 STATISTICS(jniinvokation());
5015 la = (java_longarray *) array;
5017 /* We cast this one to prevent a compiler warning on 64-bit
5018 systems since GNU Classpath typedef jlong to long long. */
5020 if ((s8 *) elems != la->data) {
5023 MCOPY(la->data, elems, s8, la->header.size);
5026 MCOPY(la->data, elems, s8, la->header.size);
5027 /* XXX TWISTI how should it be freed? */
5030 /* XXX TWISTI how should it be freed? */
5037 void _Jv_JNI_ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array,
5038 jfloat *elems, jint mode)
5040 java_floatarray *fa;
5042 STATISTICS(jniinvokation());
5044 fa = (java_floatarray *) array;
5046 if (elems != fa->data) {
5049 MCOPY(fa->data, elems, float, fa->header.size);
5052 MCOPY(fa->data, elems, float, fa->header.size);
5053 /* XXX TWISTI how should it be freed? */
5056 /* XXX TWISTI how should it be freed? */
5063 void _Jv_JNI_ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
5064 jdouble *elems, jint mode)
5066 java_doublearray *da;
5068 STATISTICS(jniinvokation());
5070 da = (java_doublearray *) array;
5072 if (elems != da->data) {
5075 MCOPY(da->data, elems, double, da->header.size);
5078 MCOPY(da->data, elems, double, da->header.size);
5079 /* XXX TWISTI how should it be freed? */
5082 /* XXX TWISTI how should it be freed? */
5089 /* Get<PrimitiveType>ArrayRegion **********************************************
5091 A family of functions that copies a region of a primitive array
5094 *******************************************************************************/
5096 void _Jv_JNI_GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array,
5097 jsize start, jsize len, jboolean *buf)
5099 java_booleanarray *ba;
5101 STATISTICS(jniinvokation());
5103 ba = (java_booleanarray *) array;
5105 if ((start < 0) || (len < 0) || (start + len > ba->header.size))
5106 exceptions_throw_arrayindexoutofboundsexception();
5108 MCOPY(buf, &ba->data[start], u1, len);
5112 void _Jv_JNI_GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start,
5113 jsize len, jbyte *buf)
5117 STATISTICS(jniinvokation());
5119 ba = (java_bytearray *) array;
5121 if ((start < 0) || (len < 0) || (start + len > ba->header.size))
5122 exceptions_throw_arrayindexoutofboundsexception();
5124 MCOPY(buf, &ba->data[start], s1, len);
5128 void _Jv_JNI_GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start,
5129 jsize len, jchar *buf)
5133 STATISTICS(jniinvokation());
5135 ca = (java_chararray *) array;
5137 if ((start < 0) || (len < 0) || (start + len > ca->header.size))
5138 exceptions_throw_arrayindexoutofboundsexception();
5140 MCOPY(buf, &ca->data[start], u2, len);
5144 void _Jv_JNI_GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
5145 jsize len, jshort *buf)
5147 java_shortarray *sa;
5149 STATISTICS(jniinvokation());
5151 sa = (java_shortarray *) array;
5153 if ((start < 0) || (len < 0) || (start + len > sa->header.size))
5154 exceptions_throw_arrayindexoutofboundsexception();
5156 MCOPY(buf, &sa->data[start], s2, len);
5160 void _Jv_JNI_GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start,
5161 jsize len, jint *buf)
5165 STATISTICS(jniinvokation());
5167 ia = (java_intarray *) array;
5169 if ((start < 0) || (len < 0) || (start + len > ia->header.size))
5170 exceptions_throw_arrayindexoutofboundsexception();
5172 MCOPY(buf, &ia->data[start], s4, len);
5176 void _Jv_JNI_GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start,
5177 jsize len, jlong *buf)
5181 STATISTICS(jniinvokation());
5183 la = (java_longarray *) array;
5185 if ((start < 0) || (len < 0) || (start + len > la->header.size))
5186 exceptions_throw_arrayindexoutofboundsexception();
5188 MCOPY(buf, &la->data[start], s8, len);
5192 void _Jv_JNI_GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
5193 jsize len, jfloat *buf)
5195 java_floatarray *fa;
5197 STATISTICS(jniinvokation());
5199 fa = (java_floatarray *) array;
5201 if ((start < 0) || (len < 0) || (start + len > fa->header.size))
5202 exceptions_throw_arrayindexoutofboundsexception();
5204 MCOPY(buf, &fa->data[start], float, len);
5208 void _Jv_JNI_GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
5209 jsize len, jdouble *buf)
5211 java_doublearray *da;
5213 STATISTICS(jniinvokation());
5215 da = (java_doublearray *) array;
5217 if ((start < 0) || (len < 0) || (start + len > da->header.size))
5218 exceptions_throw_arrayindexoutofboundsexception();
5220 MCOPY(buf, &da->data[start], double, len);
5224 /* Set<PrimitiveType>ArrayRegion **********************************************
5226 A family of functions that copies back a region of a primitive
5227 array from a buffer.
5229 *******************************************************************************/
5231 void _Jv_JNI_SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array,
5232 jsize start, jsize len, const jboolean *buf)
5234 java_booleanarray *ba;
5236 STATISTICS(jniinvokation());
5238 ba = (java_booleanarray *) array;
5240 if ((start < 0) || (len < 0) || (start + len > ba->header.size))
5241 exceptions_throw_arrayindexoutofboundsexception();
5243 MCOPY(&ba->data[start], buf, u1, len);
5247 void _Jv_JNI_SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start,
5248 jsize len, const jbyte *buf)
5252 STATISTICS(jniinvokation());
5254 ba = (java_bytearray *) array;
5256 if ((start < 0) || (len < 0) || (start + len > ba->header.size))
5257 exceptions_throw_arrayindexoutofboundsexception();
5259 MCOPY(&ba->data[start], buf, s1, len);
5263 void _Jv_JNI_SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start,
5264 jsize len, const jchar *buf)
5268 STATISTICS(jniinvokation());
5270 ca = (java_chararray *) array;
5272 if ((start < 0) || (len < 0) || (start + len > ca->header.size))
5273 exceptions_throw_arrayindexoutofboundsexception();
5275 MCOPY(&ca->data[start], buf, u2, len);
5279 void _Jv_JNI_SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
5280 jsize len, const jshort *buf)
5282 java_shortarray *sa;
5284 STATISTICS(jniinvokation());
5286 sa = (java_shortarray *) array;
5288 if ((start < 0) || (len < 0) || (start + len > sa->header.size))
5289 exceptions_throw_arrayindexoutofboundsexception();
5291 MCOPY(&sa->data[start], buf, s2, len);
5295 void _Jv_JNI_SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start,
5296 jsize len, const jint *buf)
5300 STATISTICS(jniinvokation());
5302 ia = (java_intarray *) array;
5304 if ((start < 0) || (len < 0) || (start + len > ia->header.size))
5305 exceptions_throw_arrayindexoutofboundsexception();
5307 MCOPY(&ia->data[start], buf, s4, len);
5311 void _Jv_JNI_SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start,
5312 jsize len, const jlong *buf)
5316 STATISTICS(jniinvokation());
5318 la = (java_longarray *) array;
5320 if ((start < 0) || (len < 0) || (start + len > la->header.size))
5321 exceptions_throw_arrayindexoutofboundsexception();
5323 MCOPY(&la->data[start], buf, s8, len);
5327 void _Jv_JNI_SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
5328 jsize len, const jfloat *buf)
5330 java_floatarray *fa;
5332 STATISTICS(jniinvokation());
5334 fa = (java_floatarray *) array;
5336 if ((start < 0) || (len < 0) || (start + len > fa->header.size))
5337 exceptions_throw_arrayindexoutofboundsexception();
5339 MCOPY(&fa->data[start], buf, float, len);
5343 void _Jv_JNI_SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
5344 jsize len, const jdouble *buf)
5346 java_doublearray *da;
5348 STATISTICS(jniinvokation());
5350 da = (java_doublearray *) array;
5352 if ((start < 0) || (len < 0) || (start + len > da->header.size))
5353 exceptions_throw_arrayindexoutofboundsexception();
5355 MCOPY(&da->data[start], buf, double, len);
5359 /* Registering Native Methods *************************************************/
5361 /* RegisterNatives *************************************************************
5363 Registers native methods with the class specified by the clazz
5364 argument. The methods parameter specifies an array of
5365 JNINativeMethod structures that contain the names, signatures, and
5366 function pointers of the native methods. The nMethods parameter
5367 specifies the number of native methods in the array.
5369 *******************************************************************************/
5371 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
5372 const JNINativeMethod *methods, jint nMethods)
5376 STATISTICS(jniinvokation());
5378 c = (classinfo *) clazz;
5380 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
5381 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
5384 native_method_register(c->name, methods, nMethods);
5390 /* UnregisterNatives ***********************************************************
5392 Unregisters native methods of a class. The class goes back to the
5393 state before it was linked or registered with its native method
5396 This function should not be used in normal native code. Instead, it
5397 provides special programs a way to reload and relink native
5400 *******************************************************************************/
5402 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
5404 STATISTICS(jniinvokation());
5406 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
5408 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
5414 /* Monitor Operations *********************************************************/
5416 /* MonitorEnter ****************************************************************
5418 Enters the monitor associated with the underlying Java object
5421 *******************************************************************************/
5423 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
5425 STATISTICS(jniinvokation());
5428 exceptions_throw_nullpointerexception();
5432 LOCK_MONITOR_ENTER(obj);
5438 /* MonitorExit *****************************************************************
5440 The current thread must be the owner of the monitor associated with
5441 the underlying Java object referred to by obj. The thread
5442 decrements the counter indicating the number of times it has
5443 entered this monitor. If the value of the counter becomes zero, the
5444 current thread releases the monitor.
5446 *******************************************************************************/
5448 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
5450 STATISTICS(jniinvokation());
5453 exceptions_throw_nullpointerexception();
5457 LOCK_MONITOR_EXIT(obj);
5463 /* JavaVM Interface ***********************************************************/
5465 /* GetJavaVM *******************************************************************
5467 Returns the Java VM interface (used in the Invocation API)
5468 associated with the current thread. The result is placed at the
5469 location pointed to by the second argument, vm.
5471 *******************************************************************************/
5473 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
5475 STATISTICS(jniinvokation());
5477 *vm = (JavaVM *) _Jv_jvm;
5483 /* GetStringRegion *************************************************************
5485 Copies len number of Unicode characters beginning at offset start
5486 to the given buffer buf.
5488 Throws StringIndexOutOfBoundsException on index overflow.
5490 *******************************************************************************/
5492 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
5495 java_lang_String *s;
5498 STATISTICS(jniinvokation());
5500 s = (java_lang_String *) str;
5503 if ((start < 0) || (len < 0) || (start > s->count) ||
5504 (start + len > s->count)) {
5505 exceptions_throw_stringindexoutofboundsexception();
5509 MCOPY(buf, &ca->data[start], u2, len);
5513 /* GetStringUTFRegion **********************************************************
5515 Translates len number of Unicode characters beginning at offset
5516 start into UTF-8 format and place the result in the given buffer
5519 Throws StringIndexOutOfBoundsException on index overflow.
5521 *******************************************************************************/
5523 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
5524 jsize len, char *buf)
5526 java_lang_String *s;
5530 STATISTICS(jniinvokation());
5532 s = (java_lang_String *) str;
5535 if ((start < 0) || (len < 0) || (start > s->count) ||
5536 (start + len > s->count)) {
5537 exceptions_throw_stringindexoutofboundsexception();
5541 /* XXX not sure if this is correct */
5543 for (i = 0; i < len; i++)
5544 buf[i] = ca->data[start + i];
5550 /* GetPrimitiveArrayCritical ***************************************************
5552 Obtain a direct pointer to array elements.
5554 *******************************************************************************/
5556 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
5562 ba = (java_bytearray *) array;
5564 /* do the same as Kaffe does */
5566 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
5572 /* ReleasePrimitiveArrayCritical ***********************************************
5574 No specific documentation.
5576 *******************************************************************************/
5578 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
5579 void *carray, jint mode)
5581 STATISTICS(jniinvokation());
5583 /* do the same as Kaffe does */
5585 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
5590 /* GetStringCritical ***********************************************************
5592 The semantics of these two functions are similar to the existing
5593 Get/ReleaseStringChars functions.
5595 *******************************************************************************/
5597 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
5600 STATISTICS(jniinvokation());
5602 return _Jv_JNI_GetStringChars(env, string, isCopy);
5606 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
5607 const jchar *cstring)
5609 STATISTICS(jniinvokation());
5611 _Jv_JNI_ReleaseStringChars(env, string, cstring);
5615 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
5617 STATISTICS(jniinvokation());
5619 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
5625 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
5627 STATISTICS(jniinvokation());
5629 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
5633 /* NewGlobalRef ****************************************************************
5635 Creates a new global reference to the object referred to by the obj
5638 *******************************************************************************/
5640 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
5642 hashtable_global_ref_entry *gre;
5643 u4 key; /* hashkey */
5644 u4 slot; /* slot in hashtable */
5645 java_objectheader *o;
5647 STATISTICS(jniinvokation());
5649 o = (java_objectheader *) obj;
5651 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
5653 /* normally addresses are aligned to 4, 8 or 16 bytes */
5655 key = ((u4) (ptrint) obj) >> 4; /* align to 16-byte boundaries */
5656 slot = key & (hashtable_global_ref->size - 1);
5657 gre = hashtable_global_ref->ptr[slot];
5659 /* search external hash chain for the entry */
5663 /* global object found, increment the reference */
5667 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5672 gre = gre->hashlink; /* next element in external chain */
5675 /* global ref not found, create a new one */
5677 gre = NEW(hashtable_global_ref_entry);
5682 /* insert entry into hashtable */
5684 gre->hashlink = hashtable_global_ref->ptr[slot];
5686 hashtable_global_ref->ptr[slot] = gre;
5688 /* update number of hashtable-entries */
5690 hashtable_global_ref->entries++;
5692 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5698 /* DeleteGlobalRef *************************************************************
5700 Deletes the global reference pointed to by globalRef.
5702 *******************************************************************************/
5704 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
5706 hashtable_global_ref_entry *gre;
5707 hashtable_global_ref_entry *prevgre;
5708 u4 key; /* hashkey */
5709 u4 slot; /* slot in hashtable */
5710 java_objectheader *o;
5712 STATISTICS(jniinvokation());
5714 o = (java_objectheader *) globalRef;
5716 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
5718 /* normally addresses are aligned to 4, 8 or 16 bytes */
5720 key = ((u4) (ptrint) globalRef) >> 4; /* align to 16-byte boundaries */
5721 slot = key & (hashtable_global_ref->size - 1);
5722 gre = hashtable_global_ref->ptr[slot];
5724 /* initialize prevgre */
5728 /* search external hash chain for the entry */
5732 /* global object found, decrement the reference count */
5736 /* if reference count is 0, remove the entry */
5738 if (gre->refs == 0) {
5739 /* special handling if it's the first in the chain */
5741 if (prevgre == NULL)
5742 hashtable_global_ref->ptr[slot] = gre->hashlink;
5744 prevgre->hashlink = gre->hashlink;
5746 FREE(gre, hashtable_global_ref_entry);
5749 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5754 prevgre = gre; /* save current pointer for removal */
5755 gre = gre->hashlink; /* next element in external chain */
5758 log_println("JNI-DeleteGlobalRef: global reference not found");
5760 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5764 /* ExceptionCheck **************************************************************
5766 Returns JNI_TRUE when there is a pending exception; otherwise,
5769 *******************************************************************************/
5771 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
5773 java_objectheader *o;
5775 STATISTICS(jniinvokation());
5777 o = exceptions_get_exception();
5779 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
5783 /* New JNI 1.4 functions ******************************************************/
5785 /* NewDirectByteBuffer *********************************************************
5787 Allocates and returns a direct java.nio.ByteBuffer referring to the
5788 block of memory starting at the memory address address and
5789 extending capacity bytes.
5791 *******************************************************************************/
5793 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
5795 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
5796 java_objectheader *nbuf;
5798 # if SIZEOF_VOID_P == 8
5799 gnu_classpath_Pointer64 *paddress;
5801 gnu_classpath_Pointer32 *paddress;
5804 STATISTICS(jniinvokation());
5806 /* alocate a gnu.classpath.Pointer{32,64} object */
5808 # if SIZEOF_VOID_P == 8
5809 if (!(paddress = (gnu_classpath_Pointer64 *)
5810 builtin_new(class_gnu_classpath_Pointer64)))
5812 if (!(paddress = (gnu_classpath_Pointer32 *)
5813 builtin_new(class_gnu_classpath_Pointer32)))
5817 /* fill gnu.classpath.Pointer{32,64} with address */
5819 paddress->data = (ptrint) address;
5821 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
5823 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
5824 (jmethodID) dbbirw_init, NULL, paddress,
5825 (jint) capacity, (jint) capacity, (jint) 0);
5827 /* add local reference and return the value */
5829 return _Jv_JNI_NewLocalRef(env, nbuf);
5831 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
5833 /* keep compiler happy */
5840 /* GetDirectBufferAddress ******************************************************
5842 Fetches and returns the starting address of the memory region
5843 referenced by the given direct java.nio.Buffer.
5845 *******************************************************************************/
5847 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
5849 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
5850 java_nio_DirectByteBufferImpl *nbuf;
5851 # if SIZEOF_VOID_P == 8
5852 gnu_classpath_Pointer64 *address;
5854 gnu_classpath_Pointer32 *address;
5857 STATISTICS(jniinvokation());
5859 if (!builtin_instanceof(buf, class_java_nio_Buffer))
5862 nbuf = (java_nio_DirectByteBufferImpl *) buf;
5864 # if SIZEOF_VOID_P == 8
5865 address = (gnu_classpath_Pointer64 *) nbuf->address;
5867 address = (gnu_classpath_Pointer32 *) nbuf->address;
5870 if (address == NULL)
5873 return (void *) address->data;
5875 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
5877 /* keep compiler happy */
5884 /* GetDirectBufferCapacity *****************************************************
5886 Fetches and returns the capacity in bytes of the memory region
5887 referenced by the given direct java.nio.Buffer.
5889 *******************************************************************************/
5891 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
5893 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
5894 java_objectheader *o;
5895 java_nio_Buffer *nbuf;
5897 STATISTICS(jniinvokation());
5899 o = (java_objectheader *) buf;
5901 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
5904 nbuf = (java_nio_Buffer *) o;
5906 return (jlong) nbuf->cap;
5908 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
5910 /* keep compiler happy */
5917 /* DestroyJavaVM ***************************************************************
5919 Unloads a Java VM and reclaims its resources. Only the main thread
5920 can unload the VM. The system waits until the main thread is only
5921 remaining user thread before it destroys the VM.
5923 *******************************************************************************/
5925 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
5929 STATISTICS(jniinvokation());
5931 status = vm_destroy(vm);
5937 /* AttachCurrentThread *********************************************************
5939 Attaches the current thread to a Java VM. Returns a JNI interface
5940 pointer in the JNIEnv argument.
5942 Trying to attach a thread that is already attached is a no-op.
5944 A native thread cannot be attached simultaneously to two Java VMs.
5946 When a thread is attached to the VM, the context class loader is
5947 the bootstrap loader.
5949 *******************************************************************************/
5951 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
5953 JavaVMAttachArgs *vm_aargs;
5955 #if defined(ENABLE_THREADS)
5956 if (threads_get_current_threadobject() == NULL) {
5957 vm_aargs = (JavaVMAttachArgs *) thr_args;
5959 if (vm_aargs != NULL) {
5960 if ((vm_aargs->version != JNI_VERSION_1_2) &&
5961 (vm_aargs->version != JNI_VERSION_1_4))
5962 return JNI_EVERSION;
5965 if (!threads_attach_current_thread(vm_aargs, false))
5968 if (!jni_init_localref_table())
5979 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
5981 STATISTICS(jniinvokation());
5983 return jni_attach_current_thread(p_env, thr_args, false);
5987 /* DetachCurrentThread *********************************************************
5989 Detaches the current thread from a Java VM. All Java monitors held
5990 by this thread are released. All Java threads waiting for this
5991 thread to die are notified.
5993 In JDK 1.1, the main thread cannot be detached from the VM. It must
5994 call DestroyJavaVM to unload the entire VM.
5996 In the JDK, the main thread can be detached from the VM.
5998 The main thread, which is the thread that created the Java VM,
5999 cannot be detached from the VM. Instead, the main thread must call
6000 JNI_DestroyJavaVM() to unload the entire VM.
6002 *******************************************************************************/
6004 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
6006 #if defined(ENABLE_THREADS)
6007 threadobject *thread;
6009 STATISTICS(jniinvokation());
6011 thread = threads_get_current_threadobject();
6016 if (!threads_detach_thread(thread))
6024 /* GetEnv **********************************************************************
6026 If the current thread is not attached to the VM, sets *env to NULL,
6027 and returns JNI_EDETACHED. If the specified version is not
6028 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
6029 sets *env to the appropriate interface, and returns JNI_OK.
6031 *******************************************************************************/
6033 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
6035 STATISTICS(jniinvokation());
6037 #if defined(ENABLE_THREADS)
6038 if (threads_get_current_threadobject() == NULL) {
6041 return JNI_EDETACHED;
6045 /* check the JNI version */
6048 case JNI_VERSION_1_1:
6049 case JNI_VERSION_1_2:
6050 case JNI_VERSION_1_4:
6058 #if defined(ENABLE_JVMTI)
6059 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
6060 == JVMTI_VERSION_INTERFACE_JVMTI) {
6062 *env = (void *) jvmti_new_environment();
6071 return JNI_EVERSION;
6075 /* AttachCurrentThreadAsDaemon *************************************************
6077 Same semantics as AttachCurrentThread, but the newly-created
6078 java.lang.Thread instance is a daemon.
6080 If the thread has already been attached via either
6081 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
6082 simply sets the value pointed to by penv to the JNIEnv of the
6083 current thread. In this case neither AttachCurrentThread nor this
6084 routine have any effect on the daemon status of the thread.
6086 *******************************************************************************/
6088 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
6090 STATISTICS(jniinvokation());
6092 return jni_attach_current_thread(penv, args, true);
6096 /* JNI invocation table *******************************************************/
6098 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
6103 _Jv_JNI_DestroyJavaVM,
6104 _Jv_JNI_AttachCurrentThread,
6105 _Jv_JNI_DetachCurrentThread,
6107 _Jv_JNI_AttachCurrentThreadAsDaemon
6111 /* JNI function table *********************************************************/
6113 struct JNINativeInterface_ _Jv_JNINativeInterface = {
6120 _Jv_JNI_DefineClass,
6122 _Jv_JNI_FromReflectedMethod,
6123 _Jv_JNI_FromReflectedField,
6124 _Jv_JNI_ToReflectedMethod,
6125 _Jv_JNI_GetSuperclass,
6126 _Jv_JNI_IsAssignableFrom,
6127 _Jv_JNI_ToReflectedField,
6131 _Jv_JNI_ExceptionOccurred,
6132 _Jv_JNI_ExceptionDescribe,
6133 _Jv_JNI_ExceptionClear,
6135 _Jv_JNI_PushLocalFrame,
6136 _Jv_JNI_PopLocalFrame,
6138 _Jv_JNI_NewGlobalRef,
6139 _Jv_JNI_DeleteGlobalRef,
6140 _Jv_JNI_DeleteLocalRef,
6141 _Jv_JNI_IsSameObject,
6142 _Jv_JNI_NewLocalRef,
6143 _Jv_JNI_EnsureLocalCapacity,
6145 _Jv_JNI_AllocObject,
6150 _Jv_JNI_GetObjectClass,
6151 _Jv_JNI_IsInstanceOf,
6153 _Jv_JNI_GetMethodID,
6155 _Jv_JNI_CallObjectMethod,
6156 _Jv_JNI_CallObjectMethodV,
6157 _Jv_JNI_CallObjectMethodA,
6158 _Jv_JNI_CallBooleanMethod,
6159 _Jv_JNI_CallBooleanMethodV,
6160 _Jv_JNI_CallBooleanMethodA,
6161 _Jv_JNI_CallByteMethod,
6162 _Jv_JNI_CallByteMethodV,
6163 _Jv_JNI_CallByteMethodA,
6164 _Jv_JNI_CallCharMethod,
6165 _Jv_JNI_CallCharMethodV,
6166 _Jv_JNI_CallCharMethodA,
6167 _Jv_JNI_CallShortMethod,
6168 _Jv_JNI_CallShortMethodV,
6169 _Jv_JNI_CallShortMethodA,
6170 _Jv_JNI_CallIntMethod,
6171 _Jv_JNI_CallIntMethodV,
6172 _Jv_JNI_CallIntMethodA,
6173 _Jv_JNI_CallLongMethod,
6174 _Jv_JNI_CallLongMethodV,
6175 _Jv_JNI_CallLongMethodA,
6176 _Jv_JNI_CallFloatMethod,
6177 _Jv_JNI_CallFloatMethodV,
6178 _Jv_JNI_CallFloatMethodA,
6179 _Jv_JNI_CallDoubleMethod,
6180 _Jv_JNI_CallDoubleMethodV,
6181 _Jv_JNI_CallDoubleMethodA,
6182 _Jv_JNI_CallVoidMethod,
6183 _Jv_JNI_CallVoidMethodV,
6184 _Jv_JNI_CallVoidMethodA,
6186 _Jv_JNI_CallNonvirtualObjectMethod,
6187 _Jv_JNI_CallNonvirtualObjectMethodV,
6188 _Jv_JNI_CallNonvirtualObjectMethodA,
6189 _Jv_JNI_CallNonvirtualBooleanMethod,
6190 _Jv_JNI_CallNonvirtualBooleanMethodV,
6191 _Jv_JNI_CallNonvirtualBooleanMethodA,
6192 _Jv_JNI_CallNonvirtualByteMethod,
6193 _Jv_JNI_CallNonvirtualByteMethodV,
6194 _Jv_JNI_CallNonvirtualByteMethodA,
6195 _Jv_JNI_CallNonvirtualCharMethod,
6196 _Jv_JNI_CallNonvirtualCharMethodV,
6197 _Jv_JNI_CallNonvirtualCharMethodA,
6198 _Jv_JNI_CallNonvirtualShortMethod,
6199 _Jv_JNI_CallNonvirtualShortMethodV,
6200 _Jv_JNI_CallNonvirtualShortMethodA,
6201 _Jv_JNI_CallNonvirtualIntMethod,
6202 _Jv_JNI_CallNonvirtualIntMethodV,
6203 _Jv_JNI_CallNonvirtualIntMethodA,
6204 _Jv_JNI_CallNonvirtualLongMethod,
6205 _Jv_JNI_CallNonvirtualLongMethodV,
6206 _Jv_JNI_CallNonvirtualLongMethodA,
6207 _Jv_JNI_CallNonvirtualFloatMethod,
6208 _Jv_JNI_CallNonvirtualFloatMethodV,
6209 _Jv_JNI_CallNonvirtualFloatMethodA,
6210 _Jv_JNI_CallNonvirtualDoubleMethod,
6211 _Jv_JNI_CallNonvirtualDoubleMethodV,
6212 _Jv_JNI_CallNonvirtualDoubleMethodA,
6213 _Jv_JNI_CallNonvirtualVoidMethod,
6214 _Jv_JNI_CallNonvirtualVoidMethodV,
6215 _Jv_JNI_CallNonvirtualVoidMethodA,
6219 _Jv_JNI_GetObjectField,
6220 _Jv_JNI_GetBooleanField,
6221 _Jv_JNI_GetByteField,
6222 _Jv_JNI_GetCharField,
6223 _Jv_JNI_GetShortField,
6224 _Jv_JNI_GetIntField,
6225 _Jv_JNI_GetLongField,
6226 _Jv_JNI_GetFloatField,
6227 _Jv_JNI_GetDoubleField,
6228 _Jv_JNI_SetObjectField,
6229 _Jv_JNI_SetBooleanField,
6230 _Jv_JNI_SetByteField,
6231 _Jv_JNI_SetCharField,
6232 _Jv_JNI_SetShortField,
6233 _Jv_JNI_SetIntField,
6234 _Jv_JNI_SetLongField,
6235 _Jv_JNI_SetFloatField,
6236 _Jv_JNI_SetDoubleField,
6238 _Jv_JNI_GetStaticMethodID,
6240 _Jv_JNI_CallStaticObjectMethod,
6241 _Jv_JNI_CallStaticObjectMethodV,
6242 _Jv_JNI_CallStaticObjectMethodA,
6243 _Jv_JNI_CallStaticBooleanMethod,
6244 _Jv_JNI_CallStaticBooleanMethodV,
6245 _Jv_JNI_CallStaticBooleanMethodA,
6246 _Jv_JNI_CallStaticByteMethod,
6247 _Jv_JNI_CallStaticByteMethodV,
6248 _Jv_JNI_CallStaticByteMethodA,
6249 _Jv_JNI_CallStaticCharMethod,
6250 _Jv_JNI_CallStaticCharMethodV,
6251 _Jv_JNI_CallStaticCharMethodA,
6252 _Jv_JNI_CallStaticShortMethod,
6253 _Jv_JNI_CallStaticShortMethodV,
6254 _Jv_JNI_CallStaticShortMethodA,
6255 _Jv_JNI_CallStaticIntMethod,
6256 _Jv_JNI_CallStaticIntMethodV,
6257 _Jv_JNI_CallStaticIntMethodA,
6258 _Jv_JNI_CallStaticLongMethod,
6259 _Jv_JNI_CallStaticLongMethodV,
6260 _Jv_JNI_CallStaticLongMethodA,
6261 _Jv_JNI_CallStaticFloatMethod,
6262 _Jv_JNI_CallStaticFloatMethodV,
6263 _Jv_JNI_CallStaticFloatMethodA,
6264 _Jv_JNI_CallStaticDoubleMethod,
6265 _Jv_JNI_CallStaticDoubleMethodV,
6266 _Jv_JNI_CallStaticDoubleMethodA,
6267 _Jv_JNI_CallStaticVoidMethod,
6268 _Jv_JNI_CallStaticVoidMethodV,
6269 _Jv_JNI_CallStaticVoidMethodA,
6271 _Jv_JNI_GetStaticFieldID,
6273 _Jv_JNI_GetStaticObjectField,
6274 _Jv_JNI_GetStaticBooleanField,
6275 _Jv_JNI_GetStaticByteField,
6276 _Jv_JNI_GetStaticCharField,
6277 _Jv_JNI_GetStaticShortField,
6278 _Jv_JNI_GetStaticIntField,
6279 _Jv_JNI_GetStaticLongField,
6280 _Jv_JNI_GetStaticFloatField,
6281 _Jv_JNI_GetStaticDoubleField,
6282 _Jv_JNI_SetStaticObjectField,
6283 _Jv_JNI_SetStaticBooleanField,
6284 _Jv_JNI_SetStaticByteField,
6285 _Jv_JNI_SetStaticCharField,
6286 _Jv_JNI_SetStaticShortField,
6287 _Jv_JNI_SetStaticIntField,
6288 _Jv_JNI_SetStaticLongField,
6289 _Jv_JNI_SetStaticFloatField,
6290 _Jv_JNI_SetStaticDoubleField,
6293 _Jv_JNI_GetStringLength,
6294 _Jv_JNI_GetStringChars,
6295 _Jv_JNI_ReleaseStringChars,
6297 _Jv_JNI_NewStringUTF,
6298 _Jv_JNI_GetStringUTFLength,
6299 _Jv_JNI_GetStringUTFChars,
6300 _Jv_JNI_ReleaseStringUTFChars,
6302 _Jv_JNI_GetArrayLength,
6304 _Jv_JNI_NewObjectArray,
6305 _Jv_JNI_GetObjectArrayElement,
6306 _Jv_JNI_SetObjectArrayElement,
6308 _Jv_JNI_NewBooleanArray,
6309 _Jv_JNI_NewByteArray,
6310 _Jv_JNI_NewCharArray,
6311 _Jv_JNI_NewShortArray,
6312 _Jv_JNI_NewIntArray,
6313 _Jv_JNI_NewLongArray,
6314 _Jv_JNI_NewFloatArray,
6315 _Jv_JNI_NewDoubleArray,
6317 _Jv_JNI_GetBooleanArrayElements,
6318 _Jv_JNI_GetByteArrayElements,
6319 _Jv_JNI_GetCharArrayElements,
6320 _Jv_JNI_GetShortArrayElements,
6321 _Jv_JNI_GetIntArrayElements,
6322 _Jv_JNI_GetLongArrayElements,
6323 _Jv_JNI_GetFloatArrayElements,
6324 _Jv_JNI_GetDoubleArrayElements,
6326 _Jv_JNI_ReleaseBooleanArrayElements,
6327 _Jv_JNI_ReleaseByteArrayElements,
6328 _Jv_JNI_ReleaseCharArrayElements,
6329 _Jv_JNI_ReleaseShortArrayElements,
6330 _Jv_JNI_ReleaseIntArrayElements,
6331 _Jv_JNI_ReleaseLongArrayElements,
6332 _Jv_JNI_ReleaseFloatArrayElements,
6333 _Jv_JNI_ReleaseDoubleArrayElements,
6335 _Jv_JNI_GetBooleanArrayRegion,
6336 _Jv_JNI_GetByteArrayRegion,
6337 _Jv_JNI_GetCharArrayRegion,
6338 _Jv_JNI_GetShortArrayRegion,
6339 _Jv_JNI_GetIntArrayRegion,
6340 _Jv_JNI_GetLongArrayRegion,
6341 _Jv_JNI_GetFloatArrayRegion,
6342 _Jv_JNI_GetDoubleArrayRegion,
6343 _Jv_JNI_SetBooleanArrayRegion,
6344 _Jv_JNI_SetByteArrayRegion,
6345 _Jv_JNI_SetCharArrayRegion,
6346 _Jv_JNI_SetShortArrayRegion,
6347 _Jv_JNI_SetIntArrayRegion,
6348 _Jv_JNI_SetLongArrayRegion,
6349 _Jv_JNI_SetFloatArrayRegion,
6350 _Jv_JNI_SetDoubleArrayRegion,
6352 _Jv_JNI_RegisterNatives,
6353 _Jv_JNI_UnregisterNatives,
6355 _Jv_JNI_MonitorEnter,
6356 _Jv_JNI_MonitorExit,
6360 /* new JNI 1.2 functions */
6362 _Jv_JNI_GetStringRegion,
6363 _Jv_JNI_GetStringUTFRegion,
6365 _Jv_JNI_GetPrimitiveArrayCritical,
6366 _Jv_JNI_ReleasePrimitiveArrayCritical,
6368 _Jv_JNI_GetStringCritical,
6369 _Jv_JNI_ReleaseStringCritical,
6371 _Jv_JNI_NewWeakGlobalRef,
6372 _Jv_JNI_DeleteWeakGlobalRef,
6374 _Jv_JNI_ExceptionCheck,
6376 /* new JNI 1.4 functions */
6378 _Jv_JNI_NewDirectByteBuffer,
6379 _Jv_JNI_GetDirectBufferAddress,
6380 _Jv_JNI_GetDirectBufferCapacity
6384 /* Invocation API Functions ***************************************************/
6386 /* JNI_GetDefaultJavaVMInitArgs ************************************************
6388 Returns a default configuration for the Java VM.
6390 *******************************************************************************/
6392 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
6394 JavaVMInitArgs *_vm_args;
6396 _vm_args = (JavaVMInitArgs *) vm_args;
6398 /* GNU classpath currently supports JNI 1.2 */
6400 switch (_vm_args->version) {
6401 case JNI_VERSION_1_1:
6402 _vm_args->version = JNI_VERSION_1_1;
6405 case JNI_VERSION_1_2:
6406 case JNI_VERSION_1_4:
6407 _vm_args->ignoreUnrecognized = JNI_FALSE;
6408 _vm_args->options = NULL;
6409 _vm_args->nOptions = 0;
6420 /* JNI_GetCreatedJavaVMs *******************************************************
6422 Returns all Java VMs that have been created. Pointers to VMs are written in
6423 the buffer vmBuf in the order they are created. At most bufLen number of
6424 entries will be written. The total number of created VMs is returned in
6427 *******************************************************************************/
6429 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
6431 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
6437 /* JNI_CreateJavaVM ************************************************************
6439 Loads and initializes a Java VM. The current thread becomes the main thread.
6440 Sets the env argument to the JNI interface pointer of the main thread.
6442 *******************************************************************************/
6444 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
6446 /* actually create the JVM */
6448 if (!vm_createjvm(p_vm, p_env, vm_args))
6456 * These are local overrides for various environment variables in Emacs.
6457 * Please do not remove this and leave it at the end of the file, where
6458 * Emacs will automagically detect them.
6459 * ---------------------------------------------------------------------
6462 * indent-tabs-mode: t
6466 * vim:noexpandtab:sw=4:ts=4: