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 8198 2007-07-12 07:16:24Z 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__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__)
786 java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
787 java_objectarray *params)
791 java_objectheader *ro;
794 java_objectheader *xptr;
797 exceptions_throw_nullpointerexception();
801 argcount = m->parseddesc->paramcount;
802 paramcount = argcount;
804 /* if method is non-static, remove the `this' pointer */
806 if (!(m->flags & ACC_STATIC))
809 /* For instance methods the object has to be an instance of the
810 class the method belongs to. For static methods the obj
811 parameter is ignored. */
813 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
814 exceptions_throw_illegalargumentexception();
818 /* check if we got the right number of arguments */
820 if (((params == NULL) && (paramcount != 0)) ||
821 (params && (params->header.size != paramcount)))
823 exceptions_throw_illegalargumentexception();
827 /* for instance methods we need an object */
829 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
830 /* XXX not sure if that is the correct exception */
831 exceptions_throw_nullpointerexception();
835 /* for static methods, zero object to make subsequent code simpler */
836 if (m->flags & ACC_STATIC)
840 /* for instance methods we must do a vftbl lookup */
841 resm = method_vftbl_lookup(o->vftbl, m);
844 /* for static methods, just for convenience */
848 vmargs = MNEW(vm_arg, argcount);
850 if (!vm_vmargs_from_objectarray(resm, o, vmargs, params)) {
851 MFREE(vmargs, vm_arg, argcount);
855 switch (resm->parseddesc->returntype.decltype) {
857 (void) vm_call_method_vmarg(resm, argcount, vmargs);
862 case PRIMITIVETYPE_BOOLEAN: {
864 java_lang_Boolean *bo;
866 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
868 ro = builtin_new(class_java_lang_Boolean);
870 /* setting the value of the object direct */
872 bo = (java_lang_Boolean *) ro;
877 case PRIMITIVETYPE_BYTE: {
881 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
883 ro = builtin_new(class_java_lang_Byte);
885 /* setting the value of the object direct */
887 bo = (java_lang_Byte *) ro;
892 case PRIMITIVETYPE_CHAR: {
894 java_lang_Character *co;
896 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
898 ro = builtin_new(class_java_lang_Character);
900 /* setting the value of the object direct */
902 co = (java_lang_Character *) ro;
907 case PRIMITIVETYPE_SHORT: {
911 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
913 ro = builtin_new(class_java_lang_Short);
915 /* setting the value of the object direct */
917 so = (java_lang_Short *) ro;
922 case PRIMITIVETYPE_INT: {
924 java_lang_Integer *io;
926 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
928 ro = builtin_new(class_java_lang_Integer);
930 /* setting the value of the object direct */
932 io = (java_lang_Integer *) ro;
937 case PRIMITIVETYPE_LONG: {
941 l = vm_call_method_long_vmarg(resm, argcount, vmargs);
943 ro = builtin_new(class_java_lang_Long);
945 /* setting the value of the object direct */
947 lo = (java_lang_Long *) ro;
952 case PRIMITIVETYPE_FLOAT: {
956 f = vm_call_method_float_vmarg(resm, argcount, vmargs);
958 ro = builtin_new(class_java_lang_Float);
960 /* setting the value of the object direct */
962 fo = (java_lang_Float *) ro;
967 case PRIMITIVETYPE_DOUBLE: {
969 java_lang_Double *_do;
971 d = vm_call_method_double_vmarg(resm, argcount, vmargs);
973 ro = builtin_new(class_java_lang_Double);
975 /* setting the value of the object direct */
977 _do = (java_lang_Double *) ro;
983 ro = vm_call_method_vmarg(resm, argcount, vmargs);
987 /* if this happens the exception has already been set by
988 fill_callblock_from_objectarray */
990 MFREE(vmargs, vm_arg, argcount);
995 MFREE(vmargs, vm_arg, argcount);
997 xptr = exceptions_get_exception();
1000 /* clear exception pointer, we are calling JIT code again */
1002 exceptions_clear_exception();
1004 exceptions_throw_invocationtargetexception(xptr);
1010 java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
1011 java_objectarray *params)
1014 java_objectheader *ro;
1017 java_objectheader *xptr;
1022 exceptions_throw_nullpointerexception();
1026 argcount = m->parseddesc->paramcount;
1027 paramcount = argcount;
1029 /* if method is non-static, remove the `this' pointer */
1031 if (!(m->flags & ACC_STATIC))
1034 /* For instance methods the object has to be an instance of the
1035 class the method belongs to. For static methods the obj
1036 parameter is ignored. */
1038 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
1039 exceptions_throw_illegalargumentexception();
1043 /* check if we got the right number of arguments */
1045 if (((params == NULL) && (paramcount != 0)) ||
1046 (params && (params->header.size != paramcount)))
1048 exceptions_throw_illegalargumentexception();
1052 /* for instance methods we need an object */
1054 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
1055 /* XXX not sure if that is the correct exception */
1056 exceptions_throw_nullpointerexception();
1060 /* for static methods, zero object to make subsequent code simpler */
1061 if (m->flags & ACC_STATIC)
1065 /* for instance methods we must do a vftbl lookup */
1066 resm = method_vftbl_lookup(o->vftbl, m);
1069 /* for static methods, just for convenience */
1073 /* mark start of dump memory area */
1075 dumpsize = dump_size();
1077 /* fill the argument array from a object-array */
1079 array = vm_array_from_objectarray(resm, o, params);
1081 if (array == NULL) {
1082 /* release dump area */
1084 dump_release(dumpsize);
1089 switch (resm->parseddesc->returntype.decltype) {
1091 (void) vm_call_array(resm, array);
1096 case PRIMITIVETYPE_BOOLEAN: {
1098 java_lang_Boolean *bo;
1100 i = vm_call_int_array(resm, array);
1102 ro = builtin_new(class_java_lang_Boolean);
1104 /* setting the value of the object direct */
1106 bo = (java_lang_Boolean *) ro;
1111 case PRIMITIVETYPE_BYTE: {
1115 i = vm_call_int_array(resm, array);
1117 ro = builtin_new(class_java_lang_Byte);
1119 /* setting the value of the object direct */
1121 bo = (java_lang_Byte *) ro;
1126 case PRIMITIVETYPE_CHAR: {
1128 java_lang_Character *co;
1130 i = vm_call_int_array(resm, array);
1132 ro = builtin_new(class_java_lang_Character);
1134 /* setting the value of the object direct */
1136 co = (java_lang_Character *) ro;
1141 case PRIMITIVETYPE_SHORT: {
1143 java_lang_Short *so;
1145 i = vm_call_int_array(resm, array);
1147 ro = builtin_new(class_java_lang_Short);
1149 /* setting the value of the object direct */
1151 so = (java_lang_Short *) ro;
1156 case PRIMITIVETYPE_INT: {
1158 java_lang_Integer *io;
1160 i = vm_call_int_array(resm, array);
1162 ro = builtin_new(class_java_lang_Integer);
1164 /* setting the value of the object direct */
1166 io = (java_lang_Integer *) ro;
1171 case PRIMITIVETYPE_LONG: {
1175 l = vm_call_long_array(resm, array);
1177 ro = builtin_new(class_java_lang_Long);
1179 /* setting the value of the object direct */
1181 lo = (java_lang_Long *) ro;
1186 case PRIMITIVETYPE_FLOAT: {
1188 java_lang_Float *fo;
1190 f = vm_call_float_array(resm, array);
1192 ro = builtin_new(class_java_lang_Float);
1194 /* setting the value of the object direct */
1196 fo = (java_lang_Float *) ro;
1201 case PRIMITIVETYPE_DOUBLE: {
1203 java_lang_Double *_do;
1205 d = vm_call_double_array(resm, array);
1207 ro = builtin_new(class_java_lang_Double);
1209 /* setting the value of the object direct */
1211 _do = (java_lang_Double *) ro;
1217 ro = vm_call_array(resm, array);
1221 /* if this happens the exception has already been set by
1222 fill_callblock_from_objectarray */
1224 /* release dump area */
1226 dump_release(dumpsize);
1231 xptr = exceptions_get_exception();
1234 /* clear exception pointer, we are calling JIT code again */
1236 exceptions_clear_exception();
1238 exceptions_throw_invocationtargetexception(xptr);
1241 /* release dump area */
1243 dump_release(dumpsize);
1250 /* GetVersion ******************************************************************
1252 Returns the major version number in the higher 16 bits and the
1253 minor version number in the lower 16 bits.
1255 *******************************************************************************/
1257 jint _Jv_JNI_GetVersion(JNIEnv *env)
1259 STATISTICS(jniinvokation());
1261 /* we support JNI 1.4 */
1263 return JNI_VERSION_1_4;
1267 /* Class Operations ***********************************************************/
1269 /* DefineClass *****************************************************************
1271 Loads a class from a buffer of raw class data. The buffer
1272 containing the raw class data is not referenced by the VM after the
1273 DefineClass call returns, and it may be discarded if desired.
1275 *******************************************************************************/
1277 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
1278 const jbyte *buf, jsize bufLen)
1280 #if defined(ENABLE_JAVASE)
1281 java_lang_ClassLoader *cl;
1282 java_lang_String *s;
1286 STATISTICS(jniinvokation());
1288 cl = (java_lang_ClassLoader *) loader;
1289 s = (java_lang_String *) javastring_new_from_utf_string(name);
1290 ba = (java_bytearray *) buf;
1292 c = (jclass) _Jv_java_lang_ClassLoader_defineClass(cl, s, ba, 0, bufLen,
1295 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1297 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
1299 /* keep compiler happy */
1306 /* FindClass *******************************************************************
1308 This function loads a locally-defined class. It searches the
1309 directories and zip files specified by the CLASSPATH environment
1310 variable for the class with the specified name.
1312 *******************************************************************************/
1314 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
1316 #if defined(ENABLE_JAVASE)
1321 STATISTICS(jniinvokation());
1323 u = utf_new_char_classname((char *) name);
1325 /* Check stacktrace for classloader, if one found use it,
1326 otherwise use the system classloader. */
1328 /* Quote from the JNI documentation:
1330 In the Java 2 Platform, FindClass locates the class loader
1331 associated with the current native method. If the native code
1332 belongs to a system class, no class loader will be
1333 involved. Otherwise, the proper class loader will be invoked to
1334 load and link the named class. When FindClass is called through
1335 the Invocation Interface, there is no current native method or
1336 its associated class loader. In that case, the result of
1337 ClassLoader.getBaseClassLoader is used." */
1339 cc = stacktrace_getCurrentClass();
1342 c = load_class_from_sysloader(u);
1344 c = load_class_from_classloader(u, cc->classloader);
1352 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1354 vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1356 /* keep compiler happy */
1363 /* GetSuperclass ***************************************************************
1365 If clazz represents any class other than the class Object, then
1366 this function returns the object that represents the superclass of
1367 the class specified by clazz.
1369 *******************************************************************************/
1371 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1375 STATISTICS(jniinvokation());
1377 c = ((classinfo *) sub)->super.cls;
1382 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1386 /* IsAssignableFrom ************************************************************
1388 Determines whether an object of sub can be safely cast to sup.
1390 *******************************************************************************/
1392 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1394 java_lang_Class *csup;
1395 java_lang_Class *csub;
1397 csup = (java_lang_Class *) sup;
1398 csub = (java_lang_Class *) sub;
1400 STATISTICS(jniinvokation());
1402 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1406 /* Throw ***********************************************************************
1408 Causes a java.lang.Throwable object to be thrown.
1410 *******************************************************************************/
1412 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1414 java_objectheader *o;
1416 STATISTICS(jniinvokation());
1418 o = (java_objectheader *) obj;
1420 exceptions_set_exception(o);
1426 /* ThrowNew ********************************************************************
1428 Constructs an exception object from the specified class with the
1429 message specified by message and causes that exception to be
1432 *******************************************************************************/
1434 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1437 java_objectheader *o;
1438 java_objectheader *s;
1440 STATISTICS(jniinvokation());
1442 c = (classinfo *) clazz;
1445 s = javastring_new_from_utf_string(msg);
1447 /* instantiate exception object */
1449 o = native_new_and_init_string(c, s);
1454 exceptions_set_exception(o);
1460 /* ExceptionOccurred ***********************************************************
1462 Determines if an exception is being thrown. The exception stays
1463 being thrown until either the native code calls ExceptionClear(),
1464 or the Java code handles the exception.
1466 *******************************************************************************/
1468 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1470 java_objectheader *o;
1472 STATISTICS(jniinvokation());
1474 o = exceptions_get_exception();
1476 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1480 /* ExceptionDescribe ***********************************************************
1482 Prints an exception and a backtrace of the stack to a system
1483 error-reporting channel, such as stderr. This is a convenience
1484 routine provided for debugging.
1486 *******************************************************************************/
1488 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1490 java_objectheader *o;
1493 STATISTICS(jniinvokation());
1495 o = exceptions_get_exception();
1498 /* clear exception, because we are calling jit code again */
1500 exceptions_clear_exception();
1502 /* get printStackTrace method from exception class */
1504 m = class_resolveclassmethod(o->vftbl->class,
1505 utf_printStackTrace,
1511 /* XXX what should we do? */
1514 /* print the stacktrace */
1516 (void) vm_call_method(m, o);
1521 /* ExceptionClear **************************************************************
1523 Clears any exception that is currently being thrown. If no
1524 exception is currently being thrown, this routine has no effect.
1526 *******************************************************************************/
1528 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1530 STATISTICS(jniinvokation());
1532 exceptions_clear_exception();
1536 /* FatalError ******************************************************************
1538 Raises a fatal error and does not expect the VM to recover. This
1539 function does not return.
1541 *******************************************************************************/
1543 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1545 STATISTICS(jniinvokation());
1547 /* this seems to be the best way */
1549 vm_abort("JNI Fatal error: %s", msg);
1553 /* PushLocalFrame **************************************************************
1555 Creates a new local reference frame, in which at least a given
1556 number of local references can be created.
1558 *******************************************************************************/
1560 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1563 localref_table *lrt;
1564 localref_table *nlrt;
1566 STATISTICS(jniinvokation());
1571 /* Allocate new local reference table on Java heap. Calculate the
1572 additional memory we have to allocate. */
1574 if (capacity > LOCALREFTABLE_CAPACITY)
1575 additionalrefs = capacity - LOCALREFTABLE_CAPACITY;
1579 nlrt = GCMNEW(u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
1584 /* get current local reference table from thread */
1586 lrt = LOCALREFTABLE;
1588 /* Set up the new local reference table and add it to the local
1591 nlrt->capacity = capacity;
1593 nlrt->localframes = lrt->localframes + 1;
1596 /* store new local reference table in thread */
1598 LOCALREFTABLE = nlrt;
1604 /* PopLocalFrame ***************************************************************
1606 Pops off the current local reference frame, frees all the local
1607 references, and returns a local reference in the previous local
1608 reference frame for the given result object.
1610 *******************************************************************************/
1612 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1614 localref_table *lrt;
1615 localref_table *plrt;
1618 STATISTICS(jniinvokation());
1620 /* get current local reference table from thread */
1622 lrt = LOCALREFTABLE;
1624 localframes = lrt->localframes;
1626 /* Don't delete the top local frame, as this one is allocated in
1627 the native stub on the stack and is freed automagically on
1630 if (localframes == 1)
1631 return _Jv_JNI_NewLocalRef(env, result);
1633 /* release all current local frames */
1635 for (; localframes >= 1; localframes--) {
1636 /* get previous frame */
1640 /* clear all reference entries */
1642 MSET(&lrt->refs[0], 0, java_objectheader*, lrt->capacity);
1646 /* set new local references table */
1651 /* store new local reference table in thread */
1653 LOCALREFTABLE = lrt;
1655 /* add local reference and return the value */
1657 return _Jv_JNI_NewLocalRef(env, result);
1661 /* DeleteLocalRef **************************************************************
1663 Deletes the local reference pointed to by localRef.
1665 *******************************************************************************/
1667 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1669 java_objectheader *o;
1670 localref_table *lrt;
1673 STATISTICS(jniinvokation());
1675 o = (java_objectheader *) localRef;
1677 /* get local reference table (thread specific) */
1679 lrt = LOCALREFTABLE;
1681 /* go through all local frames */
1683 for (; lrt != NULL; lrt = lrt->prev) {
1685 /* and try to remove the reference */
1687 for (i = 0; i < lrt->capacity; i++) {
1688 if (lrt->refs[i] == o) {
1689 lrt->refs[i] = NULL;
1697 /* this should not happen */
1699 /* if (opt_checkjni) */
1700 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1701 log_text("JNI-DeleteLocalRef: Local ref passed to JNI not found");
1705 /* IsSameObject ****************************************************************
1707 Tests whether two references refer to the same Java object.
1709 *******************************************************************************/
1711 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1713 STATISTICS(jniinvokation());
1722 /* NewLocalRef *****************************************************************
1724 Creates a new local reference that refers to the same object as ref.
1726 *******************************************************************************/
1728 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1730 localref_table *lrt;
1733 STATISTICS(jniinvokation());
1738 /* get local reference table (thread specific) */
1740 lrt = LOCALREFTABLE;
1742 /* Check if we have space for the requested reference? No,
1743 allocate a new frame. This is actually not what the spec says,
1744 but for compatibility reasons... */
1746 if (lrt->used == lrt->capacity) {
1747 if (_Jv_JNI_EnsureLocalCapacity(env, 16) != 0)
1750 /* get the new local reference table */
1752 lrt = LOCALREFTABLE;
1755 /* insert the reference */
1757 for (i = 0; i < lrt->capacity; i++) {
1758 if (lrt->refs[i] == NULL) {
1759 lrt->refs[i] = (java_objectheader *) ref;
1766 /* should not happen, just to be sure */
1770 /* keep compiler happy */
1776 /* EnsureLocalCapacity *********************************************************
1778 Ensures that at least a given number of local references can be
1779 created in the current thread
1781 *******************************************************************************/
1783 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1785 localref_table *lrt;
1787 STATISTICS(jniinvokation());
1789 /* get local reference table (thread specific) */
1791 lrt = LOCALREFTABLE;
1793 /* check if capacity elements are available in the local references table */
1795 if ((lrt->used + capacity) > lrt->capacity)
1796 return _Jv_JNI_PushLocalFrame(env, capacity);
1802 /* AllocObject *****************************************************************
1804 Allocates a new Java object without invoking any of the
1805 constructors for the object. Returns a reference to the object.
1807 *******************************************************************************/
1809 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1812 java_objectheader *o;
1814 STATISTICS(jniinvokation());
1816 c = (classinfo *) clazz;
1818 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1819 exceptions_throw_instantiationexception(c);
1825 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1829 /* NewObject *******************************************************************
1831 Programmers place all arguments that are to be passed to the
1832 constructor immediately following the methodID
1833 argument. NewObject() accepts these arguments and passes them to
1834 the Java method that the programmer wishes to invoke.
1836 *******************************************************************************/
1838 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1840 java_objectheader *o;
1845 STATISTICS(jniinvokation());
1847 c = (classinfo *) clazz;
1848 m = (methodinfo *) methodID;
1857 /* call constructor */
1859 va_start(ap, methodID);
1860 _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
1863 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1867 /* NewObjectV ******************************************************************
1869 Programmers place all arguments that are to be passed to the
1870 constructor in an args argument of type va_list that immediately
1871 follows the methodID argument. NewObjectV() accepts these
1872 arguments, and, in turn, passes them to the Java method that the
1873 programmer wishes to invoke.
1875 *******************************************************************************/
1877 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1880 java_objectheader *o;
1884 STATISTICS(jniinvokation());
1886 c = (classinfo *) clazz;
1887 m = (methodinfo *) methodID;
1896 /* call constructor */
1898 _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
1900 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1904 /* NewObjectA *****************************************************************
1906 Programmers place all arguments that are to be passed to the
1907 constructor in an args array of jvalues that immediately follows
1908 the methodID argument. NewObjectA() accepts the arguments in this
1909 array, and, in turn, passes them to the Java method that the
1910 programmer wishes to invoke.
1912 *******************************************************************************/
1914 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1917 java_objectheader *o;
1921 STATISTICS(jniinvokation());
1923 c = (classinfo *) clazz;
1924 m = (methodinfo *) methodID;
1933 /* call constructor */
1935 _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
1937 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1941 /* GetObjectClass **************************************************************
1943 Returns the class of an object.
1945 *******************************************************************************/
1947 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1949 java_objectheader *o;
1952 STATISTICS(jniinvokation());
1954 o = (java_objectheader *) obj;
1956 if ((o == NULL) || (o->vftbl == NULL))
1959 c = o->vftbl->class;
1961 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1965 /* IsInstanceOf ****************************************************************
1967 Tests whether an object is an instance of a class.
1969 *******************************************************************************/
1971 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1974 java_lang_Object *o;
1976 STATISTICS(jniinvokation());
1978 c = (java_lang_Class *) clazz;
1979 o = (java_lang_Object *) obj;
1981 return _Jv_java_lang_Class_isInstance(c, o);
1985 /* Reflection Support *********************************************************/
1987 /* FromReflectedMethod *********************************************************
1989 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1990 object to a method ID.
1992 *******************************************************************************/
1994 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1996 #if defined(ENABLE_JAVASE)
1997 java_objectheader *o;
2002 STATISTICS(jniinvokation());
2004 o = (java_objectheader *) method;
2009 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
2010 java_lang_reflect_Method *rm;
2012 rm = (java_lang_reflect_Method *) method;
2013 c = (classinfo *) (rm->clazz);
2016 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
2017 java_lang_reflect_Constructor *rc;
2019 rc = (java_lang_reflect_Constructor *) method;
2020 c = (classinfo *) (rc->clazz);
2026 m = &(c->methods[slot]);
2028 return (jmethodID) m;
2030 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
2032 /* keep compiler happy */
2039 /* FromReflectedField **********************************************************
2041 Converts a java.lang.reflect.Field to a field ID.
2043 *******************************************************************************/
2045 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
2047 #if defined(ENABLE_JAVASE)
2048 java_lang_reflect_Field *rf;
2052 STATISTICS(jniinvokation());
2054 rf = (java_lang_reflect_Field *) field;
2059 c = (classinfo *) rf->clazz;
2060 f = &(c->fields[rf->slot]);
2062 return (jfieldID) f;
2064 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
2066 /* keep compiler happy */
2073 /* ToReflectedMethod ***********************************************************
2075 Converts a method ID derived from cls to an instance of the
2076 java.lang.reflect.Method class or to an instance of the
2077 java.lang.reflect.Constructor class.
2079 *******************************************************************************/
2081 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
2084 #if defined(ENABLE_JAVASE)
2086 java_lang_reflect_Constructor *rc;
2087 java_lang_reflect_Method *rm;
2089 STATISTICS(jniinvokation());
2091 m = (methodinfo *) methodID;
2093 /* HotSpot does the same assert. */
2095 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
2097 if (m->name == utf_init) {
2098 rc = reflect_constructor_new(m);
2100 return (jobject) rc;
2103 rm = reflect_method_new(m);
2105 return (jobject) rm;
2108 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
2110 /* keep compiler happy */
2117 /* ToReflectedField ************************************************************
2119 Converts a field ID derived from cls to an instance of the
2120 java.lang.reflect.Field class.
2122 *******************************************************************************/
2124 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
2127 STATISTICS(jniinvokation());
2129 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
2135 /* Calling Instance Methods ***************************************************/
2137 /* GetMethodID *****************************************************************
2139 Returns the method ID for an instance (nonstatic) method of a class
2140 or interface. The method may be defined in one of the clazz's
2141 superclasses and inherited by clazz. The method is determined by
2142 its name and signature.
2144 GetMethodID() causes an uninitialized class to be initialized.
2146 *******************************************************************************/
2148 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
2156 STATISTICS(jniinvokation());
2158 c = (classinfo *) clazz;
2163 if (!(c->state & CLASS_INITIALIZED))
2164 if (!initialize_class(c))
2167 /* try to get the method of the class or one of it's superclasses */
2169 uname = utf_new_char((char *) name);
2170 udesc = utf_new_char((char *) sig);
2172 m = class_resolvemethod(c, uname, udesc);
2174 if ((m == NULL) || (m->flags & ACC_STATIC)) {
2175 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2180 return (jmethodID) m;
2184 /* JNI-functions for calling instance methods *********************************/
2186 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
2189 java_objectheader *o;
2191 java_objectheader *ret;
2194 o = (java_objectheader *) obj;
2195 m = (methodinfo *) methodID;
2197 va_start(ap, methodID);
2198 ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, ap);
2201 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
2205 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2208 java_objectheader *o;
2210 java_objectheader *ret;
2212 o = (java_objectheader *) obj;
2213 m = (methodinfo *) methodID;
2215 ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, args);
2217 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
2221 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2224 java_objectheader *o;
2226 java_objectheader *ret;
2228 o = (java_objectheader *) obj;
2229 m = (methodinfo *) methodID;
2231 ret = _Jv_jni_CallObjectMethodA(o, o->vftbl, m, args);
2233 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
2237 jboolean _Jv_JNI_CallBooleanMethod(JNIEnv *env, jobject obj, jmethodID methodID,
2240 java_objectheader *o;
2245 o = (java_objectheader *) obj;
2246 m = (methodinfo *) methodID;
2248 va_start(ap, methodID);
2249 b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2256 jboolean _Jv_JNI_CallBooleanMethodV(JNIEnv *env, jobject obj,
2257 jmethodID methodID, va_list args)
2259 java_objectheader *o;
2263 o = (java_objectheader *) obj;
2264 m = (methodinfo *) methodID;
2266 b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2272 jboolean _Jv_JNI_CallBooleanMethodA(JNIEnv *env, jobject obj,
2273 jmethodID methodID, const jvalue *args)
2275 java_objectheader *o;
2279 o = (java_objectheader *) obj;
2280 m = (methodinfo *) methodID;
2282 b = _Jv_jni_CallIntMethodA(o, o->vftbl, m, args);
2288 jbyte _Jv_JNI_CallByteMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2290 java_objectheader *o;
2295 o = (java_objectheader *) obj;
2296 m = (methodinfo *) methodID;
2298 va_start(ap, methodID);
2299 b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2307 jbyte _Jv_JNI_CallByteMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2310 java_objectheader *o;
2314 o = (java_objectheader *) obj;
2315 m = (methodinfo *) methodID;
2317 b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2323 jbyte _Jv_JNI_CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2326 log_text("JNI-Call: CallByteMethodA: IMPLEMENT ME!");
2332 jchar _Jv_JNI_CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2334 java_objectheader *o;
2339 o = (java_objectheader *) obj;
2340 m = (methodinfo *) methodID;
2342 va_start(ap, methodID);
2343 c = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2350 jchar _Jv_JNI_CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2353 java_objectheader *o;
2357 o = (java_objectheader *) obj;
2358 m = (methodinfo *) methodID;
2360 c = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2366 jchar _Jv_JNI_CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2369 log_text("JNI-Call: CallCharMethodA: IMPLEMENT ME!");
2375 jshort _Jv_JNI_CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID,
2378 java_objectheader *o;
2383 o = (java_objectheader *) obj;
2384 m = (methodinfo *) methodID;
2386 va_start(ap, methodID);
2387 s = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2394 jshort _Jv_JNI_CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2397 java_objectheader *o;
2401 o = (java_objectheader *) obj;
2402 m = (methodinfo *) methodID;
2404 s = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2410 jshort _Jv_JNI_CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2413 log_text("JNI-Call: CallShortMethodA: IMPLEMENT ME!");
2420 jint _Jv_JNI_CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2422 java_objectheader *o;
2427 o = (java_objectheader *) obj;
2428 m = (methodinfo *) methodID;
2430 va_start(ap, methodID);
2431 i = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2438 jint _Jv_JNI_CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2441 java_objectheader *o;
2445 o = (java_objectheader *) obj;
2446 m = (methodinfo *) methodID;
2448 i = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2454 jint _Jv_JNI_CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2457 log_text("JNI-Call: CallIntMethodA: IMPLEMENT ME!");
2464 jlong _Jv_JNI_CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2466 java_objectheader *o;
2471 o = (java_objectheader *) obj;
2472 m = (methodinfo *) methodID;
2474 va_start(ap, methodID);
2475 l = _Jv_jni_CallLongMethod(o, o->vftbl, m, ap);
2482 jlong _Jv_JNI_CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2485 java_objectheader *o;
2489 o = (java_objectheader *) obj;
2490 m = (methodinfo *) methodID;
2492 l = _Jv_jni_CallLongMethod(o, o->vftbl, m, args);
2498 jlong _Jv_JNI_CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2501 log_text("JNI-Call: CallLongMethodA: IMPLEMENT ME!");
2508 jfloat _Jv_JNI_CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID,
2511 java_objectheader *o;
2516 o = (java_objectheader *) obj;
2517 m = (methodinfo *) methodID;
2519 va_start(ap, methodID);
2520 f = _Jv_jni_CallFloatMethod(o, o->vftbl, m, ap);
2527 jfloat _Jv_JNI_CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2530 java_objectheader *o;
2534 o = (java_objectheader *) obj;
2535 m = (methodinfo *) methodID;
2537 f = _Jv_jni_CallFloatMethod(o, o->vftbl, m, args);
2543 jfloat _Jv_JNI_CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2546 log_text("JNI-Call: CallFloatMethodA: IMPLEMENT ME!");
2553 jdouble _Jv_JNI_CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID,
2556 java_objectheader *o;
2561 o = (java_objectheader *) obj;
2562 m = (methodinfo *) methodID;
2564 va_start(ap, methodID);
2565 d = _Jv_jni_CallDoubleMethod(o, o->vftbl, m, ap);
2572 jdouble _Jv_JNI_CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2575 java_objectheader *o;
2579 o = (java_objectheader *) obj;
2580 m = (methodinfo *) methodID;
2582 d = _Jv_jni_CallDoubleMethod(o, o->vftbl, m, args);
2588 jdouble _Jv_JNI_CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2591 log_text("JNI-Call: CallDoubleMethodA: IMPLEMENT ME!");
2598 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2600 java_objectheader *o;
2604 o = (java_objectheader *) obj;
2605 m = (methodinfo *) methodID;
2607 va_start(ap, methodID);
2608 _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
2613 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2616 java_objectheader *o;
2619 o = (java_objectheader *) obj;
2620 m = (methodinfo *) methodID;
2622 _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
2626 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2629 java_objectheader *o;
2632 o = (java_objectheader *) obj;
2633 m = (methodinfo *) methodID;
2635 _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
2640 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2641 jclass clazz, jmethodID methodID,
2644 java_objectheader *o;
2647 java_objectheader *r;
2650 o = (java_objectheader *) obj;
2651 c = (classinfo *) clazz;
2652 m = (methodinfo *) methodID;
2654 va_start(ap, methodID);
2655 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2658 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2662 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2663 jclass clazz, jmethodID methodID,
2666 java_objectheader *o;
2669 java_objectheader *r;
2671 o = (java_objectheader *) obj;
2672 c = (classinfo *) clazz;
2673 m = (methodinfo *) methodID;
2675 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2677 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2681 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2682 jclass clazz, jmethodID methodID,
2685 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2687 return _Jv_JNI_NewLocalRef(env, NULL);
2692 jboolean _Jv_JNI_CallNonvirtualBooleanMethod(JNIEnv *env, jobject obj,
2693 jclass clazz, jmethodID methodID,
2696 java_objectheader *o;
2702 o = (java_objectheader *) obj;
2703 c = (classinfo *) clazz;
2704 m = (methodinfo *) methodID;
2706 va_start(ap, methodID);
2707 b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2714 jboolean _Jv_JNI_CallNonvirtualBooleanMethodV(JNIEnv *env, jobject obj,
2715 jclass clazz, jmethodID methodID,
2718 java_objectheader *o;
2723 o = (java_objectheader *) obj;
2724 c = (classinfo *) clazz;
2725 m = (methodinfo *) methodID;
2727 b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2733 jboolean _Jv_JNI_CallNonvirtualBooleanMethodA(JNIEnv *env, jobject obj,
2734 jclass clazz, jmethodID methodID,
2737 log_text("JNI-Call: CallNonvirtualBooleanMethodA: IMPLEMENT ME!");
2743 jbyte _Jv_JNI_CallNonvirtualByteMethod(JNIEnv *env, jobject obj, jclass clazz,
2744 jmethodID methodID, ...)
2746 java_objectheader *o;
2752 o = (java_objectheader *) obj;
2753 c = (classinfo *) clazz;
2754 m = (methodinfo *) methodID;
2756 va_start(ap, methodID);
2757 b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2764 jbyte _Jv_JNI_CallNonvirtualByteMethodV(JNIEnv *env, jobject obj, jclass clazz,
2765 jmethodID methodID, va_list args)
2767 java_objectheader *o;
2772 o = (java_objectheader *) obj;
2773 c = (classinfo *) clazz;
2774 m = (methodinfo *) methodID;
2776 b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2782 jbyte _Jv_JNI_CallNonvirtualByteMethodA(JNIEnv *env, jobject obj, jclass clazz,
2783 jmethodID methodID, const jvalue *args)
2785 log_text("JNI-Call: CallNonvirtualByteMethodA: IMPLEMENT ME!");
2792 jchar _Jv_JNI_CallNonvirtualCharMethod(JNIEnv *env, jobject obj, jclass clazz,
2793 jmethodID methodID, ...)
2795 java_objectheader *o;
2801 o = (java_objectheader *) obj;
2802 c = (classinfo *) clazz;
2803 m = (methodinfo *) methodID;
2805 va_start(ap, methodID);
2806 ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2813 jchar _Jv_JNI_CallNonvirtualCharMethodV(JNIEnv *env, jobject obj, jclass clazz,
2814 jmethodID methodID, va_list args)
2816 java_objectheader *o;
2821 o = (java_objectheader *) obj;
2822 c = (classinfo *) clazz;
2823 m = (methodinfo *) methodID;
2825 ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2831 jchar _Jv_JNI_CallNonvirtualCharMethodA(JNIEnv *env, jobject obj, jclass clazz,
2832 jmethodID methodID, const jvalue *args)
2834 log_text("JNI-Call: CallNonvirtualCharMethodA: IMPLEMENT ME!");
2841 jshort _Jv_JNI_CallNonvirtualShortMethod(JNIEnv *env, jobject obj,
2842 jclass clazz, jmethodID methodID, ...)
2844 java_objectheader *o;
2850 o = (java_objectheader *) obj;
2851 c = (classinfo *) clazz;
2852 m = (methodinfo *) methodID;
2854 va_start(ap, methodID);
2855 s = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2862 jshort _Jv_JNI_CallNonvirtualShortMethodV(JNIEnv *env, jobject obj,
2863 jclass clazz, jmethodID methodID,
2866 java_objectheader *o;
2871 o = (java_objectheader *) obj;
2872 c = (classinfo *) clazz;
2873 m = (methodinfo *) methodID;
2875 s = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2881 jshort _Jv_JNI_CallNonvirtualShortMethodA(JNIEnv *env, jobject obj,
2882 jclass clazz, jmethodID methodID,
2885 log_text("JNI-Call: CallNonvirtualShortMethodA: IMPLEMENT ME!");
2892 jint _Jv_JNI_CallNonvirtualIntMethod(JNIEnv *env, jobject obj, jclass clazz,
2893 jmethodID methodID, ...)
2895 java_objectheader *o;
2901 o = (java_objectheader *) obj;
2902 c = (classinfo *) clazz;
2903 m = (methodinfo *) methodID;
2905 va_start(ap, methodID);
2906 i = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2913 jint _Jv_JNI_CallNonvirtualIntMethodV(JNIEnv *env, jobject obj, jclass clazz,
2914 jmethodID methodID, va_list args)
2916 java_objectheader *o;
2921 o = (java_objectheader *) obj;
2922 c = (classinfo *) clazz;
2923 m = (methodinfo *) methodID;
2925 i = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2931 jint _Jv_JNI_CallNonvirtualIntMethodA(JNIEnv *env, jobject obj, jclass clazz,
2932 jmethodID methodID, const jvalue *args)
2934 log_text("JNI-Call: CallNonvirtualIntMethodA: IMPLEMENT ME!");
2941 jlong _Jv_JNI_CallNonvirtualLongMethod(JNIEnv *env, jobject obj, jclass clazz,
2942 jmethodID methodID, ...)
2944 java_objectheader *o;
2950 o = (java_objectheader *) obj;
2951 c = (classinfo *) clazz;
2952 m = (methodinfo *) methodID;
2954 va_start(ap, methodID);
2955 l = _Jv_jni_CallLongMethod(o, c->vftbl, m, ap);
2962 jlong _Jv_JNI_CallNonvirtualLongMethodV(JNIEnv *env, jobject obj, jclass clazz,
2963 jmethodID methodID, va_list args)
2965 java_objectheader *o;
2970 o = (java_objectheader *) obj;
2971 c = (classinfo *) clazz;
2972 m = (methodinfo *) methodID;
2974 l = _Jv_jni_CallLongMethod(o, c->vftbl, m, args);
2980 jlong _Jv_JNI_CallNonvirtualLongMethodA(JNIEnv *env, jobject obj, jclass clazz,
2981 jmethodID methodID, const jvalue *args)
2983 log_text("JNI-Call: CallNonvirtualLongMethodA: IMPLEMENT ME!");
2990 jfloat _Jv_JNI_CallNonvirtualFloatMethod(JNIEnv *env, jobject obj,
2991 jclass clazz, jmethodID methodID, ...)
2993 java_objectheader *o;
2999 o = (java_objectheader *) obj;
3000 c = (classinfo *) clazz;
3001 m = (methodinfo *) methodID;
3003 va_start(ap, methodID);
3004 f = _Jv_jni_CallFloatMethod(o, c->vftbl, m, ap);
3011 jfloat _Jv_JNI_CallNonvirtualFloatMethodV(JNIEnv *env, jobject obj,
3012 jclass clazz, jmethodID methodID,
3015 java_objectheader *o;
3020 o = (java_objectheader *) obj;
3021 c = (classinfo *) clazz;
3022 m = (methodinfo *) methodID;
3024 f = _Jv_jni_CallFloatMethod(o, c->vftbl, m, args);
3030 jfloat _Jv_JNI_CallNonvirtualFloatMethodA(JNIEnv *env, jobject obj,
3031 jclass clazz, jmethodID methodID,
3034 log_text("JNI-Call: CallNonvirtualFloatMethodA: IMPLEMENT ME!");
3041 jdouble _Jv_JNI_CallNonvirtualDoubleMethod(JNIEnv *env, jobject obj,
3042 jclass clazz, jmethodID methodID,
3045 java_objectheader *o;
3051 o = (java_objectheader *) obj;
3052 c = (classinfo *) clazz;
3053 m = (methodinfo *) methodID;
3055 va_start(ap, methodID);
3056 d = _Jv_jni_CallDoubleMethod(o, c->vftbl, m, ap);
3063 jdouble _Jv_JNI_CallNonvirtualDoubleMethodV(JNIEnv *env, jobject obj,
3064 jclass clazz, jmethodID methodID,
3067 java_objectheader *o;
3072 o = (java_objectheader *) obj;
3073 c = (classinfo *) clazz;
3074 m = (methodinfo *) methodID;
3076 d = _Jv_jni_CallDoubleMethod(o, c->vftbl, m, args);
3082 jdouble _Jv_JNI_CallNonvirtualDoubleMethodA(JNIEnv *env, jobject obj,
3083 jclass clazz, jmethodID methodID,
3086 log_text("JNI-Call: CallNonvirtualDoubleMethodA: IMPLEMENT ME!");
3093 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
3094 jmethodID methodID, ...)
3096 java_objectheader *o;
3101 o = (java_objectheader *) obj;
3102 c = (classinfo *) clazz;
3103 m = (methodinfo *) methodID;
3105 va_start(ap, methodID);
3106 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
3111 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
3112 jmethodID methodID, va_list args)
3114 java_objectheader *o;
3118 o = (java_objectheader *) obj;
3119 c = (classinfo *) clazz;
3120 m = (methodinfo *) methodID;
3122 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
3126 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
3127 jmethodID methodID, const jvalue * args)
3129 java_objectheader *o;
3133 o = (java_objectheader *) obj;
3134 c = (classinfo *) clazz;
3135 m = (methodinfo *) methodID;
3137 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
3141 /* Accessing Fields of Objects ************************************************/
3143 /* GetFieldID ******************************************************************
3145 Returns the field ID for an instance (nonstatic) field of a
3146 class. The field is specified by its name and signature. The
3147 Get<type>Field and Set<type>Field families of accessor functions
3148 use field IDs to retrieve object fields.
3150 *******************************************************************************/
3152 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
3160 STATISTICS(jniinvokation());
3162 c = (classinfo *) clazz;
3164 /* XXX NPE check? */
3166 uname = utf_new_char((char *) name);
3167 udesc = utf_new_char((char *) sig);
3169 f = class_findfield(c, uname, udesc);
3172 exceptions_throw_nosuchfielderror(c, uname);
3174 return (jfieldID) f;
3178 /* Get<type>Field Routines *****************************************************
3180 This family of accessor routines returns the value of an instance
3181 (nonstatic) field of an object. The field to access is specified by
3182 a field ID obtained by calling GetFieldID().
3184 *******************************************************************************/
3186 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
3188 java_objectheader *o;
3190 STATISTICS(jniinvokation());
3192 o = GET_FIELD(obj, java_objectheader*, fieldID);
3194 return _Jv_JNI_NewLocalRef(env, (jobject) o);
3198 jboolean _Jv_JNI_GetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID)
3202 STATISTICS(jniinvokation());
3204 i = GET_FIELD(obj, s4, fieldID);
3206 return (jboolean) i;
3210 jbyte _Jv_JNI_GetByteField(JNIEnv *env, jobject obj, jfieldID fieldID)
3214 STATISTICS(jniinvokation());
3216 i = GET_FIELD(obj, s4, fieldID);
3222 jchar _Jv_JNI_GetCharField(JNIEnv *env, jobject obj, jfieldID fieldID)
3226 STATISTICS(jniinvokation());
3228 i = GET_FIELD(obj, s4, fieldID);
3234 jshort _Jv_JNI_GetShortField(JNIEnv *env, jobject obj, jfieldID fieldID)
3238 STATISTICS(jniinvokation());
3240 i = GET_FIELD(obj, s4, fieldID);
3246 jint _Jv_JNI_GetIntField(JNIEnv *env, jobject obj, jfieldID fieldID)
3248 java_objectheader *o;
3252 STATISTICS(jniinvokation());
3254 o = (java_objectheader *) obj;
3255 f = (fieldinfo *) fieldID;
3257 i = GET_FIELD(o, s4, f);
3263 jlong _Jv_JNI_GetLongField(JNIEnv *env, jobject obj, jfieldID fieldID)
3267 STATISTICS(jniinvokation());
3269 l = GET_FIELD(obj, s8, fieldID);
3275 jfloat _Jv_JNI_GetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID)
3279 STATISTICS(jniinvokation());
3281 f = GET_FIELD(obj, float, fieldID);
3287 jdouble _Jv_JNI_GetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID)
3291 STATISTICS(jniinvokation());
3293 d = GET_FIELD(obj, double, fieldID);
3299 /* Set<type>Field Routines *****************************************************
3301 This family of accessor routines sets the value of an instance
3302 (nonstatic) field of an object. The field to access is specified by
3303 a field ID obtained by calling GetFieldID().
3305 *******************************************************************************/
3307 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
3310 STATISTICS(jniinvokation());
3312 SET_FIELD(obj, java_objectheader*, fieldID, value);
3316 void _Jv_JNI_SetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID,
3319 STATISTICS(jniinvokation());
3321 SET_FIELD(obj, s4, fieldID, value);
3325 void _Jv_JNI_SetByteField(JNIEnv *env, jobject obj, jfieldID fieldID,
3328 STATISTICS(jniinvokation());
3330 SET_FIELD(obj, s4, fieldID, value);
3334 void _Jv_JNI_SetCharField(JNIEnv *env, jobject obj, jfieldID fieldID,
3337 STATISTICS(jniinvokation());
3339 SET_FIELD(obj, s4, fieldID, value);
3343 void _Jv_JNI_SetShortField(JNIEnv *env, jobject obj, jfieldID fieldID,
3346 STATISTICS(jniinvokation());
3348 SET_FIELD(obj, s4, fieldID, value);
3352 void _Jv_JNI_SetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint value)
3354 STATISTICS(jniinvokation());
3356 SET_FIELD(obj, s4, fieldID, value);
3360 void _Jv_JNI_SetLongField(JNIEnv *env, jobject obj, jfieldID fieldID,
3363 STATISTICS(jniinvokation());
3365 SET_FIELD(obj, s8, fieldID, value);
3369 void _Jv_JNI_SetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID,
3372 STATISTICS(jniinvokation());
3374 SET_FIELD(obj, float, fieldID, value);
3378 void _Jv_JNI_SetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID,
3381 STATISTICS(jniinvokation());
3383 SET_FIELD(obj, double, fieldID, value);
3387 /* Calling Static Methods *****************************************************/
3389 /* GetStaticMethodID ***********************************************************
3391 Returns the method ID for a static method of a class. The method is
3392 specified by its name and signature.
3394 GetStaticMethodID() causes an uninitialized class to be
3397 *******************************************************************************/
3399 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
3407 STATISTICS(jniinvokation());
3409 c = (classinfo *) clazz;
3414 if (!(c->state & CLASS_INITIALIZED))
3415 if (!initialize_class(c))
3418 /* try to get the static method of the class */
3420 uname = utf_new_char((char *) name);
3421 udesc = utf_new_char((char *) sig);
3423 m = class_resolvemethod(c, uname, udesc);
3425 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
3426 exceptions_throw_nosuchmethoderror(c, uname, udesc);
3431 return (jmethodID) m;
3435 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
3436 jmethodID methodID, ...)
3439 java_objectheader *o;
3442 m = (methodinfo *) methodID;
3444 va_start(ap, methodID);
3445 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
3448 return _Jv_JNI_NewLocalRef(env, (jobject) o);
3452 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
3453 jmethodID methodID, va_list args)
3456 java_objectheader *o;
3458 m = (methodinfo *) methodID;
3460 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
3462 return _Jv_JNI_NewLocalRef(env, (jobject) o);
3466 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
3467 jmethodID methodID, const jvalue *args)
3470 java_objectheader *o;
3472 m = (methodinfo *) methodID;
3474 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
3476 return _Jv_JNI_NewLocalRef(env, (jobject) o);
3480 jboolean _Jv_JNI_CallStaticBooleanMethod(JNIEnv *env, jclass clazz,
3481 jmethodID methodID, ...)
3487 m = (methodinfo *) methodID;
3489 va_start(ap, methodID);
3490 b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3497 jboolean _Jv_JNI_CallStaticBooleanMethodV(JNIEnv *env, jclass clazz,
3498 jmethodID methodID, va_list args)
3503 m = (methodinfo *) methodID;
3505 b = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3511 jboolean _Jv_JNI_CallStaticBooleanMethodA(JNIEnv *env, jclass clazz,
3512 jmethodID methodID, const jvalue *args)
3517 m = (methodinfo *) methodID;
3519 b = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
3525 jbyte _Jv_JNI_CallStaticByteMethod(JNIEnv *env, jclass clazz,
3526 jmethodID methodID, ...)
3532 m = (methodinfo *) methodID;
3534 va_start(ap, methodID);
3535 b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3542 jbyte _Jv_JNI_CallStaticByteMethodV(JNIEnv *env, jclass clazz,
3543 jmethodID methodID, va_list args)
3548 m = (methodinfo *) methodID;
3550 b = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3556 jbyte _Jv_JNI_CallStaticByteMethodA(JNIEnv *env, jclass clazz,
3557 jmethodID methodID, const jvalue *args)
3562 m = (methodinfo *) methodID;
3564 b = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
3570 jchar _Jv_JNI_CallStaticCharMethod(JNIEnv *env, jclass clazz,
3571 jmethodID methodID, ...)
3577 m = (methodinfo *) methodID;
3579 va_start(ap, methodID);
3580 c = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3587 jchar _Jv_JNI_CallStaticCharMethodV(JNIEnv *env, jclass clazz,
3588 jmethodID methodID, va_list args)
3593 m = (methodinfo *) methodID;
3595 c = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3601 jchar _Jv_JNI_CallStaticCharMethodA(JNIEnv *env, jclass clazz,
3602 jmethodID methodID, const jvalue *args)
3607 m = (methodinfo *) methodID;
3609 c = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
3615 jshort _Jv_JNI_CallStaticShortMethod(JNIEnv *env, jclass clazz,
3616 jmethodID methodID, ...)
3622 m = (methodinfo *) methodID;
3624 va_start(ap, methodID);
3625 s = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3632 jshort _Jv_JNI_CallStaticShortMethodV(JNIEnv *env, jclass clazz,
3633 jmethodID methodID, va_list args)
3638 m = (methodinfo *) methodID;
3640 s = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3646 jshort _Jv_JNI_CallStaticShortMethodA(JNIEnv *env, jclass clazz,
3647 jmethodID methodID, const jvalue *args)
3652 m = (methodinfo *) methodID;
3654 s = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
3660 jint _Jv_JNI_CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID,
3667 m = (methodinfo *) methodID;
3669 va_start(ap, methodID);
3670 i = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3677 jint _Jv_JNI_CallStaticIntMethodV(JNIEnv *env, jclass clazz,
3678 jmethodID methodID, va_list args)
3683 m = (methodinfo *) methodID;
3685 i = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3691 jint _Jv_JNI_CallStaticIntMethodA(JNIEnv *env, jclass clazz,
3692 jmethodID methodID, const jvalue *args)
3697 m = (methodinfo *) methodID;
3699 i = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
3705 jlong _Jv_JNI_CallStaticLongMethod(JNIEnv *env, jclass clazz,
3706 jmethodID methodID, ...)
3712 m = (methodinfo *) methodID;
3714 va_start(ap, methodID);
3715 l = _Jv_jni_CallLongMethod(NULL, NULL, m, ap);
3722 jlong _Jv_JNI_CallStaticLongMethodV(JNIEnv *env, jclass clazz,
3723 jmethodID methodID, va_list args)
3728 m = (methodinfo *) methodID;
3730 l = _Jv_jni_CallLongMethod(NULL, NULL, m, args);
3736 jlong _Jv_JNI_CallStaticLongMethodA(JNIEnv *env, jclass clazz,
3737 jmethodID methodID, const jvalue *args)
3742 m = (methodinfo *) methodID;
3744 l = _Jv_jni_CallLongMethodA(NULL, NULL, m, args);
3751 jfloat _Jv_JNI_CallStaticFloatMethod(JNIEnv *env, jclass clazz,
3752 jmethodID methodID, ...)
3758 m = (methodinfo *) methodID;
3760 va_start(ap, methodID);
3761 f = _Jv_jni_CallFloatMethod(NULL, NULL, m, ap);
3768 jfloat _Jv_JNI_CallStaticFloatMethodV(JNIEnv *env, jclass clazz,
3769 jmethodID methodID, va_list args)
3774 m = (methodinfo *) methodID;
3776 f = _Jv_jni_CallFloatMethod(NULL, NULL, m, args);
3782 jfloat _Jv_JNI_CallStaticFloatMethodA(JNIEnv *env, jclass clazz,
3783 jmethodID methodID, const jvalue *args)
3788 m = (methodinfo *) methodID;
3790 f = _Jv_jni_CallFloatMethodA(NULL, NULL, m, args);
3796 jdouble _Jv_JNI_CallStaticDoubleMethod(JNIEnv *env, jclass clazz,
3797 jmethodID methodID, ...)
3803 m = (methodinfo *) methodID;
3805 va_start(ap, methodID);
3806 d = _Jv_jni_CallDoubleMethod(NULL, NULL, m, ap);
3813 jdouble _Jv_JNI_CallStaticDoubleMethodV(JNIEnv *env, jclass clazz,
3814 jmethodID methodID, va_list args)
3819 m = (methodinfo *) methodID;
3821 d = _Jv_jni_CallDoubleMethod(NULL, NULL, m, args);
3827 jdouble _Jv_JNI_CallStaticDoubleMethodA(JNIEnv *env, jclass clazz,
3828 jmethodID methodID, const jvalue *args)
3833 m = (methodinfo *) methodID;
3835 d = _Jv_jni_CallDoubleMethodA(NULL, NULL, m, args);
3841 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
3842 jmethodID methodID, ...)
3847 m = (methodinfo *) methodID;
3849 va_start(ap, methodID);
3850 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
3855 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
3856 jmethodID methodID, va_list args)
3860 m = (methodinfo *) methodID;
3862 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
3866 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
3867 jmethodID methodID, const jvalue * args)
3871 m = (methodinfo *) methodID;
3873 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
3877 /* Accessing Static Fields ****************************************************/
3879 /* GetStaticFieldID ************************************************************
3881 Returns the field ID for a static field of a class. The field is
3882 specified by its name and signature. The GetStatic<type>Field and
3883 SetStatic<type>Field families of accessor functions use field IDs
3884 to retrieve static fields.
3886 *******************************************************************************/
3888 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
3896 STATISTICS(jniinvokation());
3898 c = (classinfo *) clazz;
3900 uname = utf_new_char((char *) name);
3901 usig = utf_new_char((char *) sig);
3903 f = class_findfield(c, uname, usig);
3906 exceptions_throw_nosuchfielderror(c, uname);
3908 return (jfieldID) f;
3912 /* GetStatic<type>Field ********************************************************
3914 This family of accessor routines returns the value of a static
3917 *******************************************************************************/
3919 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
3925 STATISTICS(jniinvokation());
3927 c = (classinfo *) clazz;
3928 f = (fieldinfo *) fieldID;
3930 if (!(c->state & CLASS_INITIALIZED))
3931 if (!initialize_class(c))
3934 return _Jv_JNI_NewLocalRef(env, f->value.a);
3938 jboolean _Jv_JNI_GetStaticBooleanField(JNIEnv *env, jclass clazz,
3944 STATISTICS(jniinvokation());
3946 c = (classinfo *) clazz;
3947 f = (fieldinfo *) fieldID;
3949 if (!(c->state & CLASS_INITIALIZED))
3950 if (!initialize_class(c))
3957 jbyte _Jv_JNI_GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3962 STATISTICS(jniinvokation());
3964 c = (classinfo *) clazz;
3965 f = (fieldinfo *) fieldID;
3967 if (!(c->state & CLASS_INITIALIZED))
3968 if (!initialize_class(c))
3975 jchar _Jv_JNI_GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3980 STATISTICS(jniinvokation());
3982 c = (classinfo *) clazz;
3983 f = (fieldinfo *) fieldID;
3985 if (!(c->state & CLASS_INITIALIZED))
3986 if (!initialize_class(c))
3993 jshort _Jv_JNI_GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3998 STATISTICS(jniinvokation());
4000 c = (classinfo *) clazz;
4001 f = (fieldinfo *) fieldID;
4003 if (!(c->state & CLASS_INITIALIZED))
4004 if (!initialize_class(c))
4011 jint _Jv_JNI_GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
4016 STATISTICS(jniinvokation());
4018 c = (classinfo *) clazz;
4019 f = (fieldinfo *) fieldID;
4021 if (!(c->state & CLASS_INITIALIZED))
4022 if (!initialize_class(c))
4029 jlong _Jv_JNI_GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
4034 STATISTICS(jniinvokation());
4036 c = (classinfo *) clazz;
4037 f = (fieldinfo *) fieldID;
4039 if (!(c->state & CLASS_INITIALIZED))
4040 if (!initialize_class(c))
4047 jfloat _Jv_JNI_GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
4052 STATISTICS(jniinvokation());
4054 c = (classinfo *) clazz;
4055 f = (fieldinfo *) fieldID;
4057 if (!(c->state & CLASS_INITIALIZED))
4058 if (!initialize_class(c))
4065 jdouble _Jv_JNI_GetStaticDoubleField(JNIEnv *env, jclass clazz,
4071 STATISTICS(jniinvokation());
4073 c = (classinfo *) clazz;
4074 f = (fieldinfo *) fieldID;
4076 if (!(c->state & CLASS_INITIALIZED))
4077 if (!initialize_class(c))
4084 /* SetStatic<type>Field *******************************************************
4086 This family of accessor routines sets the value of a static field
4089 *******************************************************************************/
4091 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4097 STATISTICS(jniinvokation());
4099 c = (classinfo *) clazz;
4100 f = (fieldinfo *) fieldID;
4102 if (!(c->state & CLASS_INITIALIZED))
4103 if (!initialize_class(c))
4110 void _Jv_JNI_SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4116 STATISTICS(jniinvokation());
4118 c = (classinfo *) clazz;
4119 f = (fieldinfo *) fieldID;
4121 if (!(c->state & CLASS_INITIALIZED))
4122 if (!initialize_class(c))
4129 void _Jv_JNI_SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4135 STATISTICS(jniinvokation());
4137 c = (classinfo *) clazz;
4138 f = (fieldinfo *) fieldID;
4140 if (!(c->state & CLASS_INITIALIZED))
4141 if (!initialize_class(c))
4148 void _Jv_JNI_SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4154 STATISTICS(jniinvokation());
4156 c = (classinfo *) clazz;
4157 f = (fieldinfo *) fieldID;
4159 if (!(c->state & CLASS_INITIALIZED))
4160 if (!initialize_class(c))
4167 void _Jv_JNI_SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4173 STATISTICS(jniinvokation());
4175 c = (classinfo *) clazz;
4176 f = (fieldinfo *) fieldID;
4178 if (!(c->state & CLASS_INITIALIZED))
4179 if (!initialize_class(c))
4186 void _Jv_JNI_SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4192 STATISTICS(jniinvokation());
4194 c = (classinfo *) clazz;
4195 f = (fieldinfo *) fieldID;
4197 if (!(c->state & CLASS_INITIALIZED))
4198 if (!initialize_class(c))
4205 void _Jv_JNI_SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4211 STATISTICS(jniinvokation());
4213 c = (classinfo *) clazz;
4214 f = (fieldinfo *) fieldID;
4216 if (!(c->state & CLASS_INITIALIZED))
4217 if (!initialize_class(c))
4224 void _Jv_JNI_SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4230 STATISTICS(jniinvokation());
4232 c = (classinfo *) clazz;
4233 f = (fieldinfo *) fieldID;
4235 if (!(c->state & CLASS_INITIALIZED))
4236 if (!initialize_class(c))
4243 void _Jv_JNI_SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4249 STATISTICS(jniinvokation());
4251 c = (classinfo *) clazz;
4252 f = (fieldinfo *) fieldID;
4254 if (!(c->state & CLASS_INITIALIZED))
4255 if (!initialize_class(c))
4262 /* String Operations **********************************************************/
4264 /* NewString *******************************************************************
4266 Create new java.lang.String object from an array of Unicode
4269 *******************************************************************************/
4271 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
4273 java_lang_String *s;
4277 STATISTICS(jniinvokation());
4279 s = (java_lang_String *) builtin_new(class_java_lang_String);
4280 a = builtin_newarray_char(len);
4282 /* javastring or characterarray could not be created */
4283 if ((a == NULL) || (s == NULL))
4287 for (i = 0; i < len; i++)
4288 a->data[i] = buf[i];
4294 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
4298 static jchar emptyStringJ[]={0,0};
4300 /* GetStringLength *************************************************************
4302 Returns the length (the count of Unicode characters) of a Java
4305 *******************************************************************************/
4307 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
4309 java_lang_String *s;
4311 s = (java_lang_String *) str;
4317 /******************** convertes javastring to u2-array ****************************/
4319 u2 *javastring_tou2(jstring so)
4321 java_lang_String *s;
4326 STATISTICS(jniinvokation());
4328 s = (java_lang_String *) so;
4338 /* allocate memory */
4340 stringbuffer = MNEW(u2, s->count + 1);
4344 for (i = 0; i < s->count; i++)
4345 stringbuffer[i] = a->data[s->offset + i];
4347 /* terminate string */
4349 stringbuffer[i] = '\0';
4351 return stringbuffer;
4355 /* GetStringChars **************************************************************
4357 Returns a pointer to the array of Unicode characters of the
4358 string. This pointer is valid until ReleaseStringChars() is called.
4360 *******************************************************************************/
4362 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
4366 STATISTICS(jniinvokation());
4368 jc = javastring_tou2(str);
4380 return emptyStringJ;
4384 /* ReleaseStringChars **********************************************************
4386 Informs the VM that the native code no longer needs access to
4387 chars. The chars argument is a pointer obtained from string using
4390 *******************************************************************************/
4392 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
4394 STATISTICS(jniinvokation());
4396 if (chars == emptyStringJ)
4399 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
4403 /* NewStringUTF ****************************************************************
4405 Constructs a new java.lang.String object from an array of UTF-8
4408 *******************************************************************************/
4410 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
4412 java_lang_String *s;
4414 STATISTICS(jniinvokation());
4416 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
4418 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
4422 /****************** returns the utf8 length in bytes of a string *******************/
4424 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
4426 java_lang_String *s;
4429 STATISTICS(jniinvokation());
4431 s = (java_lang_String *) string;
4433 length = u2_utflength(s->value->data, s->count);
4439 /* GetStringUTFChars ***********************************************************
4441 Returns a pointer to an array of UTF-8 characters of the
4442 string. This array is valid until it is released by
4443 ReleaseStringUTFChars().
4445 *******************************************************************************/
4447 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
4452 STATISTICS(jniinvokation());
4460 u = javastring_toutf((java_objectheader *) string, false);
4469 /* ReleaseStringUTFChars *******************************************************
4471 Informs the VM that the native code no longer needs access to
4472 utf. The utf argument is a pointer derived from string using
4473 GetStringUTFChars().
4475 *******************************************************************************/
4477 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
4479 STATISTICS(jniinvokation());
4481 /* XXX we don't release utf chars right now, perhaps that should be done
4482 later. Since there is always one reference the garbage collector will
4487 /* Array Operations ***********************************************************/
4489 /* GetArrayLength **************************************************************
4491 Returns the number of elements in the array.
4493 *******************************************************************************/
4495 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
4497 java_arrayheader *a;
4499 STATISTICS(jniinvokation());
4501 a = (java_arrayheader *) array;
4507 /* NewObjectArray **************************************************************
4509 Constructs a new array holding objects in class elementClass. All
4510 elements are initially set to initialElement.
4512 *******************************************************************************/
4514 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
4515 jclass elementClass, jobject initialElement)
4518 java_objectheader *o;
4519 java_objectarray *oa;
4522 STATISTICS(jniinvokation());
4524 c = (classinfo *) elementClass;
4525 o = (java_objectheader *) initialElement;
4528 exceptions_throw_negativearraysizeexception();
4532 oa = builtin_anewarray(length, c);
4537 /* set all elements to initialElement */
4539 for (i = 0; i < length; i++)
4542 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
4546 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
4549 java_objectarray *oa;
4550 java_objectheader *o;
4552 STATISTICS(jniinvokation());
4554 oa = (java_objectarray *) array;
4556 if (index >= oa->header.size) {
4557 exceptions_throw_arrayindexoutofboundsexception();
4561 o = oa->data[index];
4563 return _Jv_JNI_NewLocalRef(env, (jobject) o);
4567 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
4568 jsize index, jobject val)
4570 java_objectarray *oa;
4571 java_objectheader *o;
4573 STATISTICS(jniinvokation());
4575 oa = (java_objectarray *) array;
4576 o = (java_objectheader *) val;
4578 if (index >= oa->header.size) {
4579 exceptions_throw_arrayindexoutofboundsexception();
4583 /* check if the class of value is a subclass of the element class
4586 if (!builtin_canstore(oa, o))
4589 oa->data[index] = o;
4593 jbooleanArray _Jv_JNI_NewBooleanArray(JNIEnv *env, jsize len)
4595 java_booleanarray *ba;
4597 STATISTICS(jniinvokation());
4600 exceptions_throw_negativearraysizeexception();
4604 ba = builtin_newarray_boolean(len);
4606 return (jbooleanArray) _Jv_JNI_NewLocalRef(env, (jobject) ba);
4610 jbyteArray _Jv_JNI_NewByteArray(JNIEnv *env, jsize len)
4614 STATISTICS(jniinvokation());
4617 exceptions_throw_negativearraysizeexception();
4621 ba = builtin_newarray_byte(len);
4623 return (jbyteArray) _Jv_JNI_NewLocalRef(env, (jobject) ba);
4627 jcharArray _Jv_JNI_NewCharArray(JNIEnv *env, jsize len)
4631 STATISTICS(jniinvokation());
4634 exceptions_throw_negativearraysizeexception();
4638 ca = builtin_newarray_char(len);
4640 return (jcharArray) _Jv_JNI_NewLocalRef(env, (jobject) ca);
4644 jshortArray _Jv_JNI_NewShortArray(JNIEnv *env, jsize len)
4646 java_shortarray *sa;
4648 STATISTICS(jniinvokation());
4651 exceptions_throw_negativearraysizeexception();
4655 sa = builtin_newarray_short(len);
4657 return (jshortArray) _Jv_JNI_NewLocalRef(env, (jobject) sa);
4661 jintArray _Jv_JNI_NewIntArray(JNIEnv *env, jsize len)
4665 STATISTICS(jniinvokation());
4668 exceptions_throw_negativearraysizeexception();
4672 ia = builtin_newarray_int(len);
4674 return (jintArray) _Jv_JNI_NewLocalRef(env, (jobject) ia);
4678 jlongArray _Jv_JNI_NewLongArray(JNIEnv *env, jsize len)
4682 STATISTICS(jniinvokation());
4685 exceptions_throw_negativearraysizeexception();
4689 la = builtin_newarray_long(len);
4691 return (jlongArray) _Jv_JNI_NewLocalRef(env, (jobject) la);
4695 jfloatArray _Jv_JNI_NewFloatArray(JNIEnv *env, jsize len)
4697 java_floatarray *fa;
4699 STATISTICS(jniinvokation());
4702 exceptions_throw_negativearraysizeexception();
4706 fa = builtin_newarray_float(len);
4708 return (jfloatArray) _Jv_JNI_NewLocalRef(env, (jobject) fa);
4712 jdoubleArray _Jv_JNI_NewDoubleArray(JNIEnv *env, jsize len)
4714 java_doublearray *da;
4716 STATISTICS(jniinvokation());
4719 exceptions_throw_negativearraysizeexception();
4723 da = builtin_newarray_double(len);
4725 return (jdoubleArray) _Jv_JNI_NewLocalRef(env, (jobject) da);
4729 /* Get<PrimitiveType>ArrayElements *********************************************
4731 A family of functions that returns the body of the primitive array.
4733 *******************************************************************************/
4735 jboolean *_Jv_JNI_GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
4738 java_booleanarray *ba;
4740 STATISTICS(jniinvokation());
4742 ba = (java_booleanarray *) array;
4745 *isCopy = JNI_FALSE;
4751 jbyte *_Jv_JNI_GetByteArrayElements(JNIEnv *env, jbyteArray array,
4756 STATISTICS(jniinvokation());
4758 ba = (java_bytearray *) array;
4761 *isCopy = JNI_FALSE;
4767 jchar *_Jv_JNI_GetCharArrayElements(JNIEnv *env, jcharArray array,
4772 STATISTICS(jniinvokation());
4774 ca = (java_chararray *) array;
4777 *isCopy = JNI_FALSE;
4783 jshort *_Jv_JNI_GetShortArrayElements(JNIEnv *env, jshortArray array,
4786 java_shortarray *sa;
4788 STATISTICS(jniinvokation());
4790 sa = (java_shortarray *) array;
4793 *isCopy = JNI_FALSE;
4799 jint *_Jv_JNI_GetIntArrayElements(JNIEnv *env, jintArray array,
4804 STATISTICS(jniinvokation());
4806 ia = (java_intarray *) array;
4809 *isCopy = JNI_FALSE;
4815 jlong *_Jv_JNI_GetLongArrayElements(JNIEnv *env, jlongArray array,
4820 STATISTICS(jniinvokation());
4822 la = (java_longarray *) array;
4825 *isCopy = JNI_FALSE;
4827 /* We cast this one to prevent a compiler warning on 64-bit
4828 systems since GNU Classpath typedef jlong to long long. */
4830 return (jlong *) la->data;
4834 jfloat *_Jv_JNI_GetFloatArrayElements(JNIEnv *env, jfloatArray array,
4837 java_floatarray *fa;
4839 STATISTICS(jniinvokation());
4841 fa = (java_floatarray *) array;
4844 *isCopy = JNI_FALSE;
4850 jdouble *_Jv_JNI_GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
4853 java_doublearray *da;
4855 STATISTICS(jniinvokation());
4857 da = (java_doublearray *) array;
4860 *isCopy = JNI_FALSE;
4866 /* Release<PrimitiveType>ArrayElements *****************************************
4868 A family of functions that informs the VM that the native code no
4869 longer needs access to elems. The elems argument is a pointer
4870 derived from array using the corresponding
4871 Get<PrimitiveType>ArrayElements() function. If necessary, this
4872 function copies back all changes made to elems to the original
4875 *******************************************************************************/
4877 void _Jv_JNI_ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
4878 jboolean *elems, jint mode)
4880 java_booleanarray *ba;
4882 STATISTICS(jniinvokation());
4884 ba = (java_booleanarray *) array;
4886 if (elems != ba->data) {
4889 MCOPY(ba->data, elems, u1, ba->header.size);
4892 MCOPY(ba->data, elems, u1, ba->header.size);
4893 /* XXX TWISTI how should it be freed? */
4896 /* XXX TWISTI how should it be freed? */
4903 void _Jv_JNI_ReleaseByteArrayElements(JNIEnv *env, jbyteArray array,
4904 jbyte *elems, jint mode)
4908 STATISTICS(jniinvokation());
4910 ba = (java_bytearray *) array;
4912 if (elems != ba->data) {
4915 MCOPY(ba->data, elems, s1, ba->header.size);
4918 MCOPY(ba->data, elems, s1, ba->header.size);
4919 /* XXX TWISTI how should it be freed? */
4922 /* XXX TWISTI how should it be freed? */
4929 void _Jv_JNI_ReleaseCharArrayElements(JNIEnv *env, jcharArray array,
4930 jchar *elems, jint mode)
4934 STATISTICS(jniinvokation());
4936 ca = (java_chararray *) array;
4938 if (elems != ca->data) {
4941 MCOPY(ca->data, elems, u2, ca->header.size);
4944 MCOPY(ca->data, elems, u2, ca->header.size);
4945 /* XXX TWISTI how should it be freed? */
4948 /* XXX TWISTI how should it be freed? */
4955 void _Jv_JNI_ReleaseShortArrayElements(JNIEnv *env, jshortArray array,
4956 jshort *elems, jint mode)
4958 java_shortarray *sa;
4960 STATISTICS(jniinvokation());
4962 sa = (java_shortarray *) array;
4964 if (elems != sa->data) {
4967 MCOPY(sa->data, elems, s2, sa->header.size);
4970 MCOPY(sa->data, elems, s2, sa->header.size);
4971 /* XXX TWISTI how should it be freed? */
4974 /* XXX TWISTI how should it be freed? */
4981 void _Jv_JNI_ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
4986 STATISTICS(jniinvokation());
4988 ia = (java_intarray *) array;
4990 if (elems != ia->data) {
4993 MCOPY(ia->data, elems, s4, ia->header.size);
4996 MCOPY(ia->data, elems, s4, ia->header.size);
4997 /* XXX TWISTI how should it be freed? */
5000 /* XXX TWISTI how should it be freed? */
5007 void _Jv_JNI_ReleaseLongArrayElements(JNIEnv *env, jlongArray array,
5008 jlong *elems, jint mode)
5012 STATISTICS(jniinvokation());
5014 la = (java_longarray *) array;
5016 /* We cast this one to prevent a compiler warning on 64-bit
5017 systems since GNU Classpath typedef jlong to long long. */
5019 if ((s8 *) elems != la->data) {
5022 MCOPY(la->data, elems, s8, la->header.size);
5025 MCOPY(la->data, elems, s8, la->header.size);
5026 /* XXX TWISTI how should it be freed? */
5029 /* XXX TWISTI how should it be freed? */
5036 void _Jv_JNI_ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array,
5037 jfloat *elems, jint mode)
5039 java_floatarray *fa;
5041 STATISTICS(jniinvokation());
5043 fa = (java_floatarray *) array;
5045 if (elems != fa->data) {
5048 MCOPY(fa->data, elems, float, fa->header.size);
5051 MCOPY(fa->data, elems, float, fa->header.size);
5052 /* XXX TWISTI how should it be freed? */
5055 /* XXX TWISTI how should it be freed? */
5062 void _Jv_JNI_ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
5063 jdouble *elems, jint mode)
5065 java_doublearray *da;
5067 STATISTICS(jniinvokation());
5069 da = (java_doublearray *) array;
5071 if (elems != da->data) {
5074 MCOPY(da->data, elems, double, da->header.size);
5077 MCOPY(da->data, elems, double, da->header.size);
5078 /* XXX TWISTI how should it be freed? */
5081 /* XXX TWISTI how should it be freed? */
5088 /* Get<PrimitiveType>ArrayRegion **********************************************
5090 A family of functions that copies a region of a primitive array
5093 *******************************************************************************/
5095 void _Jv_JNI_GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array,
5096 jsize start, jsize len, jboolean *buf)
5098 java_booleanarray *ba;
5100 STATISTICS(jniinvokation());
5102 ba = (java_booleanarray *) array;
5104 if ((start < 0) || (len < 0) || (start + len > ba->header.size))
5105 exceptions_throw_arrayindexoutofboundsexception();
5107 MCOPY(buf, &ba->data[start], u1, len);
5111 void _Jv_JNI_GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start,
5112 jsize len, jbyte *buf)
5116 STATISTICS(jniinvokation());
5118 ba = (java_bytearray *) array;
5120 if ((start < 0) || (len < 0) || (start + len > ba->header.size))
5121 exceptions_throw_arrayindexoutofboundsexception();
5123 MCOPY(buf, &ba->data[start], s1, len);
5127 void _Jv_JNI_GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start,
5128 jsize len, jchar *buf)
5132 STATISTICS(jniinvokation());
5134 ca = (java_chararray *) array;
5136 if ((start < 0) || (len < 0) || (start + len > ca->header.size))
5137 exceptions_throw_arrayindexoutofboundsexception();
5139 MCOPY(buf, &ca->data[start], u2, len);
5143 void _Jv_JNI_GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
5144 jsize len, jshort *buf)
5146 java_shortarray *sa;
5148 STATISTICS(jniinvokation());
5150 sa = (java_shortarray *) array;
5152 if ((start < 0) || (len < 0) || (start + len > sa->header.size))
5153 exceptions_throw_arrayindexoutofboundsexception();
5155 MCOPY(buf, &sa->data[start], s2, len);
5159 void _Jv_JNI_GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start,
5160 jsize len, jint *buf)
5164 STATISTICS(jniinvokation());
5166 ia = (java_intarray *) array;
5168 if ((start < 0) || (len < 0) || (start + len > ia->header.size))
5169 exceptions_throw_arrayindexoutofboundsexception();
5171 MCOPY(buf, &ia->data[start], s4, len);
5175 void _Jv_JNI_GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start,
5176 jsize len, jlong *buf)
5180 STATISTICS(jniinvokation());
5182 la = (java_longarray *) array;
5184 if ((start < 0) || (len < 0) || (start + len > la->header.size))
5185 exceptions_throw_arrayindexoutofboundsexception();
5187 MCOPY(buf, &la->data[start], s8, len);
5191 void _Jv_JNI_GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
5192 jsize len, jfloat *buf)
5194 java_floatarray *fa;
5196 STATISTICS(jniinvokation());
5198 fa = (java_floatarray *) array;
5200 if ((start < 0) || (len < 0) || (start + len > fa->header.size))
5201 exceptions_throw_arrayindexoutofboundsexception();
5203 MCOPY(buf, &fa->data[start], float, len);
5207 void _Jv_JNI_GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
5208 jsize len, jdouble *buf)
5210 java_doublearray *da;
5212 STATISTICS(jniinvokation());
5214 da = (java_doublearray *) array;
5216 if ((start < 0) || (len < 0) || (start + len > da->header.size))
5217 exceptions_throw_arrayindexoutofboundsexception();
5219 MCOPY(buf, &da->data[start], double, len);
5223 /* Set<PrimitiveType>ArrayRegion **********************************************
5225 A family of functions that copies back a region of a primitive
5226 array from a buffer.
5228 *******************************************************************************/
5230 void _Jv_JNI_SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array,
5231 jsize start, jsize len, const jboolean *buf)
5233 java_booleanarray *ba;
5235 STATISTICS(jniinvokation());
5237 ba = (java_booleanarray *) array;
5239 if ((start < 0) || (len < 0) || (start + len > ba->header.size))
5240 exceptions_throw_arrayindexoutofboundsexception();
5242 MCOPY(&ba->data[start], buf, u1, len);
5246 void _Jv_JNI_SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start,
5247 jsize len, const jbyte *buf)
5251 STATISTICS(jniinvokation());
5253 ba = (java_bytearray *) array;
5255 if ((start < 0) || (len < 0) || (start + len > ba->header.size))
5256 exceptions_throw_arrayindexoutofboundsexception();
5258 MCOPY(&ba->data[start], buf, s1, len);
5262 void _Jv_JNI_SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start,
5263 jsize len, const jchar *buf)
5267 STATISTICS(jniinvokation());
5269 ca = (java_chararray *) array;
5271 if ((start < 0) || (len < 0) || (start + len > ca->header.size))
5272 exceptions_throw_arrayindexoutofboundsexception();
5274 MCOPY(&ca->data[start], buf, u2, len);
5278 void _Jv_JNI_SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
5279 jsize len, const jshort *buf)
5281 java_shortarray *sa;
5283 STATISTICS(jniinvokation());
5285 sa = (java_shortarray *) array;
5287 if ((start < 0) || (len < 0) || (start + len > sa->header.size))
5288 exceptions_throw_arrayindexoutofboundsexception();
5290 MCOPY(&sa->data[start], buf, s2, len);
5294 void _Jv_JNI_SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start,
5295 jsize len, const jint *buf)
5299 STATISTICS(jniinvokation());
5301 ia = (java_intarray *) array;
5303 if ((start < 0) || (len < 0) || (start + len > ia->header.size))
5304 exceptions_throw_arrayindexoutofboundsexception();
5306 MCOPY(&ia->data[start], buf, s4, len);
5310 void _Jv_JNI_SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start,
5311 jsize len, const jlong *buf)
5315 STATISTICS(jniinvokation());
5317 la = (java_longarray *) array;
5319 if ((start < 0) || (len < 0) || (start + len > la->header.size))
5320 exceptions_throw_arrayindexoutofboundsexception();
5322 MCOPY(&la->data[start], buf, s8, len);
5326 void _Jv_JNI_SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
5327 jsize len, const jfloat *buf)
5329 java_floatarray *fa;
5331 STATISTICS(jniinvokation());
5333 fa = (java_floatarray *) array;
5335 if ((start < 0) || (len < 0) || (start + len > fa->header.size))
5336 exceptions_throw_arrayindexoutofboundsexception();
5338 MCOPY(&fa->data[start], buf, float, len);
5342 void _Jv_JNI_SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
5343 jsize len, const jdouble *buf)
5345 java_doublearray *da;
5347 STATISTICS(jniinvokation());
5349 da = (java_doublearray *) array;
5351 if ((start < 0) || (len < 0) || (start + len > da->header.size))
5352 exceptions_throw_arrayindexoutofboundsexception();
5354 MCOPY(&da->data[start], buf, double, len);
5358 /* Registering Native Methods *************************************************/
5360 /* RegisterNatives *************************************************************
5362 Registers native methods with the class specified by the clazz
5363 argument. The methods parameter specifies an array of
5364 JNINativeMethod structures that contain the names, signatures, and
5365 function pointers of the native methods. The nMethods parameter
5366 specifies the number of native methods in the array.
5368 *******************************************************************************/
5370 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
5371 const JNINativeMethod *methods, jint nMethods)
5375 STATISTICS(jniinvokation());
5377 c = (classinfo *) clazz;
5379 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
5380 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
5383 native_method_register(c->name, methods, nMethods);
5389 /* UnregisterNatives ***********************************************************
5391 Unregisters native methods of a class. The class goes back to the
5392 state before it was linked or registered with its native method
5395 This function should not be used in normal native code. Instead, it
5396 provides special programs a way to reload and relink native
5399 *******************************************************************************/
5401 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
5403 STATISTICS(jniinvokation());
5405 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
5407 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
5413 /* Monitor Operations *********************************************************/
5415 /* MonitorEnter ****************************************************************
5417 Enters the monitor associated with the underlying Java object
5420 *******************************************************************************/
5422 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
5424 STATISTICS(jniinvokation());
5427 exceptions_throw_nullpointerexception();
5431 LOCK_MONITOR_ENTER(obj);
5437 /* MonitorExit *****************************************************************
5439 The current thread must be the owner of the monitor associated with
5440 the underlying Java object referred to by obj. The thread
5441 decrements the counter indicating the number of times it has
5442 entered this monitor. If the value of the counter becomes zero, the
5443 current thread releases the monitor.
5445 *******************************************************************************/
5447 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
5449 STATISTICS(jniinvokation());
5452 exceptions_throw_nullpointerexception();
5456 LOCK_MONITOR_EXIT(obj);
5462 /* JavaVM Interface ***********************************************************/
5464 /* GetJavaVM *******************************************************************
5466 Returns the Java VM interface (used in the Invocation API)
5467 associated with the current thread. The result is placed at the
5468 location pointed to by the second argument, vm.
5470 *******************************************************************************/
5472 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
5474 STATISTICS(jniinvokation());
5476 *vm = (JavaVM *) _Jv_jvm;
5482 /* GetStringRegion *************************************************************
5484 Copies len number of Unicode characters beginning at offset start
5485 to the given buffer buf.
5487 Throws StringIndexOutOfBoundsException on index overflow.
5489 *******************************************************************************/
5491 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
5494 java_lang_String *s;
5497 STATISTICS(jniinvokation());
5499 s = (java_lang_String *) str;
5502 if ((start < 0) || (len < 0) || (start > s->count) ||
5503 (start + len > s->count)) {
5504 exceptions_throw_stringindexoutofboundsexception();
5508 MCOPY(buf, &ca->data[start], u2, len);
5512 /* GetStringUTFRegion **********************************************************
5514 Translates len number of Unicode characters beginning at offset
5515 start into UTF-8 format and place the result in the given buffer
5518 Throws StringIndexOutOfBoundsException on index overflow.
5520 *******************************************************************************/
5522 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
5523 jsize len, char *buf)
5525 java_lang_String *s;
5529 STATISTICS(jniinvokation());
5531 s = (java_lang_String *) str;
5534 if ((start < 0) || (len < 0) || (start > s->count) ||
5535 (start + len > s->count)) {
5536 exceptions_throw_stringindexoutofboundsexception();
5540 /* XXX not sure if this is correct */
5542 for (i = 0; i < len; i++)
5543 buf[i] = ca->data[start + i];
5549 /* GetPrimitiveArrayCritical ***************************************************
5551 Obtain a direct pointer to array elements.
5553 *******************************************************************************/
5555 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
5561 ba = (java_bytearray *) array;
5563 /* do the same as Kaffe does */
5565 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
5571 /* ReleasePrimitiveArrayCritical ***********************************************
5573 No specific documentation.
5575 *******************************************************************************/
5577 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
5578 void *carray, jint mode)
5580 STATISTICS(jniinvokation());
5582 /* do the same as Kaffe does */
5584 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
5589 /* GetStringCritical ***********************************************************
5591 The semantics of these two functions are similar to the existing
5592 Get/ReleaseStringChars functions.
5594 *******************************************************************************/
5596 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
5599 STATISTICS(jniinvokation());
5601 return _Jv_JNI_GetStringChars(env, string, isCopy);
5605 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
5606 const jchar *cstring)
5608 STATISTICS(jniinvokation());
5610 _Jv_JNI_ReleaseStringChars(env, string, cstring);
5614 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
5616 STATISTICS(jniinvokation());
5618 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
5624 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
5626 STATISTICS(jniinvokation());
5628 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
5632 /* NewGlobalRef ****************************************************************
5634 Creates a new global reference to the object referred to by the obj
5637 *******************************************************************************/
5639 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
5641 hashtable_global_ref_entry *gre;
5642 u4 key; /* hashkey */
5643 u4 slot; /* slot in hashtable */
5644 java_objectheader *o;
5646 STATISTICS(jniinvokation());
5648 o = (java_objectheader *) obj;
5650 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
5652 /* normally addresses are aligned to 4, 8 or 16 bytes */
5654 key = ((u4) (ptrint) obj) >> 4; /* align to 16-byte boundaries */
5655 slot = key & (hashtable_global_ref->size - 1);
5656 gre = hashtable_global_ref->ptr[slot];
5658 /* search external hash chain for the entry */
5662 /* global object found, increment the reference */
5666 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5671 gre = gre->hashlink; /* next element in external chain */
5674 /* global ref not found, create a new one */
5676 gre = NEW(hashtable_global_ref_entry);
5681 /* insert entry into hashtable */
5683 gre->hashlink = hashtable_global_ref->ptr[slot];
5685 hashtable_global_ref->ptr[slot] = gre;
5687 /* update number of hashtable-entries */
5689 hashtable_global_ref->entries++;
5691 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5697 /* DeleteGlobalRef *************************************************************
5699 Deletes the global reference pointed to by globalRef.
5701 *******************************************************************************/
5703 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
5705 hashtable_global_ref_entry *gre;
5706 hashtable_global_ref_entry *prevgre;
5707 u4 key; /* hashkey */
5708 u4 slot; /* slot in hashtable */
5709 java_objectheader *o;
5711 STATISTICS(jniinvokation());
5713 o = (java_objectheader *) globalRef;
5715 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
5717 /* normally addresses are aligned to 4, 8 or 16 bytes */
5719 key = ((u4) (ptrint) globalRef) >> 4; /* align to 16-byte boundaries */
5720 slot = key & (hashtable_global_ref->size - 1);
5721 gre = hashtable_global_ref->ptr[slot];
5723 /* initialize prevgre */
5727 /* search external hash chain for the entry */
5731 /* global object found, decrement the reference count */
5735 /* if reference count is 0, remove the entry */
5737 if (gre->refs == 0) {
5738 /* special handling if it's the first in the chain */
5740 if (prevgre == NULL)
5741 hashtable_global_ref->ptr[slot] = gre->hashlink;
5743 prevgre->hashlink = gre->hashlink;
5745 FREE(gre, hashtable_global_ref_entry);
5748 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5753 prevgre = gre; /* save current pointer for removal */
5754 gre = gre->hashlink; /* next element in external chain */
5757 log_println("JNI-DeleteGlobalRef: global reference not found");
5759 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5763 /* ExceptionCheck **************************************************************
5765 Returns JNI_TRUE when there is a pending exception; otherwise,
5768 *******************************************************************************/
5770 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
5772 java_objectheader *o;
5774 STATISTICS(jniinvokation());
5776 o = exceptions_get_exception();
5778 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
5782 /* New JNI 1.4 functions ******************************************************/
5784 /* NewDirectByteBuffer *********************************************************
5786 Allocates and returns a direct java.nio.ByteBuffer referring to the
5787 block of memory starting at the memory address address and
5788 extending capacity bytes.
5790 *******************************************************************************/
5792 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
5794 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
5795 java_objectheader *nbuf;
5797 # if SIZEOF_VOID_P == 8
5798 gnu_classpath_Pointer64 *paddress;
5800 gnu_classpath_Pointer32 *paddress;
5803 STATISTICS(jniinvokation());
5805 /* alocate a gnu.classpath.Pointer{32,64} object */
5807 # if SIZEOF_VOID_P == 8
5808 if (!(paddress = (gnu_classpath_Pointer64 *)
5809 builtin_new(class_gnu_classpath_Pointer64)))
5811 if (!(paddress = (gnu_classpath_Pointer32 *)
5812 builtin_new(class_gnu_classpath_Pointer32)))
5816 /* fill gnu.classpath.Pointer{32,64} with address */
5818 paddress->data = (ptrint) address;
5820 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
5822 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
5823 (jmethodID) dbbirw_init, NULL, paddress,
5824 (jint) capacity, (jint) capacity, (jint) 0);
5826 /* add local reference and return the value */
5828 return _Jv_JNI_NewLocalRef(env, nbuf);
5830 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
5832 /* keep compiler happy */
5839 /* GetDirectBufferAddress ******************************************************
5841 Fetches and returns the starting address of the memory region
5842 referenced by the given direct java.nio.Buffer.
5844 *******************************************************************************/
5846 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
5848 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
5849 java_nio_DirectByteBufferImpl *nbuf;
5850 # if SIZEOF_VOID_P == 8
5851 gnu_classpath_Pointer64 *address;
5853 gnu_classpath_Pointer32 *address;
5856 STATISTICS(jniinvokation());
5858 if (!builtin_instanceof(buf, class_java_nio_Buffer))
5861 nbuf = (java_nio_DirectByteBufferImpl *) buf;
5863 # if SIZEOF_VOID_P == 8
5864 address = (gnu_classpath_Pointer64 *) nbuf->address;
5866 address = (gnu_classpath_Pointer32 *) nbuf->address;
5869 if (address == NULL)
5872 return (void *) address->data;
5874 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
5876 /* keep compiler happy */
5883 /* GetDirectBufferCapacity *****************************************************
5885 Fetches and returns the capacity in bytes of the memory region
5886 referenced by the given direct java.nio.Buffer.
5888 *******************************************************************************/
5890 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
5892 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
5893 java_objectheader *o;
5894 java_nio_Buffer *nbuf;
5896 STATISTICS(jniinvokation());
5898 o = (java_objectheader *) buf;
5900 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
5903 nbuf = (java_nio_Buffer *) o;
5905 return (jlong) nbuf->cap;
5907 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
5909 /* keep compiler happy */
5916 /* DestroyJavaVM ***************************************************************
5918 Unloads a Java VM and reclaims its resources. Only the main thread
5919 can unload the VM. The system waits until the main thread is only
5920 remaining user thread before it destroys the VM.
5922 *******************************************************************************/
5924 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
5928 STATISTICS(jniinvokation());
5930 status = vm_destroy(vm);
5936 /* AttachCurrentThread *********************************************************
5938 Attaches the current thread to a Java VM. Returns a JNI interface
5939 pointer in the JNIEnv argument.
5941 Trying to attach a thread that is already attached is a no-op.
5943 A native thread cannot be attached simultaneously to two Java VMs.
5945 When a thread is attached to the VM, the context class loader is
5946 the bootstrap loader.
5948 *******************************************************************************/
5950 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
5952 JavaVMAttachArgs *vm_aargs;
5954 #if defined(ENABLE_THREADS)
5955 if (threads_get_current_threadobject() == NULL) {
5956 vm_aargs = (JavaVMAttachArgs *) thr_args;
5958 if (vm_aargs != NULL) {
5959 if ((vm_aargs->version != JNI_VERSION_1_2) &&
5960 (vm_aargs->version != JNI_VERSION_1_4))
5961 return JNI_EVERSION;
5964 if (!threads_attach_current_thread(vm_aargs, false))
5967 if (!jni_init_localref_table())
5978 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
5980 STATISTICS(jniinvokation());
5982 return jni_attach_current_thread(p_env, thr_args, false);
5986 /* DetachCurrentThread *********************************************************
5988 Detaches the current thread from a Java VM. All Java monitors held
5989 by this thread are released. All Java threads waiting for this
5990 thread to die are notified.
5992 In JDK 1.1, the main thread cannot be detached from the VM. It must
5993 call DestroyJavaVM to unload the entire VM.
5995 In the JDK, the main thread can be detached from the VM.
5997 The main thread, which is the thread that created the Java VM,
5998 cannot be detached from the VM. Instead, the main thread must call
5999 JNI_DestroyJavaVM() to unload the entire VM.
6001 *******************************************************************************/
6003 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
6005 #if defined(ENABLE_THREADS)
6006 threadobject *thread;
6008 STATISTICS(jniinvokation());
6010 thread = threads_get_current_threadobject();
6015 if (!threads_detach_thread(thread))
6023 /* GetEnv **********************************************************************
6025 If the current thread is not attached to the VM, sets *env to NULL,
6026 and returns JNI_EDETACHED. If the specified version is not
6027 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
6028 sets *env to the appropriate interface, and returns JNI_OK.
6030 *******************************************************************************/
6032 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
6034 STATISTICS(jniinvokation());
6036 #if defined(ENABLE_THREADS)
6037 if (threads_get_current_threadobject() == NULL) {
6040 return JNI_EDETACHED;
6044 /* check the JNI version */
6047 case JNI_VERSION_1_1:
6048 case JNI_VERSION_1_2:
6049 case JNI_VERSION_1_4:
6057 #if defined(ENABLE_JVMTI)
6058 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
6059 == JVMTI_VERSION_INTERFACE_JVMTI) {
6061 *env = (void *) jvmti_new_environment();
6070 return JNI_EVERSION;
6074 /* AttachCurrentThreadAsDaemon *************************************************
6076 Same semantics as AttachCurrentThread, but the newly-created
6077 java.lang.Thread instance is a daemon.
6079 If the thread has already been attached via either
6080 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
6081 simply sets the value pointed to by penv to the JNIEnv of the
6082 current thread. In this case neither AttachCurrentThread nor this
6083 routine have any effect on the daemon status of the thread.
6085 *******************************************************************************/
6087 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
6089 STATISTICS(jniinvokation());
6091 return jni_attach_current_thread(penv, args, true);
6095 /* JNI invocation table *******************************************************/
6097 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
6102 _Jv_JNI_DestroyJavaVM,
6103 _Jv_JNI_AttachCurrentThread,
6104 _Jv_JNI_DetachCurrentThread,
6106 _Jv_JNI_AttachCurrentThreadAsDaemon
6110 /* JNI function table *********************************************************/
6112 struct JNINativeInterface_ _Jv_JNINativeInterface = {
6119 _Jv_JNI_DefineClass,
6121 _Jv_JNI_FromReflectedMethod,
6122 _Jv_JNI_FromReflectedField,
6123 _Jv_JNI_ToReflectedMethod,
6124 _Jv_JNI_GetSuperclass,
6125 _Jv_JNI_IsAssignableFrom,
6126 _Jv_JNI_ToReflectedField,
6130 _Jv_JNI_ExceptionOccurred,
6131 _Jv_JNI_ExceptionDescribe,
6132 _Jv_JNI_ExceptionClear,
6134 _Jv_JNI_PushLocalFrame,
6135 _Jv_JNI_PopLocalFrame,
6137 _Jv_JNI_NewGlobalRef,
6138 _Jv_JNI_DeleteGlobalRef,
6139 _Jv_JNI_DeleteLocalRef,
6140 _Jv_JNI_IsSameObject,
6141 _Jv_JNI_NewLocalRef,
6142 _Jv_JNI_EnsureLocalCapacity,
6144 _Jv_JNI_AllocObject,
6149 _Jv_JNI_GetObjectClass,
6150 _Jv_JNI_IsInstanceOf,
6152 _Jv_JNI_GetMethodID,
6154 _Jv_JNI_CallObjectMethod,
6155 _Jv_JNI_CallObjectMethodV,
6156 _Jv_JNI_CallObjectMethodA,
6157 _Jv_JNI_CallBooleanMethod,
6158 _Jv_JNI_CallBooleanMethodV,
6159 _Jv_JNI_CallBooleanMethodA,
6160 _Jv_JNI_CallByteMethod,
6161 _Jv_JNI_CallByteMethodV,
6162 _Jv_JNI_CallByteMethodA,
6163 _Jv_JNI_CallCharMethod,
6164 _Jv_JNI_CallCharMethodV,
6165 _Jv_JNI_CallCharMethodA,
6166 _Jv_JNI_CallShortMethod,
6167 _Jv_JNI_CallShortMethodV,
6168 _Jv_JNI_CallShortMethodA,
6169 _Jv_JNI_CallIntMethod,
6170 _Jv_JNI_CallIntMethodV,
6171 _Jv_JNI_CallIntMethodA,
6172 _Jv_JNI_CallLongMethod,
6173 _Jv_JNI_CallLongMethodV,
6174 _Jv_JNI_CallLongMethodA,
6175 _Jv_JNI_CallFloatMethod,
6176 _Jv_JNI_CallFloatMethodV,
6177 _Jv_JNI_CallFloatMethodA,
6178 _Jv_JNI_CallDoubleMethod,
6179 _Jv_JNI_CallDoubleMethodV,
6180 _Jv_JNI_CallDoubleMethodA,
6181 _Jv_JNI_CallVoidMethod,
6182 _Jv_JNI_CallVoidMethodV,
6183 _Jv_JNI_CallVoidMethodA,
6185 _Jv_JNI_CallNonvirtualObjectMethod,
6186 _Jv_JNI_CallNonvirtualObjectMethodV,
6187 _Jv_JNI_CallNonvirtualObjectMethodA,
6188 _Jv_JNI_CallNonvirtualBooleanMethod,
6189 _Jv_JNI_CallNonvirtualBooleanMethodV,
6190 _Jv_JNI_CallNonvirtualBooleanMethodA,
6191 _Jv_JNI_CallNonvirtualByteMethod,
6192 _Jv_JNI_CallNonvirtualByteMethodV,
6193 _Jv_JNI_CallNonvirtualByteMethodA,
6194 _Jv_JNI_CallNonvirtualCharMethod,
6195 _Jv_JNI_CallNonvirtualCharMethodV,
6196 _Jv_JNI_CallNonvirtualCharMethodA,
6197 _Jv_JNI_CallNonvirtualShortMethod,
6198 _Jv_JNI_CallNonvirtualShortMethodV,
6199 _Jv_JNI_CallNonvirtualShortMethodA,
6200 _Jv_JNI_CallNonvirtualIntMethod,
6201 _Jv_JNI_CallNonvirtualIntMethodV,
6202 _Jv_JNI_CallNonvirtualIntMethodA,
6203 _Jv_JNI_CallNonvirtualLongMethod,
6204 _Jv_JNI_CallNonvirtualLongMethodV,
6205 _Jv_JNI_CallNonvirtualLongMethodA,
6206 _Jv_JNI_CallNonvirtualFloatMethod,
6207 _Jv_JNI_CallNonvirtualFloatMethodV,
6208 _Jv_JNI_CallNonvirtualFloatMethodA,
6209 _Jv_JNI_CallNonvirtualDoubleMethod,
6210 _Jv_JNI_CallNonvirtualDoubleMethodV,
6211 _Jv_JNI_CallNonvirtualDoubleMethodA,
6212 _Jv_JNI_CallNonvirtualVoidMethod,
6213 _Jv_JNI_CallNonvirtualVoidMethodV,
6214 _Jv_JNI_CallNonvirtualVoidMethodA,
6218 _Jv_JNI_GetObjectField,
6219 _Jv_JNI_GetBooleanField,
6220 _Jv_JNI_GetByteField,
6221 _Jv_JNI_GetCharField,
6222 _Jv_JNI_GetShortField,
6223 _Jv_JNI_GetIntField,
6224 _Jv_JNI_GetLongField,
6225 _Jv_JNI_GetFloatField,
6226 _Jv_JNI_GetDoubleField,
6227 _Jv_JNI_SetObjectField,
6228 _Jv_JNI_SetBooleanField,
6229 _Jv_JNI_SetByteField,
6230 _Jv_JNI_SetCharField,
6231 _Jv_JNI_SetShortField,
6232 _Jv_JNI_SetIntField,
6233 _Jv_JNI_SetLongField,
6234 _Jv_JNI_SetFloatField,
6235 _Jv_JNI_SetDoubleField,
6237 _Jv_JNI_GetStaticMethodID,
6239 _Jv_JNI_CallStaticObjectMethod,
6240 _Jv_JNI_CallStaticObjectMethodV,
6241 _Jv_JNI_CallStaticObjectMethodA,
6242 _Jv_JNI_CallStaticBooleanMethod,
6243 _Jv_JNI_CallStaticBooleanMethodV,
6244 _Jv_JNI_CallStaticBooleanMethodA,
6245 _Jv_JNI_CallStaticByteMethod,
6246 _Jv_JNI_CallStaticByteMethodV,
6247 _Jv_JNI_CallStaticByteMethodA,
6248 _Jv_JNI_CallStaticCharMethod,
6249 _Jv_JNI_CallStaticCharMethodV,
6250 _Jv_JNI_CallStaticCharMethodA,
6251 _Jv_JNI_CallStaticShortMethod,
6252 _Jv_JNI_CallStaticShortMethodV,
6253 _Jv_JNI_CallStaticShortMethodA,
6254 _Jv_JNI_CallStaticIntMethod,
6255 _Jv_JNI_CallStaticIntMethodV,
6256 _Jv_JNI_CallStaticIntMethodA,
6257 _Jv_JNI_CallStaticLongMethod,
6258 _Jv_JNI_CallStaticLongMethodV,
6259 _Jv_JNI_CallStaticLongMethodA,
6260 _Jv_JNI_CallStaticFloatMethod,
6261 _Jv_JNI_CallStaticFloatMethodV,
6262 _Jv_JNI_CallStaticFloatMethodA,
6263 _Jv_JNI_CallStaticDoubleMethod,
6264 _Jv_JNI_CallStaticDoubleMethodV,
6265 _Jv_JNI_CallStaticDoubleMethodA,
6266 _Jv_JNI_CallStaticVoidMethod,
6267 _Jv_JNI_CallStaticVoidMethodV,
6268 _Jv_JNI_CallStaticVoidMethodA,
6270 _Jv_JNI_GetStaticFieldID,
6272 _Jv_JNI_GetStaticObjectField,
6273 _Jv_JNI_GetStaticBooleanField,
6274 _Jv_JNI_GetStaticByteField,
6275 _Jv_JNI_GetStaticCharField,
6276 _Jv_JNI_GetStaticShortField,
6277 _Jv_JNI_GetStaticIntField,
6278 _Jv_JNI_GetStaticLongField,
6279 _Jv_JNI_GetStaticFloatField,
6280 _Jv_JNI_GetStaticDoubleField,
6281 _Jv_JNI_SetStaticObjectField,
6282 _Jv_JNI_SetStaticBooleanField,
6283 _Jv_JNI_SetStaticByteField,
6284 _Jv_JNI_SetStaticCharField,
6285 _Jv_JNI_SetStaticShortField,
6286 _Jv_JNI_SetStaticIntField,
6287 _Jv_JNI_SetStaticLongField,
6288 _Jv_JNI_SetStaticFloatField,
6289 _Jv_JNI_SetStaticDoubleField,
6292 _Jv_JNI_GetStringLength,
6293 _Jv_JNI_GetStringChars,
6294 _Jv_JNI_ReleaseStringChars,
6296 _Jv_JNI_NewStringUTF,
6297 _Jv_JNI_GetStringUTFLength,
6298 _Jv_JNI_GetStringUTFChars,
6299 _Jv_JNI_ReleaseStringUTFChars,
6301 _Jv_JNI_GetArrayLength,
6303 _Jv_JNI_NewObjectArray,
6304 _Jv_JNI_GetObjectArrayElement,
6305 _Jv_JNI_SetObjectArrayElement,
6307 _Jv_JNI_NewBooleanArray,
6308 _Jv_JNI_NewByteArray,
6309 _Jv_JNI_NewCharArray,
6310 _Jv_JNI_NewShortArray,
6311 _Jv_JNI_NewIntArray,
6312 _Jv_JNI_NewLongArray,
6313 _Jv_JNI_NewFloatArray,
6314 _Jv_JNI_NewDoubleArray,
6316 _Jv_JNI_GetBooleanArrayElements,
6317 _Jv_JNI_GetByteArrayElements,
6318 _Jv_JNI_GetCharArrayElements,
6319 _Jv_JNI_GetShortArrayElements,
6320 _Jv_JNI_GetIntArrayElements,
6321 _Jv_JNI_GetLongArrayElements,
6322 _Jv_JNI_GetFloatArrayElements,
6323 _Jv_JNI_GetDoubleArrayElements,
6325 _Jv_JNI_ReleaseBooleanArrayElements,
6326 _Jv_JNI_ReleaseByteArrayElements,
6327 _Jv_JNI_ReleaseCharArrayElements,
6328 _Jv_JNI_ReleaseShortArrayElements,
6329 _Jv_JNI_ReleaseIntArrayElements,
6330 _Jv_JNI_ReleaseLongArrayElements,
6331 _Jv_JNI_ReleaseFloatArrayElements,
6332 _Jv_JNI_ReleaseDoubleArrayElements,
6334 _Jv_JNI_GetBooleanArrayRegion,
6335 _Jv_JNI_GetByteArrayRegion,
6336 _Jv_JNI_GetCharArrayRegion,
6337 _Jv_JNI_GetShortArrayRegion,
6338 _Jv_JNI_GetIntArrayRegion,
6339 _Jv_JNI_GetLongArrayRegion,
6340 _Jv_JNI_GetFloatArrayRegion,
6341 _Jv_JNI_GetDoubleArrayRegion,
6342 _Jv_JNI_SetBooleanArrayRegion,
6343 _Jv_JNI_SetByteArrayRegion,
6344 _Jv_JNI_SetCharArrayRegion,
6345 _Jv_JNI_SetShortArrayRegion,
6346 _Jv_JNI_SetIntArrayRegion,
6347 _Jv_JNI_SetLongArrayRegion,
6348 _Jv_JNI_SetFloatArrayRegion,
6349 _Jv_JNI_SetDoubleArrayRegion,
6351 _Jv_JNI_RegisterNatives,
6352 _Jv_JNI_UnregisterNatives,
6354 _Jv_JNI_MonitorEnter,
6355 _Jv_JNI_MonitorExit,
6359 /* new JNI 1.2 functions */
6361 _Jv_JNI_GetStringRegion,
6362 _Jv_JNI_GetStringUTFRegion,
6364 _Jv_JNI_GetPrimitiveArrayCritical,
6365 _Jv_JNI_ReleasePrimitiveArrayCritical,
6367 _Jv_JNI_GetStringCritical,
6368 _Jv_JNI_ReleaseStringCritical,
6370 _Jv_JNI_NewWeakGlobalRef,
6371 _Jv_JNI_DeleteWeakGlobalRef,
6373 _Jv_JNI_ExceptionCheck,
6375 /* new JNI 1.4 functions */
6377 _Jv_JNI_NewDirectByteBuffer,
6378 _Jv_JNI_GetDirectBufferAddress,
6379 _Jv_JNI_GetDirectBufferCapacity
6383 /* Invocation API Functions ***************************************************/
6385 /* JNI_GetDefaultJavaVMInitArgs ************************************************
6387 Returns a default configuration for the Java VM.
6389 *******************************************************************************/
6391 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
6393 JavaVMInitArgs *_vm_args;
6395 _vm_args = (JavaVMInitArgs *) vm_args;
6397 /* GNU classpath currently supports JNI 1.2 */
6399 switch (_vm_args->version) {
6400 case JNI_VERSION_1_1:
6401 _vm_args->version = JNI_VERSION_1_1;
6404 case JNI_VERSION_1_2:
6405 case JNI_VERSION_1_4:
6406 _vm_args->ignoreUnrecognized = JNI_FALSE;
6407 _vm_args->options = NULL;
6408 _vm_args->nOptions = 0;
6419 /* JNI_GetCreatedJavaVMs *******************************************************
6421 Returns all Java VMs that have been created. Pointers to VMs are written in
6422 the buffer vmBuf in the order they are created. At most bufLen number of
6423 entries will be written. The total number of created VMs is returned in
6426 *******************************************************************************/
6428 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
6430 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
6436 /* JNI_CreateJavaVM ************************************************************
6438 Loads and initializes a Java VM. The current thread becomes the main thread.
6439 Sets the env argument to the JNI interface pointer of the main thread.
6441 *******************************************************************************/
6443 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
6445 /* actually create the JVM */
6447 if (!vm_createjvm(p_vm, p_env, vm_args))
6455 * These are local overrides for various environment variables in Emacs.
6456 * Please do not remove this and leave it at the end of the file, where
6457 * Emacs will automagically detect them.
6458 * ---------------------------------------------------------------------
6461 * indent-tabs-mode: t
6465 * vim:noexpandtab:sw=4:ts=4: