1 /* src/native/jni.c - implementation of the Java Native Interface functions
3 Copyright (C) 1996-2005, 2006 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 Contact: cacao@cacaojvm.org
27 Authors: Rainhard Grafl
30 Changes: Joseph Wenninger
35 $Id: jni.c 4566 2006-03-07 10:36:42Z twisti $
48 #include "mm/memory.h"
49 #include "native/jni.h"
50 #include "native/native.h"
52 #include "native/include/gnu_classpath_Pointer.h"
54 #if SIZEOF_VOID_P == 8
55 # include "native/include/gnu_classpath_Pointer64.h"
57 # include "native/include/gnu_classpath_Pointer32.h"
60 #include "native/include/java_lang_Object.h"
61 #include "native/include/java_lang_Byte.h"
62 #include "native/include/java_lang_Character.h"
63 #include "native/include/java_lang_Short.h"
64 #include "native/include/java_lang_Integer.h"
65 #include "native/include/java_lang_Boolean.h"
66 #include "native/include/java_lang_Long.h"
67 #include "native/include/java_lang_Float.h"
68 #include "native/include/java_lang_Double.h"
69 #include "native/include/java_lang_Throwable.h"
70 #include "native/include/java_lang_reflect_Method.h"
71 #include "native/include/java_lang_reflect_Constructor.h"
72 #include "native/include/java_lang_reflect_Field.h"
74 #include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
75 #include "native/include/java_lang_VMClass.h"
76 #include "native/include/java_lang_VMClassLoader.h"
77 #include "native/include/java_nio_Buffer.h"
78 #include "native/include/java_nio_DirectByteBufferImpl.h"
80 #if defined(ENABLE_JVMTI)
81 # include "native/jvmti/jvmti.h"
84 #if defined(USE_THREADS)
85 # if defined(NATIVE_THREADS)
86 # include "threads/native/threads.h"
88 # include "threads/green/threads.h"
92 #include "toolbox/logging.h"
93 #include "vm/builtin.h"
94 #include "vm/exceptions.h"
95 #include "vm/global.h"
96 #include "vm/initialize.h"
97 #include "vm/loader.h"
98 #include "vm/options.h"
99 #include "vm/resolve.h"
100 #include "vm/statistics.h"
101 #include "vm/stringlocal.h"
102 #include "vm/jit/asmpart.h"
103 #include "vm/jit/jit.h"
104 #include "vm/statistics.h"
108 /* global variables ***********************************************************/
110 /* global reference table *****************************************************/
112 static java_objectheader **global_ref_table;
114 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
115 static classinfo *ihmclass = NULL;
116 static methodinfo *putmid = NULL;
117 static methodinfo *getmid = NULL;
118 static methodinfo *removemid = NULL;
121 /* direct buffer stuff ********************************************************/
123 static classinfo *class_java_nio_Buffer;
124 static classinfo *class_java_nio_DirectByteBufferImpl;
125 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
126 #if SIZEOF_VOID_P == 8
127 static classinfo *class_gnu_classpath_Pointer64;
129 static classinfo *class_gnu_classpath_Pointer32;
132 static methodinfo *dbbirw_init;
135 /* local reference table ******************************************************/
137 #if !defined(USE_THREADS)
138 localref_table *_no_threads_localref_table;
142 /* accessing instance fields macros *******************************************/
144 #define SET_FIELD(o,type,f,value) \
145 *((type *) ((ptrint) (o) + (ptrint) ((fieldinfo *) (f))->offset)) = (type) (value)
147 #define GET_FIELD(o,type,f) \
148 *((type *) ((ptrint) (o) + (ptrint) ((fieldinfo *) (f))->offset))
151 /* some forward declarations **************************************************/
153 jobject NewLocalRef(JNIEnv *env, jobject ref);
156 /* jni_init ********************************************************************
158 Initialize the JNI subsystem.
160 *******************************************************************************/
164 /* initalize global reference table */
167 load_class_bootstrap(utf_new_char("java/util/IdentityHashMap"))))
170 global_ref_table = GCNEW(jobject);
172 if (!(*global_ref_table = native_new_and_init(ihmclass)))
175 if (!(getmid = class_resolvemethod(ihmclass, utf_get,
176 utf_java_lang_Object__java_lang_Object)))
179 if (!(putmid = class_resolvemethod(ihmclass, utf_put,
180 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))))
184 class_resolvemethod(ihmclass, utf_remove,
185 utf_java_lang_Object__java_lang_Object)))
189 /* direct buffer stuff */
191 if (!(class_java_nio_Buffer =
192 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
193 !link_class(class_java_nio_Buffer))
196 if (!(class_java_nio_DirectByteBufferImpl =
197 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
198 !link_class(class_java_nio_DirectByteBufferImpl))
201 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
202 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
203 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
207 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
209 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
212 #if SIZEOF_VOID_P == 8
213 if (!(class_gnu_classpath_Pointer64 =
214 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
215 !link_class(class_gnu_classpath_Pointer64))
218 if (!(class_gnu_classpath_Pointer32 =
219 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
220 !link_class(class_gnu_classpath_Pointer32))
228 /* _Jv_jni_vmargs_from_objectarray *********************************************
232 *******************************************************************************/
234 static bool _Jv_jni_vmargs_from_objectarray(java_objectheader *o,
237 java_objectarray *params)
239 java_objectheader *param;
241 typedesc *paramtypes;
246 paramcount = descr->paramcount;
247 paramtypes = descr->paramtypes;
249 /* if method is non-static fill first block and skip `this' pointer */
255 vmargs[0].type = TYPE_ADR;
256 vmargs[0].data = (u8) (ptrint) o;
263 for (j = 0; j < paramcount; i++, j++, paramtypes++) {
264 switch (paramtypes->type) {
265 /* primitive types */
270 param = params->data[j];
275 /* internally used data type */
276 vmargs[i].type = paramtypes->type;
278 /* convert the value according to its declared type */
280 c = param->vftbl->class;
282 switch (paramtypes->decltype) {
283 case PRIMITIVETYPE_BOOLEAN:
284 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
285 vmargs[i].data = (s8) ((java_lang_Boolean *) param)->value;
290 case PRIMITIVETYPE_BYTE:
291 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
292 vmargs[i].data = (s8) ((java_lang_Byte *) param)->value;
297 case PRIMITIVETYPE_CHAR:
298 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
299 vmargs[i].data = (s8) ((java_lang_Character *) param)->value;
304 case PRIMITIVETYPE_SHORT:
305 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
306 vmargs[i].data = (s8) ((java_lang_Short *) param)->value;
307 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
308 vmargs[i].data = (s8) ((java_lang_Byte *) param)->value;
313 case PRIMITIVETYPE_INT:
314 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
315 vmargs[i].data = (s8) ((java_lang_Integer *) param)->value;
316 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
317 vmargs[i].data = (s8) ((java_lang_Short *) param)->value;
318 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
319 vmargs[i].data = (s8) ((java_lang_Byte *) param)->value;
324 case PRIMITIVETYPE_LONG:
325 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
326 vmargs[i].data = (s8) ((java_lang_Long *) param)->value;
327 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
328 vmargs[i].data = (s8) ((java_lang_Integer *) param)->value;
329 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
330 vmargs[i].data = (s8) ((java_lang_Short *) param)->value;
331 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
332 vmargs[i].data = (s8) ((java_lang_Byte *) param)->value;
337 case PRIMITIVETYPE_FLOAT:
338 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
339 *((jfloat *) (&vmargs[i].data)) = (jfloat) ((java_lang_Float *) param)->value;
344 case PRIMITIVETYPE_DOUBLE:
345 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
346 *((jdouble *) (&vmargs[i].data)) = (jdouble) ((java_lang_Double *) param)->value;
347 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
348 *((jfloat *) (&vmargs[i].data)) = (jfloat) ((java_lang_Float *) param)->value;
359 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
362 if (params->data[j] != 0) {
363 if (paramtypes->arraydim > 0) {
364 if (!builtin_arrayinstanceof(params->data[j], c))
368 if (!builtin_instanceof(params->data[j], c))
372 vmargs[i].type = TYPE_ADR;
373 vmargs[i].data = (u8) (ptrint) params->data[j];
382 /* *rettype = descr->returntype.decltype; */
387 exceptions_throw_illegalargumentexception();
392 /* _Jv_jni_CallObjectMethod ****************************************************
394 Internal function to call Java Object methods.
396 *******************************************************************************/
398 static java_objectheader *_Jv_jni_CallObjectMethod(java_objectheader *o,
400 methodinfo *m, va_list ap)
403 java_objectheader *ro;
405 STATISTICS(jniinvokation());
408 exceptions_throw_nullpointerexception();
412 /* Class initialization is done by the JIT compiler. This is ok
413 since a static method always belongs to the declaring class. */
415 if (m->flags & ACC_STATIC) {
416 /* For static methods we reset the object. */
421 /* for convenience */
426 /* For instance methods we make a virtual function table lookup. */
428 resm = method_vftbl_lookup(vftbl, m);
431 STATISTICS(jnicallXmethodnvokation());
433 ro = vm_call_method_valist(resm, o, ap);
439 /* _Jv_jni_CallObjectMethodA ***************************************************
441 Internal function to call Java Object methods.
443 *******************************************************************************/
445 static java_objectheader *_Jv_jni_CallObjectMethodA(java_objectheader *o,
447 methodinfo *m, jvalue *args)
450 java_objectheader *ro;
452 STATISTICS(jniinvokation());
455 exceptions_throw_nullpointerexception();
459 /* Class initialization is done by the JIT compiler. This is ok
460 since a static method always belongs to the declaring class. */
462 if (m->flags & ACC_STATIC) {
463 /* For static methods we reset the object. */
468 /* for convenience */
473 /* For instance methods we make a virtual function table lookup. */
475 resm = method_vftbl_lookup(vftbl, m);
478 STATISTICS(jnicallXmethodnvokation());
480 ro = vm_call_method_jvalue(resm, o, args);
486 /* _Jv_jni_CallIntMethod *******************************************************
488 Internal function to call Java integer class methods (boolean,
489 byte, char, short, int).
491 *******************************************************************************/
493 static jint _Jv_jni_CallIntMethod(java_objectheader *o, vftbl_t *vftbl,
494 methodinfo *m, va_list ap)
499 STATISTICS(jniinvokation());
502 exceptions_throw_nullpointerexception();
506 /* Class initialization is done by the JIT compiler. This is ok
507 since a static method always belongs to the declaring class. */
509 if (m->flags & ACC_STATIC) {
510 /* For static methods we reset the object. */
515 /* for convenience */
520 /* For instance methods we make a virtual function table lookup. */
522 resm = method_vftbl_lookup(vftbl, m);
525 STATISTICS(jnicallXmethodnvokation());
527 i = vm_call_method_int_valist(resm, o, ap);
533 /* _Jv_jni_CallLongMethod ******************************************************
535 Internal function to call Java long methods.
537 *******************************************************************************/
539 static jlong _Jv_jni_CallLongMethod(java_objectheader *o, vftbl_t *vftbl,
540 methodinfo *m, va_list ap)
545 STATISTICS(jniinvokation());
548 exceptions_throw_nullpointerexception();
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 l = vm_call_method_long_valist(resm, o, ap);
579 /* _Jv_jni_CallFloatMethod *****************************************************
581 Internal function to call Java float methods.
583 *******************************************************************************/
585 static jfloat _Jv_jni_CallFloatMethod(java_objectheader *o, vftbl_t *vftbl,
586 methodinfo *m, va_list ap)
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_valist(resm, o, ap);
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_CallVoidMethod ******************************************************
657 Internal function to call Java void methods.
659 *******************************************************************************/
661 static void _Jv_jni_CallVoidMethod(java_objectheader *o, vftbl_t *vftbl,
662 methodinfo *m, va_list ap)
667 exceptions_throw_nullpointerexception();
671 /* Class initialization is done by the JIT compiler. This is ok
672 since a static method always belongs to the declaring class. */
674 if (m->flags & ACC_STATIC) {
675 /* For static methods we reset the object. */
680 /* for convenience */
685 /* For instance methods we make a virtual function table lookup. */
687 resm = method_vftbl_lookup(vftbl, m);
690 STATISTICS(jnicallXmethodnvokation());
692 (void) vm_call_method_valist(resm, o, ap);
696 /* _Jv_jni_CallVoidMethodA *****************************************************
698 Internal function to call Java void methods.
700 *******************************************************************************/
702 static void _Jv_jni_CallVoidMethodA(java_objectheader *o, vftbl_t *vftbl,
703 methodinfo *m, jvalue *args)
708 exceptions_throw_nullpointerexception();
712 /* Class initialization is done by the JIT compiler. This is ok
713 since a static method always belongs to the declaring class. */
715 if (m->flags & ACC_STATIC) {
716 /* For static methods we reset the object. */
721 /* for convenience */
726 /* For instance methods we make a virtual function table lookup. */
728 resm = method_vftbl_lookup(vftbl, m);
731 STATISTICS(jnicallXmethodnvokation());
733 (void) vm_call_method_jvalue(resm, o, args);
737 /* _Jv_jni_invokeNative ********************************************************
739 Invoke a method on the given object with the given arguments.
741 For instance methods OBJ must be != NULL and the method is looked up
742 in the vftbl of the object.
744 For static methods, OBJ is ignored.
746 *******************************************************************************/
748 java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
749 java_objectarray *params)
753 java_objectheader *ro;
758 exceptions_throw_nullpointerexception();
762 argcount = m->parseddesc->paramcount;
763 paramcount = argcount;
765 /* if method is non-static, remove the `this' pointer */
767 if (!(m->flags & ACC_STATIC))
770 /* For instance methods the object has to be an instance of the
771 class the method belongs to. For static methods the obj
772 parameter is ignored. */
774 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
776 new_exception_message(string_java_lang_IllegalArgumentException,
777 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
781 /* check if we got the right number of arguments */
783 if (((params == NULL) && (paramcount != 0)) ||
784 (params && (params->header.size != paramcount)))
787 new_exception(string_java_lang_IllegalArgumentException);
791 /* for instance methods we need an object */
793 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
795 new_exception_message(string_java_lang_NullPointerException,
796 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
800 /* for static methods, zero object to make subsequent code simpler */
801 if (m->flags & ACC_STATIC)
805 /* for instance methods we must do a vftbl lookup */
806 resm = method_vftbl_lookup(o->vftbl, m);
809 /* for static methods, just for convenience */
813 vmargs = MNEW(vm_arg, argcount);
815 if (!_Jv_jni_vmargs_from_objectarray(o, resm->parseddesc, vmargs, params))
818 switch (resm->parseddesc->returntype.decltype) {
820 (void) vm_call_method_vmarg(resm, argcount, vmargs);
825 case PRIMITIVETYPE_BOOLEAN: {
827 java_lang_Boolean *bo;
829 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
831 ro = builtin_new(class_java_lang_Boolean);
833 /* setting the value of the object direct */
835 bo = (java_lang_Boolean *) ro;
840 case PRIMITIVETYPE_BYTE: {
844 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
846 ro = builtin_new(class_java_lang_Byte);
848 /* setting the value of the object direct */
850 bo = (java_lang_Byte *) ro;
855 case PRIMITIVETYPE_CHAR: {
857 java_lang_Character *co;
859 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
861 ro = builtin_new(class_java_lang_Character);
863 /* setting the value of the object direct */
865 co = (java_lang_Character *) ro;
870 case PRIMITIVETYPE_SHORT: {
874 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
876 ro = builtin_new(class_java_lang_Short);
878 /* setting the value of the object direct */
880 so = (java_lang_Short *) ro;
885 case PRIMITIVETYPE_INT: {
887 java_lang_Integer *io;
889 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
891 ro = builtin_new(class_java_lang_Integer);
893 /* setting the value of the object direct */
895 io = (java_lang_Integer *) ro;
900 case PRIMITIVETYPE_LONG: {
904 l = vm_call_method_long_vmarg(resm, argcount, vmargs);
906 ro = builtin_new(class_java_lang_Long);
908 /* setting the value of the object direct */
910 lo = (java_lang_Long *) ro;
915 case PRIMITIVETYPE_FLOAT: {
919 f = vm_call_method_float_vmarg(resm, argcount, vmargs);
921 ro = builtin_new(class_java_lang_Float);
923 /* setting the value of the object direct */
925 fo = (java_lang_Float *) ro;
930 case PRIMITIVETYPE_DOUBLE: {
932 java_lang_Double *_do;
934 d = vm_call_method_double_vmarg(resm, argcount, vmargs);
936 ro = builtin_new(class_java_lang_Double);
938 /* setting the value of the object direct */
940 _do = (java_lang_Double *) ro;
946 ro = vm_call_method_vmarg(resm, argcount, vmargs);
950 /* if this happens the exception has already been set by
951 fill_callblock_from_objectarray */
953 MFREE(vmargs, vm_arg, argcount);
958 MFREE(vmargs, vm_arg, argcount);
961 java_objectheader *cause;
963 cause = *exceptionptr;
965 /* clear exception pointer, we are calling JIT code again */
967 *exceptionptr = NULL;
970 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
971 (java_lang_Throwable *) cause);
978 /* GetVersion ******************************************************************
980 Returns the major version number in the higher 16 bits and the
981 minor version number in the lower 16 bits.
983 *******************************************************************************/
985 jint GetVersion(JNIEnv *env)
987 STATISTICS(jniinvokation());
989 /* we support JNI 1.4 */
991 return JNI_VERSION_1_4;
995 /* Class Operations ***********************************************************/
997 /* DefineClass *****************************************************************
999 Loads a class from a buffer of raw class data. The buffer
1000 containing the raw class data is not referenced by the VM after the
1001 DefineClass call returns, and it may be discarded if desired.
1003 *******************************************************************************/
1005 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
1006 const jbyte *buf, jsize bufLen)
1008 java_lang_ClassLoader *cl;
1009 java_lang_String *s;
1013 STATISTICS(jniinvokation());
1015 cl = (java_lang_ClassLoader *) loader;
1016 s = javastring_new_char(name);
1017 ba = (java_bytearray *) buf;
1019 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
1022 return (jclass) NewLocalRef(env, (jobject) c);
1026 /* FindClass *******************************************************************
1028 This function loads a locally-defined class. It searches the
1029 directories and zip files specified by the CLASSPATH environment
1030 variable for the class with the specified name.
1032 *******************************************************************************/
1034 jclass FindClass(JNIEnv *env, const char *name)
1040 STATISTICS(jniinvokation());
1042 u = utf_new_char_classname((char *) name);
1044 /* Check stacktrace for classloader, if one found use it,
1045 otherwise use the system classloader. */
1047 /* Quote from the JNI documentation:
1049 In the Java 2 Platform, FindClass locates the class loader
1050 associated with the current native method. If the native code
1051 belongs to a system class, no class loader will be
1052 involved. Otherwise, the proper class loader will be invoked to
1053 load and link the named class. When FindClass is called through
1054 the Invocation Interface, there is no current native method or
1055 its associated class loader. In that case, the result of
1056 ClassLoader.getBaseClassLoader is used." */
1058 #if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__)
1059 /* these JITs support stacktraces, and so does the interpreter */
1061 cc = stacktrace_getCurrentClass();
1063 # if defined(ENABLE_INTRP)
1064 /* the interpreter supports stacktraces, even if the JIT does not */
1067 cc = stacktrace_getCurrentClass();
1073 /* if no Java method was found, use the system classloader */
1076 c = load_class_from_sysloader(u);
1078 c = load_class_from_classloader(u, cc->classloader);
1086 return (jclass) NewLocalRef(env, (jobject) c);
1090 /* GetSuperclass ***************************************************************
1092 If clazz represents any class other than the class Object, then
1093 this function returns the object that represents the superclass of
1094 the class specified by clazz.
1096 *******************************************************************************/
1098 jclass GetSuperclass(JNIEnv *env, jclass sub)
1102 STATISTICS(jniinvokation());
1104 c = ((classinfo *) sub)->super.cls;
1109 return (jclass) NewLocalRef(env, (jobject) c);
1113 /* IsAssignableFrom ************************************************************
1115 Determines whether an object of sub can be safely cast to sup.
1117 *******************************************************************************/
1119 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1121 STATISTICS(jniinvokation());
1123 return Java_java_lang_VMClass_isAssignableFrom(env,
1125 (java_lang_Class *) sup,
1126 (java_lang_Class *) sub);
1130 /* Throw ***********************************************************************
1132 Causes a java.lang.Throwable object to be thrown.
1134 *******************************************************************************/
1136 jint Throw(JNIEnv *env, jthrowable obj)
1138 STATISTICS(jniinvokation());
1140 *exceptionptr = (java_objectheader *) obj;
1146 /* ThrowNew ********************************************************************
1148 Constructs an exception object from the specified class with the
1149 message specified by message and causes that exception to be
1152 *******************************************************************************/
1154 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1156 java_lang_Throwable *o;
1157 java_lang_String *s;
1159 STATISTICS(jniinvokation());
1161 s = (java_lang_String *) javastring_new_char(msg);
1163 /* instantiate exception object */
1165 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
1171 *exceptionptr = (java_objectheader *) o;
1177 /* ExceptionOccurred ***********************************************************
1179 Determines if an exception is being thrown. The exception stays
1180 being thrown until either the native code calls ExceptionClear(),
1181 or the Java code handles the exception.
1183 *******************************************************************************/
1185 jthrowable ExceptionOccurred(JNIEnv *env)
1187 java_objectheader *e;
1189 STATISTICS(jniinvokation());
1193 return NewLocalRef(env, (jthrowable) e);
1197 /* ExceptionDescribe ***********************************************************
1199 Prints an exception and a backtrace of the stack to a system
1200 error-reporting channel, such as stderr. This is a convenience
1201 routine provided for debugging.
1203 *******************************************************************************/
1205 void ExceptionDescribe(JNIEnv *env)
1207 java_objectheader *e;
1210 STATISTICS(jniinvokation());
1215 /* clear exception, because we are calling jit code again */
1217 *exceptionptr = NULL;
1219 /* get printStackTrace method from exception class */
1221 m = class_resolveclassmethod(e->vftbl->class,
1222 utf_printStackTrace,
1228 /* XXX what should we do? */
1231 /* print the stacktrace */
1233 (void) vm_call_method(m, e);
1238 /* ExceptionClear **************************************************************
1240 Clears any exception that is currently being thrown. If no
1241 exception is currently being thrown, this routine has no effect.
1243 *******************************************************************************/
1245 void ExceptionClear(JNIEnv *env)
1247 STATISTICS(jniinvokation());
1249 *exceptionptr = NULL;
1253 /* FatalError ******************************************************************
1255 Raises a fatal error and does not expect the VM to recover. This
1256 function does not return.
1258 *******************************************************************************/
1260 void FatalError(JNIEnv *env, const char *msg)
1262 STATISTICS(jniinvokation());
1264 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
1268 /* PushLocalFrame **************************************************************
1270 Creates a new local reference frame, in which at least a given
1271 number of local references can be created.
1273 *******************************************************************************/
1275 jint PushLocalFrame(JNIEnv* env, jint capacity)
1277 STATISTICS(jniinvokation());
1279 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
1286 /* PopLocalFrame ***************************************************************
1288 Pops off the current local reference frame, frees all the local
1289 references, and returns a local reference in the previous local
1290 reference frame for the given result object.
1292 *******************************************************************************/
1294 jobject PopLocalFrame(JNIEnv* env, jobject result)
1296 STATISTICS(jniinvokation());
1298 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
1302 /* add local reference and return the value */
1304 return NewLocalRef(env, NULL);
1308 /* DeleteLocalRef **************************************************************
1310 Deletes the local reference pointed to by localRef.
1312 *******************************************************************************/
1314 void DeleteLocalRef(JNIEnv *env, jobject localRef)
1316 java_objectheader *o;
1317 localref_table *lrt;
1320 STATISTICS(jniinvokation());
1322 o = (java_objectheader *) localRef;
1324 /* get local reference table (thread specific) */
1326 lrt = LOCALREFTABLE;
1328 /* remove the reference */
1330 for (i = 0; i < lrt->capacity; i++) {
1331 if (lrt->refs[i] == o) {
1332 lrt->refs[i] = NULL;
1339 /* this should not happen */
1341 /* if (opt_checkjni) */
1342 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1343 log_text("JNI-DeleteLocalRef: Bad global or local ref passed to JNI");
1347 /* IsSameObject ****************************************************************
1349 Tests whether two references refer to the same Java object.
1351 *******************************************************************************/
1353 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1355 STATISTICS(jniinvokation());
1364 /* NewLocalRef *****************************************************************
1366 Creates a new local reference that refers to the same object as ref.
1368 *******************************************************************************/
1370 jobject NewLocalRef(JNIEnv *env, jobject ref)
1372 localref_table *lrt;
1375 STATISTICS(jniinvokation());
1380 /* get local reference table (thread specific) */
1382 lrt = LOCALREFTABLE;
1384 /* check if we have space for the requested reference */
1386 if (lrt->used == lrt->capacity) {
1387 /* throw_cacao_exception_exit(string_java_lang_InternalError, */
1388 /* "Too many local references"); */
1389 fprintf(stderr, "Too many local references");
1393 /* insert the reference */
1395 for (i = 0; i < lrt->capacity; i++) {
1396 if (lrt->refs[i] == NULL) {
1397 lrt->refs[i] = (java_objectheader *) ref;
1404 /* should not happen, just to be sure */
1408 /* keep compiler happy */
1414 /* EnsureLocalCapacity *********************************************************
1416 Ensures that at least a given number of local references can be
1417 created in the current thread
1419 *******************************************************************************/
1421 jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
1423 localref_table *lrt;
1425 STATISTICS(jniinvokation());
1427 /* get local reference table (thread specific) */
1429 lrt = LOCALREFTABLE;
1431 /* check if capacity elements are available in the local references table */
1433 if ((lrt->used + capacity) > lrt->capacity) {
1434 *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
1442 /* AllocObject *****************************************************************
1444 Allocates a new Java object without invoking any of the
1445 constructors for the object. Returns a reference to the object.
1447 *******************************************************************************/
1449 jobject AllocObject(JNIEnv *env, jclass clazz)
1452 java_objectheader *o;
1454 STATISTICS(jniinvokation());
1456 c = (classinfo *) clazz;
1458 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1460 new_exception_utfmessage(string_java_lang_InstantiationException,
1467 return NewLocalRef(env, o);
1471 /* NewObject *******************************************************************
1473 Programmers place all arguments that are to be passed to the
1474 constructor immediately following the methodID
1475 argument. NewObject() accepts these arguments and passes them to
1476 the Java method that the programmer wishes to invoke.
1478 *******************************************************************************/
1480 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1482 java_objectheader *o;
1486 STATISTICS(jniinvokation());
1488 m = (methodinfo *) methodID;
1492 o = builtin_new(clazz);
1497 /* call constructor */
1499 va_start(ap, methodID);
1500 _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
1503 return NewLocalRef(env, o);
1507 /* NewObjectV ******************************************************************
1509 Programmers place all arguments that are to be passed to the
1510 constructor in an args argument of type va_list that immediately
1511 follows the methodID argument. NewObjectV() accepts these
1512 arguments, and, in turn, passes them to the Java method that the
1513 programmer wishes to invoke.
1515 *******************************************************************************/
1517 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1519 java_objectheader *o;
1522 STATISTICS(jniinvokation());
1524 m = (methodinfo *) methodID;
1528 o = builtin_new(clazz);
1533 /* call constructor */
1535 _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
1537 return NewLocalRef(env, o);
1541 /* NewObjectA *****************************************************************
1543 Programmers place all arguments that are to be passed to the
1544 constructor in an args array of jvalues that immediately follows
1545 the methodID argument. NewObjectA() accepts the arguments in this
1546 array, and, in turn, passes them to the Java method that the
1547 programmer wishes to invoke.
1549 *******************************************************************************/
1551 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1553 java_objectheader *o;
1556 STATISTICS(jniinvokation());
1558 m = (methodinfo *) methodID;
1562 o = builtin_new(clazz);
1567 /* call constructor */
1569 _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
1571 return NewLocalRef(env, o);
1575 /* GetObjectClass **************************************************************
1577 Returns the class of an object.
1579 *******************************************************************************/
1581 jclass GetObjectClass(JNIEnv *env, jobject obj)
1583 java_objectheader *o;
1586 STATISTICS(jniinvokation());
1588 o = (java_objectheader *) obj;
1590 if ((o == NULL) || (o->vftbl == NULL))
1593 c = o->vftbl->class;
1595 return (jclass) NewLocalRef(env, (jobject) c);
1599 /* IsInstanceOf ****************************************************************
1601 Tests whether an object is an instance of a class.
1603 *******************************************************************************/
1605 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1607 STATISTICS(jniinvokation());
1609 return Java_java_lang_VMClass_isInstance(env,
1611 (java_lang_Class *) clazz,
1612 (java_lang_Object *) obj);
1616 /* Reflection Support *********************************************************/
1618 /* FromReflectedMethod *********************************************************
1620 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1621 object to a method ID.
1623 *******************************************************************************/
1625 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
1631 STATISTICS(jniinvokation());
1636 if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
1637 java_lang_reflect_Method *rm;
1639 rm = (java_lang_reflect_Method *) method;
1640 c = (classinfo *) (rm->declaringClass);
1643 } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
1644 java_lang_reflect_Constructor *rc;
1646 rc = (java_lang_reflect_Constructor *) method;
1647 c = (classinfo *) (rc->clazz);
1653 mi = &(c->methods[slot]);
1655 return (jmethodID) mi;
1659 /* FromReflectedField **********************************************************
1661 Converts a java.lang.reflect.Field to a field ID.
1663 *******************************************************************************/
1665 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1667 java_lang_reflect_Field *rf;
1671 STATISTICS(jniinvokation());
1673 rf = (java_lang_reflect_Field *) field;
1678 c = (classinfo *) rf->declaringClass;
1680 f = &(c->fields[rf->slot]);
1682 return (jfieldID) f;
1686 /* ToReflectedMethod ***********************************************************
1688 Converts a method ID derived from cls to an instance of the
1689 java.lang.reflect.Method class or to an instance of the
1690 java.lang.reflect.Constructor class.
1692 *******************************************************************************/
1694 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1696 STATISTICS(jniinvokation());
1698 log_text("JNI-Call: ToReflectedMethod: IMPLEMENT ME!");
1704 /* ToReflectedField ************************************************************
1706 Converts a field ID derived from cls to an instance of the
1707 java.lang.reflect.Field class.
1709 *******************************************************************************/
1711 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1714 STATISTICS(jniinvokation());
1716 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1722 /* Calling Instance Methods ***************************************************/
1724 /* GetMethodID *****************************************************************
1726 Returns the method ID for an instance (nonstatic) method of a class
1727 or interface. The method may be defined in one of the clazz's
1728 superclasses and inherited by clazz. The method is determined by
1729 its name and signature.
1731 GetMethodID() causes an uninitialized class to be initialized.
1733 *******************************************************************************/
1735 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1743 STATISTICS(jniinvokation());
1745 c = (classinfo *) clazz;
1750 if (!(c->state & CLASS_INITIALIZED))
1751 if (!initialize_class(c))
1754 /* try to get the method of the class or one of it's superclasses */
1756 uname = utf_new_char((char *) name);
1757 udesc = utf_new_char((char *) sig);
1759 m = class_resolvemethod(clazz, uname, udesc);
1761 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1762 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1767 return (jmethodID) m;
1771 /* JNI-functions for calling instance methods *********************************/
1773 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1775 java_objectheader *o;
1777 java_objectheader *ret;
1780 o = (java_objectheader *) obj;
1781 m = (methodinfo *) methodID;
1783 va_start(ap, methodID);
1784 ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, ap);
1787 return NewLocalRef(env, ret);
1791 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1793 java_objectheader *o;
1795 java_objectheader *ret;
1797 o = (java_objectheader *) obj;
1798 m = (methodinfo *) methodID;
1800 ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, args);
1802 return NewLocalRef(env, ret);
1806 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1808 java_objectheader *o;
1810 java_objectheader *ret;
1812 o = (java_objectheader *) obj;
1813 m = (methodinfo *) methodID;
1815 ret = _Jv_jni_CallObjectMethodA(o, o->vftbl, m, args);
1817 return NewLocalRef(env, ret);
1821 jboolean CallBooleanMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1823 java_objectheader *o;
1828 o = (java_objectheader *) obj;
1829 m = (methodinfo *) methodID;
1831 va_start(ap, methodID);
1832 b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
1839 jboolean CallBooleanMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1841 java_objectheader *o;
1845 o = (java_objectheader *) obj;
1846 m = (methodinfo *) methodID;
1848 b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
1854 jboolean CallBooleanMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1856 log_text("JNI-Call: CallBooleanMethodA");
1862 jbyte CallByteMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1864 java_objectheader *o;
1869 o = (java_objectheader *) obj;
1870 m = (methodinfo *) methodID;
1872 va_start(ap, methodID);
1873 b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
1880 jbyte CallByteMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1882 java_objectheader *o;
1886 o = (java_objectheader *) obj;
1887 m = (methodinfo *) methodID;
1889 b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
1895 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1897 log_text("JNI-Call: CallByteMethodA: IMPLEMENT ME!");
1903 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1905 java_objectheader *o;
1910 o = (java_objectheader *) obj;
1911 m = (methodinfo *) methodID;
1913 va_start(ap, methodID);
1914 c = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
1921 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1923 java_objectheader *o;
1927 o = (java_objectheader *) obj;
1928 m = (methodinfo *) methodID;
1930 c = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
1936 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1938 log_text("JNI-Call: CallCharMethodA: IMPLEMENT ME!");
1944 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1946 java_objectheader *o;
1951 o = (java_objectheader *) obj;
1952 m = (methodinfo *) methodID;
1954 va_start(ap, methodID);
1955 s = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
1962 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1964 java_objectheader *o;
1968 o = (java_objectheader *) obj;
1969 m = (methodinfo *) methodID;
1971 s = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
1977 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1979 log_text("JNI-Call: CallShortMethodA: IMPLEMENT ME!");
1986 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1988 java_objectheader *o;
1993 o = (java_objectheader *) obj;
1994 m = (methodinfo *) methodID;
1996 va_start(ap, methodID);
1997 i = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2004 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2006 java_objectheader *o;
2010 o = (java_objectheader *) obj;
2011 m = (methodinfo *) methodID;
2013 i = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2019 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2021 log_text("JNI-Call: CallIntMethodA: IMPLEMENT ME!");
2028 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2030 java_objectheader *o;
2035 o = (java_objectheader *) obj;
2036 m = (methodinfo *) methodID;
2038 va_start(ap, methodID);
2039 l = _Jv_jni_CallLongMethod(o, o->vftbl, m, ap);
2046 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2048 java_objectheader *o;
2052 o = (java_objectheader *) obj;
2053 m = (methodinfo *) methodID;
2055 l = _Jv_jni_CallLongMethod(o, o->vftbl, m, args);
2061 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2063 log_text("JNI-Call: CallLongMethodA: IMPLEMENT ME!");
2070 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2072 java_objectheader *o;
2077 o = (java_objectheader *) obj;
2078 m = (methodinfo *) methodID;
2080 va_start(ap, methodID);
2081 f = _Jv_jni_CallFloatMethod(o, o->vftbl, m, ap);
2088 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2090 java_objectheader *o;
2094 o = (java_objectheader *) obj;
2095 m = (methodinfo *) methodID;
2097 f = _Jv_jni_CallFloatMethod(o, o->vftbl, m, args);
2103 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2105 log_text("JNI-Call: CallFloatMethodA: IMPLEMENT ME!");
2112 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2114 java_objectheader *o;
2119 o = (java_objectheader *) obj;
2120 m = (methodinfo *) methodID;
2122 va_start(ap, methodID);
2123 d = _Jv_jni_CallDoubleMethod(o, o->vftbl, m, ap);
2130 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2132 java_objectheader *o;
2136 o = (java_objectheader *) obj;
2137 m = (methodinfo *) methodID;
2139 d = _Jv_jni_CallDoubleMethod(o, o->vftbl, m, args);
2145 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2147 log_text("JNI-Call: CallDoubleMethodA: IMPLEMENT ME!");
2154 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2156 java_objectheader *o;
2160 o = (java_objectheader *) obj;
2161 m = (methodinfo *) methodID;
2163 va_start(ap, methodID);
2164 _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
2169 void CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2171 java_objectheader *o;
2174 o = (java_objectheader *) obj;
2175 m = (methodinfo *) methodID;
2177 _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
2181 void CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2183 java_objectheader *o;
2186 o = (java_objectheader *) obj;
2187 m = (methodinfo *) methodID;
2189 _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
2194 jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2196 java_objectheader *o;
2199 java_objectheader *r;
2202 o = (java_objectheader *) obj;
2203 c = (classinfo *) clazz;
2204 m = (methodinfo *) methodID;
2206 va_start(ap, methodID);
2207 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2210 return NewLocalRef(env, r);
2214 jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2216 java_objectheader *o;
2219 java_objectheader *r;
2221 o = (java_objectheader *) obj;
2222 c = (classinfo *) clazz;
2223 m = (methodinfo *) methodID;
2225 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2227 return NewLocalRef(env, r);
2231 jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2233 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2235 return NewLocalRef(env, NULL);
2240 jboolean CallNonvirtualBooleanMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2242 java_objectheader *o;
2248 o = (java_objectheader *) obj;
2249 c = (classinfo *) clazz;
2250 m = (methodinfo *) methodID;
2252 va_start(ap, methodID);
2253 b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2260 jboolean CallNonvirtualBooleanMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2262 java_objectheader *o;
2267 o = (java_objectheader *) obj;
2268 c = (classinfo *) clazz;
2269 m = (methodinfo *) methodID;
2271 b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2277 jboolean CallNonvirtualBooleanMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2279 log_text("JNI-Call: CallNonvirtualBooleanMethodA: IMPLEMENT ME!");
2285 jbyte CallNonvirtualByteMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2287 java_objectheader *o;
2293 o = (java_objectheader *) obj;
2294 c = (classinfo *) clazz;
2295 m = (methodinfo *) methodID;
2297 va_start(ap, methodID);
2298 b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2305 jbyte CallNonvirtualByteMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2307 java_objectheader *o;
2312 o = (java_objectheader *) obj;
2313 c = (classinfo *) clazz;
2314 m = (methodinfo *) methodID;
2316 b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2322 jbyte CallNonvirtualByteMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2324 log_text("JNI-Call: CallNonvirtualByteMethodA: IMPLEMENT ME!");
2331 jchar CallNonvirtualCharMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2333 java_objectheader *o;
2339 o = (java_objectheader *) obj;
2340 c = (classinfo *) clazz;
2341 m = (methodinfo *) methodID;
2343 va_start(ap, methodID);
2344 ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2351 jchar CallNonvirtualCharMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2353 java_objectheader *o;
2358 o = (java_objectheader *) obj;
2359 c = (classinfo *) clazz;
2360 m = (methodinfo *) methodID;
2362 ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2368 jchar CallNonvirtualCharMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2370 log_text("JNI-Call: CallNonvirtualCharMethodA: IMPLEMENT ME!");
2377 jshort CallNonvirtualShortMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2379 java_objectheader *o;
2385 o = (java_objectheader *) obj;
2386 c = (classinfo *) clazz;
2387 m = (methodinfo *) methodID;
2389 va_start(ap, methodID);
2390 s = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2397 jshort CallNonvirtualShortMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2399 java_objectheader *o;
2404 o = (java_objectheader *) obj;
2405 c = (classinfo *) clazz;
2406 m = (methodinfo *) methodID;
2408 s = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2414 jshort CallNonvirtualShortMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2416 log_text("JNI-Call: CallNonvirtualShortMethodA: IMPLEMENT ME!");
2423 jint CallNonvirtualIntMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2425 java_objectheader *o;
2431 o = (java_objectheader *) obj;
2432 c = (classinfo *) clazz;
2433 m = (methodinfo *) methodID;
2435 va_start(ap, methodID);
2436 i = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2443 jint CallNonvirtualIntMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2445 java_objectheader *o;
2450 o = (java_objectheader *) obj;
2451 c = (classinfo *) clazz;
2452 m = (methodinfo *) methodID;
2454 i = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2460 jint CallNonvirtualIntMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2462 log_text("JNI-Call: CallNonvirtualIntMethodA: IMPLEMENT ME!");
2469 jlong CallNonvirtualLongMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2471 java_objectheader *o;
2477 o = (java_objectheader *) obj;
2478 c = (classinfo *) clazz;
2479 m = (methodinfo *) methodID;
2481 va_start(ap, methodID);
2482 l = _Jv_jni_CallLongMethod(o, c->vftbl, m, ap);
2489 jlong CallNonvirtualLongMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2491 java_objectheader *o;
2496 o = (java_objectheader *) obj;
2497 c = (classinfo *) clazz;
2498 m = (methodinfo *) methodID;
2500 l = _Jv_jni_CallLongMethod(o, c->vftbl, m, args);
2506 jlong CallNonvirtualLongMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2508 log_text("JNI-Call: CallNonvirtualLongMethodA: IMPLEMENT ME!");
2515 jfloat CallNonvirtualFloatMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2517 java_objectheader *o;
2523 o = (java_objectheader *) obj;
2524 c = (classinfo *) clazz;
2525 m = (methodinfo *) methodID;
2527 va_start(ap, methodID);
2528 f = _Jv_jni_CallFloatMethod(o, c->vftbl, m, ap);
2535 jfloat CallNonvirtualFloatMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2537 java_objectheader *o;
2542 o = (java_objectheader *) obj;
2543 c = (classinfo *) clazz;
2544 m = (methodinfo *) methodID;
2546 f = _Jv_jni_CallFloatMethod(o, c->vftbl, m, args);
2552 jfloat CallNonvirtualFloatMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2554 log_text("JNI-Call: CallNonvirtualFloatMethodA: IMPLEMENT ME!");
2561 jdouble CallNonvirtualDoubleMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2563 java_objectheader *o;
2569 o = (java_objectheader *) obj;
2570 c = (classinfo *) clazz;
2571 m = (methodinfo *) methodID;
2573 va_start(ap, methodID);
2574 d = _Jv_jni_CallDoubleMethod(o, c->vftbl, m, ap);
2581 jdouble CallNonvirtualDoubleMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2583 java_objectheader *o;
2588 o = (java_objectheader *) obj;
2589 c = (classinfo *) clazz;
2590 m = (methodinfo *) methodID;
2592 d = _Jv_jni_CallDoubleMethod(o, c->vftbl, m, args);
2598 jdouble CallNonvirtualDoubleMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2600 log_text("JNI-Call: CallNonvirtualDoubleMethodA: IMPLEMENT ME!");
2607 void CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2609 java_objectheader *o;
2614 o = (java_objectheader *) obj;
2615 c = (classinfo *) clazz;
2616 m = (methodinfo *) methodID;
2618 va_start(ap, methodID);
2619 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2624 void CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2626 java_objectheader *o;
2630 o = (java_objectheader *) obj;
2631 c = (classinfo *) clazz;
2632 m = (methodinfo *) methodID;
2634 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2638 void CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
2640 java_objectheader *o;
2644 o = (java_objectheader *) obj;
2645 c = (classinfo *) clazz;
2646 m = (methodinfo *) methodID;
2648 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2652 /* Accessing Fields of Objects ************************************************/
2654 /* GetFieldID ******************************************************************
2656 Returns the field ID for an instance (nonstatic) field of a
2657 class. The field is specified by its name and signature. The
2658 Get<type>Field and Set<type>Field families of accessor functions
2659 use field IDs to retrieve object fields.
2661 *******************************************************************************/
2663 jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2670 STATISTICS(jniinvokation());
2672 uname = utf_new_char((char *) name);
2673 udesc = utf_new_char((char *) sig);
2675 f = class_findfield(clazz, uname, udesc);
2678 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2680 return (jfieldID) f;
2684 /* Get<type>Field Routines *****************************************************
2686 This family of accessor routines returns the value of an instance
2687 (nonstatic) field of an object. The field to access is specified by
2688 a field ID obtained by calling GetFieldID().
2690 *******************************************************************************/
2692 jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2694 java_objectheader *o;
2696 STATISTICS(jniinvokation());
2698 o = GET_FIELD(obj, java_objectheader*, fieldID);
2700 return NewLocalRef(env, o);
2704 jboolean GetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID)
2708 STATISTICS(jniinvokation());
2710 i = GET_FIELD(obj, s4, fieldID);
2712 return (jboolean) i;
2716 jbyte GetByteField(JNIEnv *env, jobject obj, jfieldID fieldID)
2720 STATISTICS(jniinvokation());
2722 i = GET_FIELD(obj, s4, fieldID);
2728 jchar GetCharField(JNIEnv *env, jobject obj, jfieldID fieldID)
2732 STATISTICS(jniinvokation());
2734 i = GET_FIELD(obj, s4, fieldID);
2740 jshort GetShortField(JNIEnv *env, jobject obj, jfieldID fieldID)
2744 STATISTICS(jniinvokation());
2746 i = GET_FIELD(obj, s4, fieldID);
2752 jint GetIntField(JNIEnv *env, jobject obj, jfieldID fieldID)
2754 java_objectheader *o;
2758 STATISTICS(jniinvokation());
2760 o = (java_objectheader *) obj;
2761 f = (fieldinfo *) fieldID;
2763 i = GET_FIELD(o, s4, f);
2769 jlong GetLongField(JNIEnv *env, jobject obj, jfieldID fieldID)
2773 STATISTICS(jniinvokation());
2775 l = GET_FIELD(obj, s8, fieldID);
2781 jfloat GetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID)
2785 STATISTICS(jniinvokation());
2787 f = GET_FIELD(obj, float, fieldID);
2793 jdouble GetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID)
2797 STATISTICS(jniinvokation());
2799 d = GET_FIELD(obj, double, fieldID);
2805 /* Set<type>Field Routines *****************************************************
2807 This family of accessor routines sets the value of an instance
2808 (nonstatic) field of an object. The field to access is specified by
2809 a field ID obtained by calling GetFieldID().
2811 *******************************************************************************/
2813 void SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value)
2815 STATISTICS(jniinvokation());
2817 SET_FIELD(obj, java_objectheader*, fieldID, value);
2821 void SetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID, jboolean value)
2823 STATISTICS(jniinvokation());
2825 SET_FIELD(obj, s4, fieldID, value);
2829 void SetByteField(JNIEnv *env, jobject obj, jfieldID fieldID, jbyte value)
2831 STATISTICS(jniinvokation());
2833 SET_FIELD(obj, s4, fieldID, value);
2837 void SetCharField(JNIEnv *env, jobject obj, jfieldID fieldID, jchar value)
2839 STATISTICS(jniinvokation());
2841 SET_FIELD(obj, s4, fieldID, value);
2845 void SetShortField(JNIEnv *env, jobject obj, jfieldID fieldID, jshort value)
2847 STATISTICS(jniinvokation());
2849 SET_FIELD(obj, s4, fieldID, value);
2853 void SetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint value)
2855 STATISTICS(jniinvokation());
2857 SET_FIELD(obj, s4, fieldID, value);
2861 void SetLongField(JNIEnv *env, jobject obj, jfieldID fieldID, jlong value)
2863 STATISTICS(jniinvokation());
2865 SET_FIELD(obj, s8, fieldID, value);
2869 void SetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID, jfloat value)
2871 STATISTICS(jniinvokation());
2873 SET_FIELD(obj, float, fieldID, value);
2877 void SetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID, jdouble value)
2879 STATISTICS(jniinvokation());
2881 SET_FIELD(obj, double, fieldID, value);
2885 /* Calling Static Methods *****************************************************/
2887 /* GetStaticMethodID ***********************************************************
2889 Returns the method ID for a static method of a class. The method is
2890 specified by its name and signature.
2892 GetStaticMethodID() causes an uninitialized class to be
2895 *******************************************************************************/
2897 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2905 STATISTICS(jniinvokation());
2907 c = (classinfo *) clazz;
2912 if (!(c->state & CLASS_INITIALIZED))
2913 if (!initialize_class(c))
2916 /* try to get the static method of the class */
2918 uname = utf_new_char((char *) name);
2919 udesc = utf_new_char((char *) sig);
2921 m = class_resolvemethod(c, uname, udesc);
2923 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2924 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2929 return (jmethodID) m;
2933 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2936 java_objectheader *o;
2939 m = (methodinfo *) methodID;
2941 va_start(ap, methodID);
2942 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2945 return NewLocalRef(env, o);
2949 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2952 java_objectheader *o;
2954 m = (methodinfo *) methodID;
2956 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2958 return NewLocalRef(env, o);
2962 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2965 java_objectheader *o;
2967 m = (methodinfo *) methodID;
2969 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2971 return NewLocalRef(env, o);
2975 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2981 m = (methodinfo *) methodID;
2983 va_start(ap, methodID);
2984 b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
2991 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2996 m = (methodinfo *) methodID;
2998 b = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3004 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3006 log_text("JNI-Call: CallStaticBooleanMethodA: IMPLEMENT ME!");
3012 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3018 m = (methodinfo *) methodID;
3020 va_start(ap, methodID);
3021 b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3028 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3033 m = (methodinfo *) methodID;
3035 b = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3041 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3043 log_text("JNI-Call: CallStaticByteMethodA: IMPLEMENT ME!");
3049 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3055 m = (methodinfo *) methodID;
3057 va_start(ap, methodID);
3058 c = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3065 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3070 m = (methodinfo *) methodID;
3072 c = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3078 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3080 log_text("JNI-Call: CallStaticCharMethodA: IMPLEMENT ME!");
3086 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3092 m = (methodinfo *) methodID;
3094 va_start(ap, methodID);
3095 s = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3102 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3107 m = (methodinfo *) methodID;
3109 s = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3115 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3117 log_text("JNI-Call: CallStaticShortMethodA: IMPLEMENT ME!");
3123 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3129 m = (methodinfo *) methodID;
3131 va_start(ap, methodID);
3132 i = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3139 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3144 m = (methodinfo *) methodID;
3146 i = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3152 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3154 log_text("JNI-Call: CallStaticIntMethodA: IMPLEMENT ME!");
3160 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3166 m = (methodinfo *) methodID;
3168 va_start(ap, methodID);
3169 l = _Jv_jni_CallLongMethod(NULL, NULL, m, ap);
3176 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
3182 m = (methodinfo *) methodID;
3184 l = _Jv_jni_CallLongMethod(NULL, NULL, m, args);
3190 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3192 log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!");
3199 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3205 m = (methodinfo *) methodID;
3207 va_start(ap, methodID);
3208 f = _Jv_jni_CallFloatMethod(NULL, NULL, m, ap);
3215 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3220 m = (methodinfo *) methodID;
3222 f = _Jv_jni_CallFloatMethod(NULL, NULL, m, args);
3228 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3230 log_text("JNI-Call: CallStaticFloatMethodA: IMPLEMENT ME!");
3236 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3242 m = (methodinfo *) methodID;
3244 va_start(ap, methodID);
3245 d = _Jv_jni_CallDoubleMethod(NULL, NULL, m, ap);
3252 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3257 m = (methodinfo *) methodID;
3259 d = _Jv_jni_CallDoubleMethod(NULL, NULL, m, args);
3265 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3267 log_text("JNI-Call: CallStaticDoubleMethodA: IMPLEMENT ME!");
3273 void CallStaticVoidMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3278 m = (methodinfo *) methodID;
3280 va_start(ap, methodID);
3281 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
3286 void CallStaticVoidMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3290 m = (methodinfo *) methodID;
3292 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
3296 void CallStaticVoidMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue * args)
3300 m = (methodinfo *) methodID;
3302 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
3306 /* Accessing Static Fields ****************************************************/
3308 /* GetStaticFieldID ************************************************************
3310 Returns the field ID for a static field of a class. The field is
3311 specified by its name and signature. The GetStatic<type>Field and
3312 SetStatic<type>Field families of accessor functions use field IDs
3313 to retrieve static fields.
3315 *******************************************************************************/
3317 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
3321 STATISTICS(jniinvokation());
3323 f = class_findfield(clazz,
3324 utf_new_char((char *) name),
3325 utf_new_char((char *) sig));
3328 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
3330 return (jfieldID) f;
3334 /* GetStatic<type>Field ********************************************************
3336 This family of accessor routines returns the value of a static
3339 *******************************************************************************/
3341 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3346 STATISTICS(jniinvokation());
3348 c = (classinfo *) clazz;
3349 f = (fieldinfo *) fieldID;
3351 if (!(c->state & CLASS_INITIALIZED))
3352 if (!initialize_class(c))
3355 return NewLocalRef(env, f->value.a);
3359 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3364 STATISTICS(jniinvokation());
3366 c = (classinfo *) clazz;
3367 f = (fieldinfo *) fieldID;
3369 if (!(c->state & CLASS_INITIALIZED))
3370 if (!initialize_class(c))
3377 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3382 STATISTICS(jniinvokation());
3384 c = (classinfo *) clazz;
3385 f = (fieldinfo *) fieldID;
3387 if (!(c->state & CLASS_INITIALIZED))
3388 if (!initialize_class(c))
3395 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3400 STATISTICS(jniinvokation());
3402 c = (classinfo *) clazz;
3403 f = (fieldinfo *) fieldID;
3405 if (!(c->state & CLASS_INITIALIZED))
3406 if (!initialize_class(c))
3413 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3418 STATISTICS(jniinvokation());
3420 c = (classinfo *) clazz;
3421 f = (fieldinfo *) fieldID;
3423 if (!(c->state & CLASS_INITIALIZED))
3424 if (!initialize_class(c))
3431 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3436 STATISTICS(jniinvokation());
3438 c = (classinfo *) clazz;
3439 f = (fieldinfo *) fieldID;
3441 if (!(c->state & CLASS_INITIALIZED))
3442 if (!initialize_class(c))
3449 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3454 STATISTICS(jniinvokation());
3456 c = (classinfo *) clazz;
3457 f = (fieldinfo *) fieldID;
3459 if (!(c->state & CLASS_INITIALIZED))
3460 if (!initialize_class(c))
3467 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3472 STATISTICS(jniinvokation());
3474 c = (classinfo *) clazz;
3475 f = (fieldinfo *) fieldID;
3477 if (!(c->state & CLASS_INITIALIZED))
3478 if (!initialize_class(c))
3485 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3490 STATISTICS(jniinvokation());
3492 c = (classinfo *) clazz;
3493 f = (fieldinfo *) fieldID;
3495 if (!(c->state & CLASS_INITIALIZED))
3496 if (!initialize_class(c))
3503 /* SetStatic<type>Field *******************************************************
3505 This family of accessor routines sets the value of a static field
3508 *******************************************************************************/
3510 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
3515 STATISTICS(jniinvokation());
3517 c = (classinfo *) clazz;
3518 f = (fieldinfo *) fieldID;
3520 if (!(c->state & CLASS_INITIALIZED))
3521 if (!initialize_class(c))
3528 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
3533 STATISTICS(jniinvokation());
3535 c = (classinfo *) clazz;
3536 f = (fieldinfo *) fieldID;
3538 if (!(c->state & CLASS_INITIALIZED))
3539 if (!initialize_class(c))
3546 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
3551 STATISTICS(jniinvokation());
3553 c = (classinfo *) clazz;
3554 f = (fieldinfo *) fieldID;
3556 if (!(c->state & CLASS_INITIALIZED))
3557 if (!initialize_class(c))
3564 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
3569 STATISTICS(jniinvokation());
3571 c = (classinfo *) clazz;
3572 f = (fieldinfo *) fieldID;
3574 if (!(c->state & CLASS_INITIALIZED))
3575 if (!initialize_class(c))
3582 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
3587 STATISTICS(jniinvokation());
3589 c = (classinfo *) clazz;
3590 f = (fieldinfo *) fieldID;
3592 if (!(c->state & CLASS_INITIALIZED))
3593 if (!initialize_class(c))
3600 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
3605 STATISTICS(jniinvokation());
3607 c = (classinfo *) clazz;
3608 f = (fieldinfo *) fieldID;
3610 if (!(c->state & CLASS_INITIALIZED))
3611 if (!initialize_class(c))
3618 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
3623 STATISTICS(jniinvokation());
3625 c = (classinfo *) clazz;
3626 f = (fieldinfo *) fieldID;
3628 if (!(c->state & CLASS_INITIALIZED))
3629 if (!initialize_class(c))
3636 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
3641 STATISTICS(jniinvokation());
3643 c = (classinfo *) clazz;
3644 f = (fieldinfo *) fieldID;
3646 if (!(c->state & CLASS_INITIALIZED))
3647 if (!initialize_class(c))
3654 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
3659 STATISTICS(jniinvokation());
3661 c = (classinfo *) clazz;
3662 f = (fieldinfo *) fieldID;
3664 if (!(c->state & CLASS_INITIALIZED))
3665 if (!initialize_class(c))
3672 /* String Operations **********************************************************/
3674 /* NewString *******************************************************************
3676 Create new java.lang.String object from an array of Unicode
3679 *******************************************************************************/
3681 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
3683 java_lang_String *s;
3687 STATISTICS(jniinvokation());
3689 s = (java_lang_String *) builtin_new(class_java_lang_String);
3690 a = builtin_newarray_char(len);
3692 /* javastring or characterarray could not be created */
3697 for (i = 0; i < len; i++)
3698 a->data[i] = buf[i];
3704 return (jstring) NewLocalRef(env, (jobject) s);
3708 static jchar emptyStringJ[]={0,0};
3710 /* GetStringLength *************************************************************
3712 Returns the length (the count of Unicode characters) of a Java
3715 *******************************************************************************/
3717 jsize GetStringLength(JNIEnv *env, jstring str)
3719 return ((java_lang_String *) str)->count;
3723 /******************** convertes javastring to u2-array ****************************/
3725 u2 *javastring_tou2(jstring so)
3727 java_lang_String *s;
3732 STATISTICS(jniinvokation());
3734 s = (java_lang_String *) so;
3744 /* allocate memory */
3746 stringbuffer = MNEW(u2, s->count + 1);
3750 for (i = 0; i < s->count; i++)
3751 stringbuffer[i] = a->data[s->offset + i];
3753 /* terminate string */
3755 stringbuffer[i] = '\0';
3757 return stringbuffer;
3761 /* GetStringChars **************************************************************
3763 Returns a pointer to the array of Unicode characters of the
3764 string. This pointer is valid until ReleaseStringchars() is called.
3766 *******************************************************************************/
3768 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
3772 STATISTICS(jniinvokation());
3774 jc = javastring_tou2(str);
3786 return emptyStringJ;
3790 /* ReleaseStringChars **********************************************************
3792 Informs the VM that the native code no longer needs access to
3793 chars. The chars argument is a pointer obtained from string using
3796 *******************************************************************************/
3798 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
3800 STATISTICS(jniinvokation());
3802 if (chars == emptyStringJ)
3805 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
3809 /* NewStringUTF ****************************************************************
3811 Constructs a new java.lang.String object from an array of UTF-8 characters.
3813 *******************************************************************************/
3815 jstring NewStringUTF(JNIEnv *env, const char *bytes)
3817 java_lang_String *s;
3819 STATISTICS(jniinvokation());
3821 s = javastring_new(utf_new_char(bytes));
3823 return (jstring) NewLocalRef(env, (jobject) s);
3827 /****************** returns the utf8 length in bytes of a string *******************/
3829 jsize GetStringUTFLength (JNIEnv *env, jstring string)
3831 java_lang_String *s = (java_lang_String*) string;
3833 STATISTICS(jniinvokation());
3835 return (jsize) u2_utflength(s->value->data, s->count);
3839 /* GetStringUTFChars ***********************************************************
3841 Returns a pointer to an array of UTF-8 characters of the
3842 string. This array is valid until it is released by
3843 ReleaseStringUTFChars().
3845 *******************************************************************************/
3847 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
3851 STATISTICS(jniinvokation());
3859 u = javastring_toutf((java_lang_String *) string, false);
3868 /* ReleaseStringUTFChars *******************************************************
3870 Informs the VM that the native code no longer needs access to
3871 utf. The utf argument is a pointer derived from string using
3872 GetStringUTFChars().
3874 *******************************************************************************/
3876 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
3878 STATISTICS(jniinvokation());
3880 /* XXX we don't release utf chars right now, perhaps that should be done
3881 later. Since there is always one reference the garbage collector will
3886 /* Array Operations ***********************************************************/
3888 /* GetArrayLength **************************************************************
3890 Returns the number of elements in the array.
3892 *******************************************************************************/
3894 jsize GetArrayLength(JNIEnv *env, jarray array)
3896 java_arrayheader *a;
3898 STATISTICS(jniinvokation());
3900 a = (java_arrayheader *) array;
3906 /* NewObjectArray **************************************************************
3908 Constructs a new array holding objects in class elementClass. All
3909 elements are initially set to initialElement.
3911 *******************************************************************************/
3913 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
3915 java_objectarray *oa;
3918 STATISTICS(jniinvokation());
3921 exceptions_throw_negativearraysizeexception();
3925 oa = builtin_anewarray(length, elementClass);
3930 /* set all elements to initialElement */
3932 for (i = 0; i < length; i++)
3933 oa->data[i] = initialElement;
3935 return (jobjectArray) NewLocalRef(env, (jobject) oa);
3939 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
3941 java_objectarray *oa;
3944 STATISTICS(jniinvokation());
3946 oa = (java_objectarray *) array;
3948 if (index >= oa->header.size) {
3949 exceptions_throw_arrayindexoutofboundsexception();
3953 o = oa->data[index];
3955 return NewLocalRef(env, o);
3959 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3961 java_objectarray *oa;
3962 java_objectheader *o;
3964 STATISTICS(jniinvokation());
3966 oa = (java_objectarray *) array;
3967 o = (java_objectheader *) val;
3969 if (index >= oa->header.size) {
3970 exceptions_throw_arrayindexoutofboundsexception();
3974 /* check if the class of value is a subclass of the element class
3977 if (!builtin_canstore(oa, o)) {
3978 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3983 oa->data[index] = val;
3987 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3989 java_booleanarray *ba;
3991 STATISTICS(jniinvokation());
3994 exceptions_throw_negativearraysizeexception();
3998 ba = builtin_newarray_boolean(len);
4000 return (jbooleanArray) NewLocalRef(env, (jobject) ba);
4004 jbyteArray NewByteArray(JNIEnv *env, jsize len)
4008 STATISTICS(jniinvokation());
4011 exceptions_throw_negativearraysizeexception();
4015 ba = builtin_newarray_byte(len);
4017 return (jbyteArray) NewLocalRef(env, (jobject) ba);
4021 jcharArray NewCharArray(JNIEnv *env, jsize len)
4025 STATISTICS(jniinvokation());
4028 exceptions_throw_negativearraysizeexception();
4032 ca = builtin_newarray_char(len);
4034 return (jcharArray) NewLocalRef(env, (jobject) ca);
4038 jshortArray NewShortArray(JNIEnv *env, jsize len)
4040 java_shortarray *sa;
4042 STATISTICS(jniinvokation());
4045 exceptions_throw_negativearraysizeexception();
4049 sa = builtin_newarray_short(len);
4051 return (jshortArray) NewLocalRef(env, (jobject) sa);
4055 jintArray NewIntArray(JNIEnv *env, jsize len)
4059 STATISTICS(jniinvokation());
4062 exceptions_throw_negativearraysizeexception();
4066 ia = builtin_newarray_int(len);
4068 return (jintArray) NewLocalRef(env, (jobject) ia);
4072 jlongArray NewLongArray(JNIEnv *env, jsize len)
4076 STATISTICS(jniinvokation());
4079 exceptions_throw_negativearraysizeexception();
4083 la = builtin_newarray_long(len);
4085 return (jlongArray) NewLocalRef(env, (jobject) la);
4089 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
4091 java_floatarray *fa;
4093 STATISTICS(jniinvokation());
4096 exceptions_throw_negativearraysizeexception();
4100 fa = builtin_newarray_float(len);
4102 return (jfloatArray) NewLocalRef(env, (jobject) fa);
4106 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
4108 java_doublearray *da;
4110 STATISTICS(jniinvokation());
4113 exceptions_throw_negativearraysizeexception();
4117 da = builtin_newarray_double(len);
4119 return (jdoubleArray) NewLocalRef(env, (jobject) da);
4123 /* Get<PrimitiveType>ArrayElements *********************************************
4125 A family of functions that returns the body of the primitive array.
4127 *******************************************************************************/
4129 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
4132 java_booleanarray *ba;
4134 STATISTICS(jniinvokation());
4136 ba = (java_booleanarray *) array;
4139 *isCopy = JNI_FALSE;
4145 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
4149 STATISTICS(jniinvokation());
4151 ba = (java_bytearray *) array;
4154 *isCopy = JNI_FALSE;
4160 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
4164 STATISTICS(jniinvokation());
4166 ca = (java_chararray *) array;
4169 *isCopy = JNI_FALSE;
4175 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
4177 java_shortarray *sa;
4179 STATISTICS(jniinvokation());
4181 sa = (java_shortarray *) array;
4184 *isCopy = JNI_FALSE;
4190 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
4194 STATISTICS(jniinvokation());
4196 ia = (java_intarray *) array;
4199 *isCopy = JNI_FALSE;
4205 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
4209 STATISTICS(jniinvokation());
4211 la = (java_longarray *) array;
4214 *isCopy = JNI_FALSE;
4216 /* We cast this one to prevent a compiler warning on 64-bit
4217 systems since GNU Classpath typedef jlong to long long. */
4219 return (jlong *) la->data;
4223 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
4225 java_floatarray *fa;
4227 STATISTICS(jniinvokation());
4229 fa = (java_floatarray *) array;
4232 *isCopy = JNI_FALSE;
4238 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
4241 java_doublearray *da;
4243 STATISTICS(jniinvokation());
4245 da = (java_doublearray *) array;
4248 *isCopy = JNI_FALSE;
4254 /* Release<PrimitiveType>ArrayElements *****************************************
4256 A family of functions that informs the VM that the native code no
4257 longer needs access to elems. The elems argument is a pointer
4258 derived from array using the corresponding
4259 Get<PrimitiveType>ArrayElements() function. If necessary, this
4260 function copies back all changes made to elems to the original
4263 *******************************************************************************/
4265 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
4266 jboolean *elems, jint mode)
4268 java_booleanarray *ba;
4270 STATISTICS(jniinvokation());
4272 ba = (java_booleanarray *) array;
4274 if (elems != ba->data) {
4277 MCOPY(ba->data, elems, u1, ba->header.size);
4280 MCOPY(ba->data, elems, u1, ba->header.size);
4281 /* XXX TWISTI how should it be freed? */
4284 /* XXX TWISTI how should it be freed? */
4291 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
4296 STATISTICS(jniinvokation());
4298 ba = (java_bytearray *) array;
4300 if (elems != ba->data) {
4303 MCOPY(ba->data, elems, s1, ba->header.size);
4306 MCOPY(ba->data, elems, s1, ba->header.size);
4307 /* XXX TWISTI how should it be freed? */
4310 /* XXX TWISTI how should it be freed? */
4317 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
4322 STATISTICS(jniinvokation());
4324 ca = (java_chararray *) array;
4326 if (elems != ca->data) {
4329 MCOPY(ca->data, elems, u2, ca->header.size);
4332 MCOPY(ca->data, elems, u2, ca->header.size);
4333 /* XXX TWISTI how should it be freed? */
4336 /* XXX TWISTI how should it be freed? */
4343 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
4346 java_shortarray *sa;
4348 STATISTICS(jniinvokation());
4350 sa = (java_shortarray *) array;
4352 if (elems != sa->data) {
4355 MCOPY(sa->data, elems, s2, sa->header.size);
4358 MCOPY(sa->data, elems, s2, sa->header.size);
4359 /* XXX TWISTI how should it be freed? */
4362 /* XXX TWISTI how should it be freed? */
4369 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
4374 STATISTICS(jniinvokation());
4376 ia = (java_intarray *) array;
4378 if (elems != ia->data) {
4381 MCOPY(ia->data, elems, s4, ia->header.size);
4384 MCOPY(ia->data, elems, s4, ia->header.size);
4385 /* XXX TWISTI how should it be freed? */
4388 /* XXX TWISTI how should it be freed? */
4395 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
4400 STATISTICS(jniinvokation());
4402 la = (java_longarray *) array;
4404 /* We cast this one to prevent a compiler warning on 64-bit
4405 systems since GNU Classpath typedef jlong to long long. */
4407 if ((s8 *) elems != la->data) {
4410 MCOPY(la->data, elems, s8, la->header.size);
4413 MCOPY(la->data, elems, s8, la->header.size);
4414 /* XXX TWISTI how should it be freed? */
4417 /* XXX TWISTI how should it be freed? */
4424 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
4427 java_floatarray *fa;
4429 STATISTICS(jniinvokation());
4431 fa = (java_floatarray *) array;
4433 if (elems != fa->data) {
4436 MCOPY(fa->data, elems, float, fa->header.size);
4439 MCOPY(fa->data, elems, float, fa->header.size);
4440 /* XXX TWISTI how should it be freed? */
4443 /* XXX TWISTI how should it be freed? */
4450 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
4451 jdouble *elems, jint mode)
4453 java_doublearray *da;
4455 STATISTICS(jniinvokation());
4457 da = (java_doublearray *) array;
4459 if (elems != da->data) {
4462 MCOPY(da->data, elems, double, da->header.size);
4465 MCOPY(da->data, elems, double, da->header.size);
4466 /* XXX TWISTI how should it be freed? */
4469 /* XXX TWISTI how should it be freed? */
4476 /* Get<PrimitiveType>ArrayRegion **********************************************
4478 A family of functions that copies a region of a primitive array
4481 *******************************************************************************/
4483 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
4484 jsize len, jboolean *buf)
4486 java_booleanarray *ba;
4488 STATISTICS(jniinvokation());
4490 ba = (java_booleanarray *) array;
4492 if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4493 exceptions_throw_arrayindexoutofboundsexception();
4495 MCOPY(buf, &ba->data[start], u1, len);
4499 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
4504 STATISTICS(jniinvokation());
4506 ba = (java_bytearray *) array;
4508 if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4509 exceptions_throw_arrayindexoutofboundsexception();
4511 MCOPY(buf, &ba->data[start], s1, len);
4515 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
4520 STATISTICS(jniinvokation());
4522 ca = (java_chararray *) array;
4524 if ((start < 0) || (len < 0) || (start + len > ca->header.size))
4525 exceptions_throw_arrayindexoutofboundsexception();
4527 MCOPY(buf, &ca->data[start], u2, len);
4531 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
4532 jsize len, jshort *buf)
4534 java_shortarray *sa;
4536 STATISTICS(jniinvokation());
4538 sa = (java_shortarray *) array;
4540 if ((start < 0) || (len < 0) || (start + len > sa->header.size))
4541 exceptions_throw_arrayindexoutofboundsexception();
4543 MCOPY(buf, &sa->data[start], s2, len);
4547 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
4552 STATISTICS(jniinvokation());
4554 ia = (java_intarray *) array;
4556 if ((start < 0) || (len < 0) || (start + len > ia->header.size))
4557 exceptions_throw_arrayindexoutofboundsexception();
4559 MCOPY(buf, &ia->data[start], s4, len);
4563 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
4568 STATISTICS(jniinvokation());
4570 la = (java_longarray *) array;
4572 if ((start < 0) || (len < 0) || (start + len > la->header.size))
4573 exceptions_throw_arrayindexoutofboundsexception();
4575 MCOPY(buf, &la->data[start], s8, len);
4579 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
4580 jsize len, jfloat *buf)
4582 java_floatarray *fa;
4584 STATISTICS(jniinvokation());
4586 fa = (java_floatarray *) array;
4588 if ((start < 0) || (len < 0) || (start + len > fa->header.size))
4589 exceptions_throw_arrayindexoutofboundsexception();
4591 MCOPY(buf, &fa->data[start], float, len);
4595 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
4596 jsize len, jdouble *buf)
4598 java_doublearray *da;
4600 STATISTICS(jniinvokation());
4602 da = (java_doublearray *) array;
4604 if ((start < 0) || (len < 0) || (start + len > da->header.size))
4605 exceptions_throw_arrayindexoutofboundsexception();
4607 MCOPY(buf, &da->data[start], double, len);
4611 /* Set<PrimitiveType>ArrayRegion **********************************************
4613 A family of functions that copies back a region of a primitive
4614 array from a buffer.
4616 *******************************************************************************/
4618 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
4619 jsize len, jboolean *buf)
4621 java_booleanarray *ba;
4623 STATISTICS(jniinvokation());
4625 ba = (java_booleanarray *) array;
4627 if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4628 exceptions_throw_arrayindexoutofboundsexception();
4630 MCOPY(&ba->data[start], buf, u1, len);
4634 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
4639 STATISTICS(jniinvokation());
4641 ba = (java_bytearray *) array;
4643 if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4644 exceptions_throw_arrayindexoutofboundsexception();
4646 MCOPY(&ba->data[start], buf, s1, len);
4650 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
4655 STATISTICS(jniinvokation());
4657 ca = (java_chararray *) array;
4659 if ((start < 0) || (len < 0) || (start + len > ca->header.size))
4660 exceptions_throw_arrayindexoutofboundsexception();
4662 MCOPY(&ca->data[start], buf, u2, len);
4666 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
4667 jsize len, jshort *buf)
4669 java_shortarray *sa;
4671 STATISTICS(jniinvokation());
4673 sa = (java_shortarray *) array;
4675 if ((start < 0) || (len < 0) || (start + len > sa->header.size))
4676 exceptions_throw_arrayindexoutofboundsexception();
4678 MCOPY(&sa->data[start], buf, s2, len);
4682 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
4687 STATISTICS(jniinvokation());
4689 ia = (java_intarray *) array;
4691 if ((start < 0) || (len < 0) || (start + len > ia->header.size))
4692 exceptions_throw_arrayindexoutofboundsexception();
4694 MCOPY(&ia->data[start], buf, s4, len);
4698 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
4703 STATISTICS(jniinvokation());
4705 la = (java_longarray *) array;
4707 if ((start < 0) || (len < 0) || (start + len > la->header.size))
4708 exceptions_throw_arrayindexoutofboundsexception();
4710 MCOPY(&la->data[start], buf, s8, len);
4714 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
4715 jsize len, jfloat *buf)
4717 java_floatarray *fa;
4719 STATISTICS(jniinvokation());
4721 fa = (java_floatarray *) array;
4723 if ((start < 0) || (len < 0) || (start + len > fa->header.size))
4724 exceptions_throw_arrayindexoutofboundsexception();
4726 MCOPY(&fa->data[start], buf, float, len);
4730 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
4731 jsize len, jdouble *buf)
4733 java_doublearray *da;
4735 STATISTICS(jniinvokation());
4737 da = (java_doublearray *) array;
4739 if ((start < 0) || (len < 0) || (start + len > da->header.size))
4740 exceptions_throw_arrayindexoutofboundsexception();
4742 MCOPY(&da->data[start], buf, double, len);
4746 /* Registering Native Methods *************************************************/
4748 /* RegisterNatives *************************************************************
4750 Registers native methods with the class specified by the clazz
4751 argument. The methods parameter specifies an array of
4752 JNINativeMethod structures that contain the names, signatures, and
4753 function pointers of the native methods. The nMethods parameter
4754 specifies the number of native methods in the array.
4756 *******************************************************************************/
4758 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
4761 STATISTICS(jniinvokation());
4763 log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
4769 /* UnregisterNatives ***********************************************************
4771 Unregisters native methods of a class. The class goes back to the
4772 state before it was linked or registered with its native method
4775 This function should not be used in normal native code. Instead, it
4776 provides special programs a way to reload and relink native
4779 *******************************************************************************/
4781 jint UnregisterNatives(JNIEnv *env, jclass clazz)
4783 STATISTICS(jniinvokation());
4785 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
4787 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
4793 /* Monitor Operations *********************************************************/
4795 /* MonitorEnter ****************************************************************
4797 Enters the monitor associated with the underlying Java object
4800 *******************************************************************************/
4802 jint MonitorEnter(JNIEnv *env, jobject obj)
4804 STATISTICS(jniinvokation());
4807 exceptions_throw_nullpointerexception();
4811 #if defined(USE_THREADS)
4812 builtin_monitorenter(obj);
4819 /* MonitorExit *****************************************************************
4821 The current thread must be the owner of the monitor associated with
4822 the underlying Java object referred to by obj. The thread
4823 decrements the counter indicating the number of times it has
4824 entered this monitor. If the value of the counter becomes zero, the
4825 current thread releases the monitor.
4827 *******************************************************************************/
4829 jint MonitorExit(JNIEnv *env, jobject obj)
4831 STATISTICS(jniinvokation());
4834 exceptions_throw_nullpointerexception();
4838 #if defined(USE_THREADS)
4839 builtin_monitorexit(obj);
4846 /* JavaVM Interface ***********************************************************/
4848 /* GetJavaVM *******************************************************************
4850 Returns the Java VM interface (used in the Invocation API)
4851 associated with the current thread. The result is placed at the
4852 location pointed to by the second argument, vm.
4854 *******************************************************************************/
4856 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
4858 STATISTICS(jniinvokation());
4860 *vm = (JavaVM *) _Jv_jvm;
4866 /* GetStringRegion *************************************************************
4868 Copies len number of Unicode characters beginning at offset start
4869 to the given buffer buf.
4871 Throws StringIndexOutOfBoundsException on index overflow.
4873 *******************************************************************************/
4875 void GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
4877 java_lang_String *s;
4880 STATISTICS(jniinvokation());
4882 s = (java_lang_String *) str;
4885 if ((start < 0) || (len < 0) || (start > s->count) ||
4886 (start + len > s->count)) {
4887 exceptions_throw_stringindexoutofboundsexception();
4891 MCOPY(buf, &ca->data[start], u2, len);
4895 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
4897 STATISTICS(jniinvokation());
4899 log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
4903 /* GetPrimitiveArrayCritical ***************************************************
4905 Obtain a direct pointer to array elements.
4907 *******************************************************************************/
4909 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
4914 ba = (java_bytearray *) array;
4916 /* do the same as Kaffe does */
4918 bp = GetByteArrayElements(env, ba, isCopy);
4924 /* ReleasePrimitiveArrayCritical ***********************************************
4926 No specific documentation.
4928 *******************************************************************************/
4930 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
4933 STATISTICS(jniinvokation());
4935 /* do the same as Kaffe does */
4937 ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
4941 /* GetStringCritical ***********************************************************
4943 The semantics of these two functions are similar to the existing
4944 Get/ReleaseStringChars functions.
4946 *******************************************************************************/
4948 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
4950 STATISTICS(jniinvokation());
4952 return GetStringChars(env, string, isCopy);
4956 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
4958 STATISTICS(jniinvokation());
4960 ReleaseStringChars(env, string, cstring);
4964 jweak NewWeakGlobalRef(JNIEnv* env, jobject obj)
4966 STATISTICS(jniinvokation());
4968 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
4974 void DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
4976 STATISTICS(jniinvokation());
4978 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
4982 /* NewGlobalRef ****************************************************************
4984 Creates a new global reference to the object referred to by the obj
4987 *******************************************************************************/
4989 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4991 java_objectheader *o;
4992 java_lang_Integer *refcount;
4993 java_objectheader *newval;
4995 STATISTICS(jniinvokation());
4997 #if defined(USE_THREADS)
4998 builtin_monitorenter(*global_ref_table);
5001 o = vm_call_method(getmid, *global_ref_table, lobj);
5003 refcount = (java_lang_Integer *) o;
5005 if (refcount == NULL) {
5006 newval = native_new_and_init_int(class_java_lang_Integer, 1);
5008 if (newval == NULL) {
5009 #if defined(USE_THREADS)
5010 builtin_monitorexit(*global_ref_table);
5015 (void) vm_call_method(putmid, *global_ref_table, lobj, newval);
5018 /* we can access the object itself, as we are in a
5019 synchronized section */
5024 #if defined(USE_THREADS)
5025 builtin_monitorexit(*global_ref_table);
5032 /* DeleteGlobalRef *************************************************************
5034 Deletes the global reference pointed to by globalRef.
5036 *******************************************************************************/
5038 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
5040 java_objectheader *o;
5041 java_lang_Integer *refcount;
5044 STATISTICS(jniinvokation());
5046 #if defined(USE_THREADS)
5047 builtin_monitorenter(*global_ref_table);
5050 o = vm_call_method(getmid, *global_ref_table, globalRef);
5052 refcount = (java_lang_Integer *) o;
5054 if (refcount == NULL) {
5055 log_text("JNI-DeleteGlobalRef: unable to find global reference");
5059 /* we can access the object itself, as we are in a synchronized
5062 val = refcount->value - 1;
5065 (void) vm_call_method(removemid, *global_ref_table, refcount);
5068 /* we do not create a new object, but set the new value into
5071 refcount->value = val;
5074 #if defined(USE_THREADS)
5075 builtin_monitorexit(*global_ref_table);
5080 /* ExceptionCheck **************************************************************
5082 Returns JNI_TRUE when there is a pending exception; otherwise,
5085 *******************************************************************************/
5087 jboolean ExceptionCheck(JNIEnv *env)
5089 STATISTICS(jniinvokation());
5091 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
5095 /* New JNI 1.4 functions ******************************************************/
5097 /* NewDirectByteBuffer *********************************************************
5099 Allocates and returns a direct java.nio.ByteBuffer referring to the
5100 block of memory starting at the memory address address and
5101 extending capacity bytes.
5103 *******************************************************************************/
5105 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
5107 java_objectheader *nbuf;
5108 #if SIZEOF_VOID_P == 8
5109 gnu_classpath_Pointer64 *paddress;
5111 gnu_classpath_Pointer32 *paddress;
5114 STATISTICS(jniinvokation());
5116 /* alocate a gnu.classpath.Pointer{32,64} object */
5118 #if SIZEOF_VOID_P == 8
5119 if (!(paddress = (gnu_classpath_Pointer64 *)
5120 builtin_new(class_gnu_classpath_Pointer64)))
5122 if (!(paddress = (gnu_classpath_Pointer32 *)
5123 builtin_new(class_gnu_classpath_Pointer32)))
5127 /* fill gnu.classpath.Pointer{32,64} with address */
5129 paddress->data = (ptrint) address;
5131 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
5133 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
5134 (jmethodID) dbbirw_init, NULL, paddress,
5135 (jint) capacity, (jint) capacity, (jint) 0);
5137 /* add local reference and return the value */
5139 return NewLocalRef(env, nbuf);
5143 /* GetDirectBufferAddress ******************************************************
5145 Fetches and returns the starting address of the memory region
5146 referenced by the given direct java.nio.Buffer.
5148 *******************************************************************************/
5150 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
5152 java_nio_DirectByteBufferImpl *nbuf;
5153 #if SIZEOF_VOID_P == 8
5154 gnu_classpath_Pointer64 *address;
5156 gnu_classpath_Pointer32 *address;
5159 STATISTICS(jniinvokation());
5161 if (!builtin_instanceof(buf, class_java_nio_Buffer))
5164 nbuf = (java_nio_DirectByteBufferImpl *) buf;
5166 #if SIZEOF_VOID_P == 8
5167 address = (gnu_classpath_Pointer64 *) nbuf->address;
5169 address = (gnu_classpath_Pointer32 *) nbuf->address;
5172 return (void *) address->data;
5176 /* GetDirectBufferCapacity *****************************************************
5178 Fetches and returns the capacity in bytes of the memory region
5179 referenced by the given direct java.nio.Buffer.
5181 *******************************************************************************/
5183 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
5185 java_nio_Buffer *nbuf;
5187 STATISTICS(jniinvokation());
5189 if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
5192 nbuf = (java_nio_Buffer *) buf;
5194 return (jlong) nbuf->cap;
5198 /* DestroyJavaVM ***************************************************************
5200 Unloads a Java VM and reclaims its resources. Only the main thread
5201 can unload the VM. The system waits until the main thread is only
5202 remaining user thread before it destroys the VM.
5204 *******************************************************************************/
5206 jint DestroyJavaVM(JavaVM *vm)
5210 STATISTICS(jniinvokation());
5212 status = vm_destroy(vm);
5218 /* AttachCurrentThread *********************************************************
5220 Attaches the current thread to a Java VM. Returns a JNI interface
5221 pointer in the JNIEnv argument.
5223 Trying to attach a thread that is already attached is a no-op.
5225 A native thread cannot be attached simultaneously to two Java VMs.
5227 When a thread is attached to the VM, the context class loader is
5228 the bootstrap loader.
5230 *******************************************************************************/
5232 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
5234 STATISTICS(jniinvokation());
5236 log_text("JNI-Call: AttachCurrentThread: IMPLEMENT ME!");
5238 #if !defined(HAVE___THREAD)
5239 /* cacao_thread_attach();*/
5241 #error "No idea how to implement that. Perhaps Stefan knows"
5250 jint DetachCurrentThread(JavaVM *vm)
5252 STATISTICS(jniinvokation());
5254 log_text("JNI-Call: DetachCurrentThread: IMPLEMENT ME!");
5260 /* GetEnv **********************************************************************
5262 If the current thread is not attached to the VM, sets *env to NULL,
5263 and returns JNI_EDETACHED. If the specified version is not
5264 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
5265 sets *env to the appropriate interface, and returns JNI_OK.
5267 *******************************************************************************/
5269 jint GetEnv(JavaVM *vm, void **env, jint version)
5271 STATISTICS(jniinvokation());
5273 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
5274 if (thread_getself() == NULL) {
5277 return JNI_EDETACHED;
5281 if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
5282 (version == JNI_VERSION_1_4)) {
5288 #if defined(ENABLE_JVMTI)
5289 if (version == JVMTI_VERSION_1_0) {
5290 *env = (void *) new_jvmtienv();
5299 return JNI_EVERSION;
5304 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
5306 STATISTICS(jniinvokation());
5308 log_text("JNI-Call: AttachCurrentThreadAsDaemon: IMPLEMENT ME!");
5314 /* JNI invocation table *******************************************************/
5316 const struct JNIInvokeInterface _Jv_JNIInvokeInterface = {
5322 AttachCurrentThread,
5323 DetachCurrentThread,
5325 AttachCurrentThreadAsDaemon
5329 /* JNI function table *********************************************************/
5331 struct JNINativeInterface _Jv_JNINativeInterface = {
5340 FromReflectedMethod,
5361 EnsureLocalCapacity,
5404 CallNonvirtualObjectMethod,
5405 CallNonvirtualObjectMethodV,
5406 CallNonvirtualObjectMethodA,
5407 CallNonvirtualBooleanMethod,
5408 CallNonvirtualBooleanMethodV,
5409 CallNonvirtualBooleanMethodA,
5410 CallNonvirtualByteMethod,
5411 CallNonvirtualByteMethodV,
5412 CallNonvirtualByteMethodA,
5413 CallNonvirtualCharMethod,
5414 CallNonvirtualCharMethodV,
5415 CallNonvirtualCharMethodA,
5416 CallNonvirtualShortMethod,
5417 CallNonvirtualShortMethodV,
5418 CallNonvirtualShortMethodA,
5419 CallNonvirtualIntMethod,
5420 CallNonvirtualIntMethodV,
5421 CallNonvirtualIntMethodA,
5422 CallNonvirtualLongMethod,
5423 CallNonvirtualLongMethodV,
5424 CallNonvirtualLongMethodA,
5425 CallNonvirtualFloatMethod,
5426 CallNonvirtualFloatMethodV,
5427 CallNonvirtualFloatMethodA,
5428 CallNonvirtualDoubleMethod,
5429 CallNonvirtualDoubleMethodV,
5430 CallNonvirtualDoubleMethodA,
5431 CallNonvirtualVoidMethod,
5432 CallNonvirtualVoidMethodV,
5433 CallNonvirtualVoidMethodA,
5458 CallStaticObjectMethod,
5459 CallStaticObjectMethodV,
5460 CallStaticObjectMethodA,
5461 CallStaticBooleanMethod,
5462 CallStaticBooleanMethodV,
5463 CallStaticBooleanMethodA,
5464 CallStaticByteMethod,
5465 CallStaticByteMethodV,
5466 CallStaticByteMethodA,
5467 CallStaticCharMethod,
5468 CallStaticCharMethodV,
5469 CallStaticCharMethodA,
5470 CallStaticShortMethod,
5471 CallStaticShortMethodV,
5472 CallStaticShortMethodA,
5473 CallStaticIntMethod,
5474 CallStaticIntMethodV,
5475 CallStaticIntMethodA,
5476 CallStaticLongMethod,
5477 CallStaticLongMethodV,
5478 CallStaticLongMethodA,
5479 CallStaticFloatMethod,
5480 CallStaticFloatMethodV,
5481 CallStaticFloatMethodA,
5482 CallStaticDoubleMethod,
5483 CallStaticDoubleMethodV,
5484 CallStaticDoubleMethodA,
5485 CallStaticVoidMethod,
5486 CallStaticVoidMethodV,
5487 CallStaticVoidMethodA,
5491 GetStaticObjectField,
5492 GetStaticBooleanField,
5495 GetStaticShortField,
5498 GetStaticFloatField,
5499 GetStaticDoubleField,
5500 SetStaticObjectField,
5501 SetStaticBooleanField,
5504 SetStaticShortField,
5507 SetStaticFloatField,
5508 SetStaticDoubleField,
5518 ReleaseStringUTFChars,
5523 GetObjectArrayElement,
5524 SetObjectArrayElement,
5535 GetBooleanArrayElements,
5536 GetByteArrayElements,
5537 GetCharArrayElements,
5538 GetShortArrayElements,
5539 GetIntArrayElements,
5540 GetLongArrayElements,
5541 GetFloatArrayElements,
5542 GetDoubleArrayElements,
5544 ReleaseBooleanArrayElements,
5545 ReleaseByteArrayElements,
5546 ReleaseCharArrayElements,
5547 ReleaseShortArrayElements,
5548 ReleaseIntArrayElements,
5549 ReleaseLongArrayElements,
5550 ReleaseFloatArrayElements,
5551 ReleaseDoubleArrayElements,
5553 GetBooleanArrayRegion,
5556 GetShortArrayRegion,
5559 GetFloatArrayRegion,
5560 GetDoubleArrayRegion,
5561 SetBooleanArrayRegion,
5564 SetShortArrayRegion,
5567 SetFloatArrayRegion,
5568 SetDoubleArrayRegion,
5578 /* new JNI 1.2 functions */
5583 GetPrimitiveArrayCritical,
5584 ReleasePrimitiveArrayCritical,
5587 ReleaseStringCritical,
5590 DeleteWeakGlobalRef,
5594 /* new JNI 1.4 functions */
5596 NewDirectByteBuffer,
5597 GetDirectBufferAddress,
5598 GetDirectBufferCapacity
5602 /* Invocation API Functions ***************************************************/
5604 /* JNI_GetDefaultJavaVMInitArgs ************************************************
5606 Returns a default configuration for the Java VM.
5608 *******************************************************************************/
5610 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
5612 JavaVMInitArgs *_vm_args;
5614 _vm_args = (JavaVMInitArgs *) vm_args;
5616 /* GNU classpath currently supports JNI 1.2 */
5618 switch (_vm_args->version) {
5619 case JNI_VERSION_1_1:
5620 _vm_args->version = JNI_VERSION_1_1;
5623 case JNI_VERSION_1_2:
5624 case JNI_VERSION_1_4:
5625 _vm_args->ignoreUnrecognized = JNI_FALSE;
5626 _vm_args->options = NULL;
5627 _vm_args->nOptions = 0;
5638 /* JNI_GetCreatedJavaVMs *******************************************************
5640 Returns all Java VMs that have been created. Pointers to VMs are written in
5641 the buffer vmBuf in the order they are created. At most bufLen number of
5642 entries will be written. The total number of created VMs is returned in
5645 *******************************************************************************/
5647 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
5649 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
5655 /* JNI_CreateJavaVM ************************************************************
5657 Loads and initializes a Java VM. The current thread becomes the main thread.
5658 Sets the env argument to the JNI interface pointer of the main thread.
5660 *******************************************************************************/
5662 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
5664 JavaVMInitArgs *_vm_args;
5667 localref_table *lrt;
5669 /* get the arguments for the new JVM */
5671 _vm_args = (JavaVMInitArgs *) vm_args;
5673 /* get the VM and Env tables (must be set before vm_create) */
5675 env = NEW(_Jv_JNIEnv);
5676 env->env = &_Jv_JNINativeInterface;
5678 /* XXX Set the global variable. Maybe we should do that differently. */
5682 /* actually create the JVM */
5684 if (!vm_create(_vm_args))
5687 /* create and fill a JavaVM structure */
5689 jvm = NEW(_Jv_JavaVM);
5690 jvm->functions = &_Jv_JNIInvokeInterface;
5692 /* XXX Set the global variable. Maybe we should do that differently. */
5696 /* setup the local ref table (must be created after vm_create) */
5698 lrt = GCNEW(localref_table);
5700 lrt->capacity = LOCALREFTABLE_CAPACITY;
5702 lrt->localframes = 1;
5703 lrt->prev = LOCALREFTABLE;
5705 /* clear the references array (memset is faster then a for-loop) */
5707 MSET(lrt->refs, 0, java_objectheader*, LOCALREFTABLE_CAPACITY);
5709 LOCALREFTABLE = lrt;
5711 /* now return the values */
5713 *p_vm = (JavaVM *) jvm;
5714 *p_env = (void *) env;
5721 * These are local overrides for various environment variables in Emacs.
5722 * Please do not remove this and leave it at the end of the file, where
5723 * Emacs will automagically detect them.
5724 * ---------------------------------------------------------------------
5727 * indent-tabs-mode: t
5731 * vim:noexpandtab:sw=4:ts=4: