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 4559 2006-03-05 23:24:50Z 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 /* pointers to VM and the environment needed by GetJavaVM and GetEnv */
110 static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
111 void *ptr_env = (void*) &JNI_JNIEnvTable;
114 /* global variables ***********************************************************/
116 /* global reference table *****************************************************/
118 static java_objectheader **global_ref_table;
120 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
121 static classinfo *ihmclass = NULL;
122 static methodinfo *putmid = NULL;
123 static methodinfo *getmid = NULL;
124 static methodinfo *removemid = NULL;
127 /* direct buffer stuff ********************************************************/
129 static classinfo *class_java_nio_Buffer;
130 static classinfo *class_java_nio_DirectByteBufferImpl;
131 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
132 #if SIZEOF_VOID_P == 8
133 static classinfo *class_gnu_classpath_Pointer64;
135 static classinfo *class_gnu_classpath_Pointer32;
138 static methodinfo *dbbirw_init;
141 /* local reference table ******************************************************/
143 #if !defined(USE_THREADS)
144 localref_table *_no_threads_localref_table;
148 /* accessing instance fields macros *******************************************/
150 #define SET_FIELD(o,type,f,value) \
151 *((type *) ((ptrint) (o) + (ptrint) ((fieldinfo *) (f))->offset)) = (type) (value)
153 #define GET_FIELD(o,type,f) \
154 *((type *) ((ptrint) (o) + (ptrint) ((fieldinfo *) (f))->offset))
157 /* some forward declarations **************************************************/
159 jobject NewLocalRef(JNIEnv *env, jobject ref);
162 /* jni_init ********************************************************************
164 Initialize the JNI subsystem.
166 *******************************************************************************/
170 /* initalize global reference table */
173 load_class_bootstrap(utf_new_char("java/util/IdentityHashMap"))))
176 global_ref_table = GCNEW(jobject);
178 if (!(*global_ref_table = native_new_and_init(ihmclass)))
181 if (!(getmid = class_resolvemethod(ihmclass, utf_get,
182 utf_java_lang_Object__java_lang_Object)))
185 if (!(putmid = class_resolvemethod(ihmclass, utf_put,
186 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))))
190 class_resolvemethod(ihmclass, utf_remove,
191 utf_java_lang_Object__java_lang_Object)))
195 /* direct buffer stuff */
197 if (!(class_java_nio_Buffer =
198 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
199 !link_class(class_java_nio_Buffer))
202 if (!(class_java_nio_DirectByteBufferImpl =
203 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
204 !link_class(class_java_nio_DirectByteBufferImpl))
207 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
208 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
209 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
213 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
215 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
218 #if SIZEOF_VOID_P == 8
219 if (!(class_gnu_classpath_Pointer64 =
220 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
221 !link_class(class_gnu_classpath_Pointer64))
224 if (!(class_gnu_classpath_Pointer32 =
225 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
226 !link_class(class_gnu_classpath_Pointer32))
234 /* _Jv_jni_vmargs_from_objectarray *********************************************
238 *******************************************************************************/
240 static bool _Jv_jni_vmargs_from_objectarray(java_objectheader *o,
243 java_objectarray *params)
245 java_objectheader *param;
247 typedesc *paramtypes;
252 paramcount = descr->paramcount;
253 paramtypes = descr->paramtypes;
255 /* if method is non-static fill first block and skip `this' pointer */
261 vmargs[0].type = TYPE_ADR;
262 vmargs[0].data = (u8) (ptrint) o;
269 for (j = 0; j < paramcount; i++, j++, paramtypes++) {
270 switch (paramtypes->type) {
271 /* primitive types */
276 param = params->data[j];
281 /* internally used data type */
282 vmargs[i].type = paramtypes->type;
284 /* convert the value according to its declared type */
286 c = param->vftbl->class;
288 switch (paramtypes->decltype) {
289 case PRIMITIVETYPE_BOOLEAN:
290 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
291 vmargs[i].data = (s8) ((java_lang_Boolean *) param)->value;
296 case PRIMITIVETYPE_BYTE:
297 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
298 vmargs[i].data = (s8) ((java_lang_Byte *) param)->value;
303 case PRIMITIVETYPE_CHAR:
304 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
305 vmargs[i].data = (s8) ((java_lang_Character *) param)->value;
310 case PRIMITIVETYPE_SHORT:
311 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
312 vmargs[i].data = (s8) ((java_lang_Short *) param)->value;
313 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
314 vmargs[i].data = (s8) ((java_lang_Byte *) param)->value;
319 case PRIMITIVETYPE_INT:
320 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
321 vmargs[i].data = (s8) ((java_lang_Integer *) param)->value;
322 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
323 vmargs[i].data = (s8) ((java_lang_Short *) param)->value;
324 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
325 vmargs[i].data = (s8) ((java_lang_Byte *) param)->value;
330 case PRIMITIVETYPE_LONG:
331 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
332 vmargs[i].data = (s8) ((java_lang_Long *) param)->value;
333 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
334 vmargs[i].data = (s8) ((java_lang_Integer *) param)->value;
335 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
336 vmargs[i].data = (s8) ((java_lang_Short *) param)->value;
337 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
338 vmargs[i].data = (s8) ((java_lang_Byte *) param)->value;
343 case PRIMITIVETYPE_FLOAT:
344 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
345 *((jfloat *) (&vmargs[i].data)) = (jfloat) ((java_lang_Float *) param)->value;
350 case PRIMITIVETYPE_DOUBLE:
351 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
352 *((jdouble *) (&vmargs[i].data)) = (jdouble) ((java_lang_Double *) param)->value;
353 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
354 *((jfloat *) (&vmargs[i].data)) = (jfloat) ((java_lang_Float *) param)->value;
365 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
368 if (params->data[j] != 0) {
369 if (paramtypes->arraydim > 0) {
370 if (!builtin_arrayinstanceof(params->data[j], c))
374 if (!builtin_instanceof(params->data[j], c))
378 vmargs[i].type = TYPE_ADR;
379 vmargs[i].data = (u8) (ptrint) params->data[j];
388 /* *rettype = descr->returntype.decltype; */
393 exceptions_throw_illegalargumentexception();
398 /* _Jv_jni_CallObjectMethod ****************************************************
400 Internal function to call Java Object methods.
402 *******************************************************************************/
404 static java_objectheader *_Jv_jni_CallObjectMethod(java_objectheader *o,
406 methodinfo *m, va_list ap)
409 java_objectheader *ro;
411 STATISTICS(jniinvokation());
414 exceptions_throw_nullpointerexception();
418 /* Class initialization is done by the JIT compiler. This is ok
419 since a static method always belongs to the declaring class. */
421 if (m->flags & ACC_STATIC) {
422 /* For static methods we reset the object. */
427 /* for convenience */
432 /* For instance methods we make a virtual function table lookup. */
434 resm = method_vftbl_lookup(vftbl, m);
437 STATISTICS(jnicallXmethodnvokation());
439 ro = vm_call_method_valist(resm, o, ap);
445 /* _Jv_jni_CallObjectMethodA ***************************************************
447 Internal function to call Java Object methods.
449 *******************************************************************************/
451 static java_objectheader *_Jv_jni_CallObjectMethodA(java_objectheader *o,
453 methodinfo *m, jvalue *args)
456 java_objectheader *ro;
458 STATISTICS(jniinvokation());
461 exceptions_throw_nullpointerexception();
465 /* Class initialization is done by the JIT compiler. This is ok
466 since a static method always belongs to the declaring class. */
468 if (m->flags & ACC_STATIC) {
469 /* For static methods we reset the object. */
474 /* for convenience */
479 /* For instance methods we make a virtual function table lookup. */
481 resm = method_vftbl_lookup(vftbl, m);
484 STATISTICS(jnicallXmethodnvokation());
486 ro = vm_call_method_jvalue(resm, o, args);
492 /* _Jv_jni_CallIntMethod *******************************************************
494 Internal function to call Java integer class methods (boolean,
495 byte, char, short, int).
497 *******************************************************************************/
499 static jint _Jv_jni_CallIntMethod(java_objectheader *o, vftbl_t *vftbl,
500 methodinfo *m, va_list ap)
505 STATISTICS(jniinvokation());
508 exceptions_throw_nullpointerexception();
512 /* Class initialization is done by the JIT compiler. This is ok
513 since a static method always belongs to the declaring class. */
515 if (m->flags & ACC_STATIC) {
516 /* For static methods we reset the object. */
521 /* for convenience */
526 /* For instance methods we make a virtual function table lookup. */
528 resm = method_vftbl_lookup(vftbl, m);
531 STATISTICS(jnicallXmethodnvokation());
533 i = vm_call_method_int_valist(resm, o, ap);
539 /* _Jv_jni_CallLongMethod ******************************************************
541 Internal function to call Java long methods.
543 *******************************************************************************/
545 static jlong _Jv_jni_CallLongMethod(java_objectheader *o, vftbl_t *vftbl,
546 methodinfo *m, va_list ap)
551 STATISTICS(jniinvokation());
554 exceptions_throw_nullpointerexception();
558 /* Class initialization is done by the JIT compiler. This is ok
559 since a static method always belongs to the declaring class. */
561 if (m->flags & ACC_STATIC) {
562 /* For static methods we reset the object. */
567 /* for convenience */
572 /* For instance methods we make a virtual function table lookup. */
574 resm = method_vftbl_lookup(vftbl, m);
577 STATISTICS(jnicallXmethodnvokation());
579 l = vm_call_method_long_valist(resm, o, ap);
585 /* _Jv_jni_CallFloatMethod *****************************************************
587 Internal function to call Java float methods.
589 *******************************************************************************/
591 static jfloat _Jv_jni_CallFloatMethod(java_objectheader *o, vftbl_t *vftbl,
592 methodinfo *m, va_list ap)
597 /* Class initialization is done by the JIT compiler. This is ok
598 since a static method always belongs to the declaring class. */
600 if (m->flags & ACC_STATIC) {
601 /* For static methods we reset the object. */
606 /* for convenience */
611 /* For instance methods we make a virtual function table lookup. */
613 resm = method_vftbl_lookup(vftbl, m);
616 STATISTICS(jnicallXmethodnvokation());
618 f = vm_call_method_float_valist(resm, o, ap);
624 /* _Jv_jni_CallDoubleMethod ****************************************************
626 Internal function to call Java double methods.
628 *******************************************************************************/
630 static jdouble _Jv_jni_CallDoubleMethod(java_objectheader *o, vftbl_t *vftbl,
631 methodinfo *m, va_list ap)
636 /* Class initialization is done by the JIT compiler. This is ok
637 since a static method always belongs to the declaring class. */
639 if (m->flags & ACC_STATIC) {
640 /* For static methods we reset the object. */
645 /* for convenience */
650 /* For instance methods we make a virtual function table lookup. */
652 resm = method_vftbl_lookup(vftbl, m);
655 d = vm_call_method_double_valist(resm, o, ap);
661 /* _Jv_jni_CallVoidMethod ******************************************************
663 Internal function to call Java void methods.
665 *******************************************************************************/
667 static void _Jv_jni_CallVoidMethod(java_objectheader *o, vftbl_t *vftbl,
668 methodinfo *m, va_list ap)
673 exceptions_throw_nullpointerexception();
677 /* Class initialization is done by the JIT compiler. This is ok
678 since a static method always belongs to the declaring class. */
680 if (m->flags & ACC_STATIC) {
681 /* For static methods we reset the object. */
686 /* for convenience */
691 /* For instance methods we make a virtual function table lookup. */
693 resm = method_vftbl_lookup(vftbl, m);
696 STATISTICS(jnicallXmethodnvokation());
698 (void) vm_call_method_valist(resm, o, ap);
702 /* _Jv_jni_CallVoidMethodA *****************************************************
704 Internal function to call Java void methods.
706 *******************************************************************************/
708 static void _Jv_jni_CallVoidMethodA(java_objectheader *o, vftbl_t *vftbl,
709 methodinfo *m, jvalue *args)
714 exceptions_throw_nullpointerexception();
718 /* Class initialization is done by the JIT compiler. This is ok
719 since a static method always belongs to the declaring class. */
721 if (m->flags & ACC_STATIC) {
722 /* For static methods we reset the object. */
727 /* for convenience */
732 /* For instance methods we make a virtual function table lookup. */
734 resm = method_vftbl_lookup(vftbl, m);
737 STATISTICS(jnicallXmethodnvokation());
739 (void) vm_call_method_jvalue(resm, o, args);
743 /* _Jv_jni_invokeNative ********************************************************
745 Invoke a method on the given object with the given arguments.
747 For instance methods OBJ must be != NULL and the method is looked up
748 in the vftbl of the object.
750 For static methods, OBJ is ignored.
752 *******************************************************************************/
754 java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
755 java_objectarray *params)
759 java_objectheader *ro;
764 exceptions_throw_nullpointerexception();
768 argcount = m->parseddesc->paramcount;
769 paramcount = argcount;
771 /* if method is non-static, remove the `this' pointer */
773 if (!(m->flags & ACC_STATIC))
776 /* For instance methods the object has to be an instance of the
777 class the method belongs to. For static methods the obj
778 parameter is ignored. */
780 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
782 new_exception_message(string_java_lang_IllegalArgumentException,
783 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
787 /* check if we got the right number of arguments */
789 if (((params == NULL) && (paramcount != 0)) ||
790 (params && (params->header.size != paramcount)))
793 new_exception(string_java_lang_IllegalArgumentException);
797 /* for instance methods we need an object */
799 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
801 new_exception_message(string_java_lang_NullPointerException,
802 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
806 /* for static methods, zero object to make subsequent code simpler */
807 if (m->flags & ACC_STATIC)
811 /* for instance methods we must do a vftbl lookup */
812 resm = method_vftbl_lookup(o->vftbl, m);
815 /* for static methods, just for convenience */
819 vmargs = MNEW(vm_arg, argcount);
821 if (!_Jv_jni_vmargs_from_objectarray(o, resm->parseddesc, vmargs, params))
824 switch (resm->parseddesc->returntype.decltype) {
826 (void) vm_call_method_vmarg(resm, argcount, vmargs);
831 case PRIMITIVETYPE_BOOLEAN: {
833 java_lang_Boolean *bo;
835 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
837 ro = builtin_new(class_java_lang_Boolean);
839 /* setting the value of the object direct */
841 bo = (java_lang_Boolean *) ro;
846 case PRIMITIVETYPE_BYTE: {
850 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
852 ro = builtin_new(class_java_lang_Byte);
854 /* setting the value of the object direct */
856 bo = (java_lang_Byte *) ro;
861 case PRIMITIVETYPE_CHAR: {
863 java_lang_Character *co;
865 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
867 ro = builtin_new(class_java_lang_Character);
869 /* setting the value of the object direct */
871 co = (java_lang_Character *) ro;
876 case PRIMITIVETYPE_SHORT: {
880 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
882 ro = builtin_new(class_java_lang_Short);
884 /* setting the value of the object direct */
886 so = (java_lang_Short *) ro;
891 case PRIMITIVETYPE_INT: {
893 java_lang_Integer *io;
895 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
897 ro = builtin_new(class_java_lang_Integer);
899 /* setting the value of the object direct */
901 io = (java_lang_Integer *) ro;
906 case PRIMITIVETYPE_LONG: {
910 l = vm_call_method_long_vmarg(resm, argcount, vmargs);
912 ro = builtin_new(class_java_lang_Long);
914 /* setting the value of the object direct */
916 lo = (java_lang_Long *) ro;
921 case PRIMITIVETYPE_FLOAT: {
925 f = vm_call_method_float_vmarg(resm, argcount, vmargs);
927 ro = builtin_new(class_java_lang_Float);
929 /* setting the value of the object direct */
931 fo = (java_lang_Float *) ro;
936 case PRIMITIVETYPE_DOUBLE: {
938 java_lang_Double *_do;
940 d = vm_call_method_double_vmarg(resm, argcount, vmargs);
942 ro = builtin_new(class_java_lang_Double);
944 /* setting the value of the object direct */
946 _do = (java_lang_Double *) ro;
952 ro = vm_call_method_vmarg(resm, argcount, vmargs);
956 /* if this happens the exception has already been set by
957 fill_callblock_from_objectarray */
959 MFREE(vmargs, vm_arg, argcount);
964 MFREE(vmargs, vm_arg, argcount);
967 java_objectheader *cause;
969 cause = *exceptionptr;
971 /* clear exception pointer, we are calling JIT code again */
973 *exceptionptr = NULL;
976 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
977 (java_lang_Throwable *) cause);
984 /* GetVersion ******************************************************************
986 Returns the major version number in the higher 16 bits and the
987 minor version number in the lower 16 bits.
989 *******************************************************************************/
991 jint GetVersion(JNIEnv *env)
993 STATISTICS(jniinvokation());
995 /* we support JNI 1.4 */
997 return JNI_VERSION_1_4;
1001 /* Class Operations ***********************************************************/
1003 /* DefineClass *****************************************************************
1005 Loads a class from a buffer of raw class data. The buffer
1006 containing the raw class data is not referenced by the VM after the
1007 DefineClass call returns, and it may be discarded if desired.
1009 *******************************************************************************/
1011 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
1012 const jbyte *buf, jsize bufLen)
1014 java_lang_ClassLoader *cl;
1015 java_lang_String *s;
1019 STATISTICS(jniinvokation());
1021 cl = (java_lang_ClassLoader *) loader;
1022 s = javastring_new_char(name);
1023 ba = (java_bytearray *) buf;
1025 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
1028 return (jclass) NewLocalRef(env, (jobject) c);
1032 /* FindClass *******************************************************************
1034 This function loads a locally-defined class. It searches the
1035 directories and zip files specified by the CLASSPATH environment
1036 variable for the class with the specified name.
1038 *******************************************************************************/
1040 jclass FindClass(JNIEnv *env, const char *name)
1046 STATISTICS(jniinvokation());
1048 u = utf_new_char_classname((char *) name);
1050 /* Check stacktrace for classloader, if one found use it,
1051 otherwise use the system classloader. */
1053 /* Quote from the JNI documentation:
1055 In the Java 2 Platform, FindClass locates the class loader
1056 associated with the current native method. If the native code
1057 belongs to a system class, no class loader will be
1058 involved. Otherwise, the proper class loader will be invoked to
1059 load and link the named class. When FindClass is called through
1060 the Invocation Interface, there is no current native method or
1061 its associated class loader. In that case, the result of
1062 ClassLoader.getBaseClassLoader is used." */
1064 #if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__)
1065 /* these JITs support stacktraces, and so does the interpreter */
1067 cc = stacktrace_getCurrentClass();
1069 # if defined(ENABLE_INTRP)
1070 /* the interpreter supports stacktraces, even if the JIT does not */
1073 cc = stacktrace_getCurrentClass();
1079 /* if no Java method was found, use the system classloader */
1082 c = load_class_from_sysloader(u);
1084 c = load_class_from_classloader(u, cc->classloader);
1092 return (jclass) NewLocalRef(env, (jobject) c);
1096 /* GetSuperclass ***************************************************************
1098 If clazz represents any class other than the class Object, then
1099 this function returns the object that represents the superclass of
1100 the class specified by clazz.
1102 *******************************************************************************/
1104 jclass GetSuperclass(JNIEnv *env, jclass sub)
1108 STATISTICS(jniinvokation());
1110 c = ((classinfo *) sub)->super.cls;
1115 return (jclass) NewLocalRef(env, (jobject) c);
1119 /* IsAssignableFrom ************************************************************
1121 Determines whether an object of sub can be safely cast to sup.
1123 *******************************************************************************/
1125 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1127 STATISTICS(jniinvokation());
1129 return Java_java_lang_VMClass_isAssignableFrom(env,
1131 (java_lang_Class *) sup,
1132 (java_lang_Class *) sub);
1136 /* Throw ***********************************************************************
1138 Causes a java.lang.Throwable object to be thrown.
1140 *******************************************************************************/
1142 jint Throw(JNIEnv *env, jthrowable obj)
1144 STATISTICS(jniinvokation());
1146 *exceptionptr = (java_objectheader *) obj;
1152 /* ThrowNew ********************************************************************
1154 Constructs an exception object from the specified class with the
1155 message specified by message and causes that exception to be
1158 *******************************************************************************/
1160 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1162 java_lang_Throwable *o;
1163 java_lang_String *s;
1165 STATISTICS(jniinvokation());
1167 s = (java_lang_String *) javastring_new_char(msg);
1169 /* instantiate exception object */
1171 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
1177 *exceptionptr = (java_objectheader *) o;
1183 /* ExceptionOccurred ***********************************************************
1185 Determines if an exception is being thrown. The exception stays
1186 being thrown until either the native code calls ExceptionClear(),
1187 or the Java code handles the exception.
1189 *******************************************************************************/
1191 jthrowable ExceptionOccurred(JNIEnv *env)
1193 java_objectheader *e;
1195 STATISTICS(jniinvokation());
1199 return NewLocalRef(env, (jthrowable) e);
1203 /* ExceptionDescribe ***********************************************************
1205 Prints an exception and a backtrace of the stack to a system
1206 error-reporting channel, such as stderr. This is a convenience
1207 routine provided for debugging.
1209 *******************************************************************************/
1211 void ExceptionDescribe(JNIEnv *env)
1213 java_objectheader *e;
1216 STATISTICS(jniinvokation());
1221 /* clear exception, because we are calling jit code again */
1223 *exceptionptr = NULL;
1225 /* get printStackTrace method from exception class */
1227 m = class_resolveclassmethod(e->vftbl->class,
1228 utf_printStackTrace,
1234 /* XXX what should we do? */
1237 /* print the stacktrace */
1239 (void) vm_call_method(m, e);
1244 /* ExceptionClear **************************************************************
1246 Clears any exception that is currently being thrown. If no
1247 exception is currently being thrown, this routine has no effect.
1249 *******************************************************************************/
1251 void ExceptionClear(JNIEnv *env)
1253 STATISTICS(jniinvokation());
1255 *exceptionptr = NULL;
1259 /* FatalError ******************************************************************
1261 Raises a fatal error and does not expect the VM to recover. This
1262 function does not return.
1264 *******************************************************************************/
1266 void FatalError(JNIEnv *env, const char *msg)
1268 STATISTICS(jniinvokation());
1270 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
1274 /* PushLocalFrame **************************************************************
1276 Creates a new local reference frame, in which at least a given
1277 number of local references can be created.
1279 *******************************************************************************/
1281 jint PushLocalFrame(JNIEnv* env, jint capacity)
1283 STATISTICS(jniinvokation());
1285 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
1292 /* PopLocalFrame ***************************************************************
1294 Pops off the current local reference frame, frees all the local
1295 references, and returns a local reference in the previous local
1296 reference frame for the given result object.
1298 *******************************************************************************/
1300 jobject PopLocalFrame(JNIEnv* env, jobject result)
1302 STATISTICS(jniinvokation());
1304 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
1308 /* add local reference and return the value */
1310 return NewLocalRef(env, NULL);
1314 /* DeleteLocalRef **************************************************************
1316 Deletes the local reference pointed to by localRef.
1318 *******************************************************************************/
1320 void DeleteLocalRef(JNIEnv *env, jobject localRef)
1322 java_objectheader *o;
1323 localref_table *lrt;
1326 STATISTICS(jniinvokation());
1328 o = (java_objectheader *) localRef;
1330 /* get local reference table (thread specific) */
1332 lrt = LOCALREFTABLE;
1334 /* remove the reference */
1336 for (i = 0; i < lrt->capacity; i++) {
1337 if (lrt->refs[i] == o) {
1338 lrt->refs[i] = NULL;
1345 /* this should not happen */
1347 /* if (opt_checkjni) */
1348 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1349 log_text("JNI-DeleteLocalRef: Bad global or local ref passed to JNI");
1353 /* IsSameObject ****************************************************************
1355 Tests whether two references refer to the same Java object.
1357 *******************************************************************************/
1359 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1361 STATISTICS(jniinvokation());
1370 /* NewLocalRef *****************************************************************
1372 Creates a new local reference that refers to the same object as ref.
1374 *******************************************************************************/
1376 jobject NewLocalRef(JNIEnv *env, jobject ref)
1378 localref_table *lrt;
1381 STATISTICS(jniinvokation());
1386 /* get local reference table (thread specific) */
1388 lrt = LOCALREFTABLE;
1390 /* check if we have space for the requested reference */
1392 if (lrt->used == lrt->capacity) {
1393 /* throw_cacao_exception_exit(string_java_lang_InternalError, */
1394 /* "Too many local references"); */
1395 fprintf(stderr, "Too many local references");
1399 /* insert the reference */
1401 for (i = 0; i < lrt->capacity; i++) {
1402 if (lrt->refs[i] == NULL) {
1403 lrt->refs[i] = (java_objectheader *) ref;
1410 /* should not happen, just to be sure */
1414 /* keep compiler happy */
1420 /* EnsureLocalCapacity *********************************************************
1422 Ensures that at least a given number of local references can be
1423 created in the current thread
1425 *******************************************************************************/
1427 jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
1429 localref_table *lrt;
1431 STATISTICS(jniinvokation());
1433 /* get local reference table (thread specific) */
1435 lrt = LOCALREFTABLE;
1437 /* check if capacity elements are available in the local references table */
1439 if ((lrt->used + capacity) > lrt->capacity) {
1440 *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
1448 /* AllocObject *****************************************************************
1450 Allocates a new Java object without invoking any of the
1451 constructors for the object. Returns a reference to the object.
1453 *******************************************************************************/
1455 jobject AllocObject(JNIEnv *env, jclass clazz)
1458 java_objectheader *o;
1460 STATISTICS(jniinvokation());
1462 c = (classinfo *) clazz;
1464 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1466 new_exception_utfmessage(string_java_lang_InstantiationException,
1473 return NewLocalRef(env, o);
1477 /* NewObject *******************************************************************
1479 Programmers place all arguments that are to be passed to the
1480 constructor immediately following the methodID
1481 argument. NewObject() accepts these arguments and passes them to
1482 the Java method that the programmer wishes to invoke.
1484 *******************************************************************************/
1486 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1488 java_objectheader *o;
1492 STATISTICS(jniinvokation());
1494 m = (methodinfo *) methodID;
1498 o = builtin_new(clazz);
1503 /* call constructor */
1505 va_start(ap, methodID);
1506 _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
1509 return NewLocalRef(env, o);
1513 /* NewObjectV ******************************************************************
1515 Programmers place all arguments that are to be passed to the
1516 constructor in an args argument of type va_list that immediately
1517 follows the methodID argument. NewObjectV() accepts these
1518 arguments, and, in turn, passes them to the Java method that the
1519 programmer wishes to invoke.
1521 *******************************************************************************/
1523 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1525 java_objectheader *o;
1528 STATISTICS(jniinvokation());
1530 m = (methodinfo *) methodID;
1534 o = builtin_new(clazz);
1539 /* call constructor */
1541 _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
1543 return NewLocalRef(env, o);
1547 /* NewObjectA *****************************************************************
1549 Programmers place all arguments that are to be passed to the
1550 constructor in an args array of jvalues that immediately follows
1551 the methodID argument. NewObjectA() accepts the arguments in this
1552 array, and, in turn, passes them to the Java method that the
1553 programmer wishes to invoke.
1555 *******************************************************************************/
1557 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1559 java_objectheader *o;
1562 STATISTICS(jniinvokation());
1564 m = (methodinfo *) methodID;
1568 o = builtin_new(clazz);
1573 /* call constructor */
1575 _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
1577 return NewLocalRef(env, o);
1581 /* GetObjectClass **************************************************************
1583 Returns the class of an object.
1585 *******************************************************************************/
1587 jclass GetObjectClass(JNIEnv *env, jobject obj)
1589 java_objectheader *o;
1592 STATISTICS(jniinvokation());
1594 o = (java_objectheader *) obj;
1596 if ((o == NULL) || (o->vftbl == NULL))
1599 c = o->vftbl->class;
1601 return (jclass) NewLocalRef(env, (jobject) c);
1605 /* IsInstanceOf ****************************************************************
1607 Tests whether an object is an instance of a class.
1609 *******************************************************************************/
1611 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1613 STATISTICS(jniinvokation());
1615 return Java_java_lang_VMClass_isInstance(env,
1617 (java_lang_Class *) clazz,
1618 (java_lang_Object *) obj);
1622 /* Reflection Support *********************************************************/
1624 /* FromReflectedMethod *********************************************************
1626 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1627 object to a method ID.
1629 *******************************************************************************/
1631 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
1637 STATISTICS(jniinvokation());
1642 if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
1643 java_lang_reflect_Method *rm;
1645 rm = (java_lang_reflect_Method *) method;
1646 c = (classinfo *) (rm->declaringClass);
1649 } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
1650 java_lang_reflect_Constructor *rc;
1652 rc = (java_lang_reflect_Constructor *) method;
1653 c = (classinfo *) (rc->clazz);
1659 mi = &(c->methods[slot]);
1661 return (jmethodID) mi;
1665 /* FromReflectedField **********************************************************
1667 Converts a java.lang.reflect.Field to a field ID.
1669 *******************************************************************************/
1671 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1673 java_lang_reflect_Field *rf;
1677 STATISTICS(jniinvokation());
1679 rf = (java_lang_reflect_Field *) field;
1684 c = (classinfo *) rf->declaringClass;
1686 f = &(c->fields[rf->slot]);
1688 return (jfieldID) f;
1692 /* ToReflectedMethod ***********************************************************
1694 Converts a method ID derived from cls to an instance of the
1695 java.lang.reflect.Method class or to an instance of the
1696 java.lang.reflect.Constructor class.
1698 *******************************************************************************/
1700 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1702 STATISTICS(jniinvokation());
1704 log_text("JNI-Call: ToReflectedMethod: IMPLEMENT ME!");
1710 /* ToReflectedField ************************************************************
1712 Converts a field ID derived from cls to an instance of the
1713 java.lang.reflect.Field class.
1715 *******************************************************************************/
1717 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1720 STATISTICS(jniinvokation());
1722 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1728 /* Calling Instance Methods ***************************************************/
1730 /* GetMethodID *****************************************************************
1732 Returns the method ID for an instance (nonstatic) method of a class
1733 or interface. The method may be defined in one of the clazz's
1734 superclasses and inherited by clazz. The method is determined by
1735 its name and signature.
1737 GetMethodID() causes an uninitialized class to be initialized.
1739 *******************************************************************************/
1741 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1749 STATISTICS(jniinvokation());
1751 c = (classinfo *) clazz;
1756 if (!(c->state & CLASS_INITIALIZED))
1757 if (!initialize_class(c))
1760 /* try to get the method of the class or one of it's superclasses */
1762 uname = utf_new_char((char *) name);
1763 udesc = utf_new_char((char *) sig);
1765 m = class_resolvemethod(clazz, uname, udesc);
1767 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1768 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1773 return (jmethodID) m;
1777 /* JNI-functions for calling instance methods *********************************/
1779 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1781 java_objectheader *o;
1783 java_objectheader *ret;
1786 o = (java_objectheader *) obj;
1787 m = (methodinfo *) methodID;
1789 va_start(ap, methodID);
1790 ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, ap);
1793 return NewLocalRef(env, ret);
1797 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1799 java_objectheader *o;
1801 java_objectheader *ret;
1803 o = (java_objectheader *) obj;
1804 m = (methodinfo *) methodID;
1806 ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, args);
1808 return NewLocalRef(env, ret);
1812 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1814 java_objectheader *o;
1816 java_objectheader *ret;
1818 o = (java_objectheader *) obj;
1819 m = (methodinfo *) methodID;
1821 ret = _Jv_jni_CallObjectMethodA(o, o->vftbl, m, args);
1823 return NewLocalRef(env, ret);
1827 jboolean CallBooleanMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1829 java_objectheader *o;
1834 o = (java_objectheader *) obj;
1835 m = (methodinfo *) methodID;
1837 va_start(ap, methodID);
1838 b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
1845 jboolean CallBooleanMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1847 java_objectheader *o;
1851 o = (java_objectheader *) obj;
1852 m = (methodinfo *) methodID;
1854 b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
1860 jboolean CallBooleanMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1862 log_text("JNI-Call: CallBooleanMethodA");
1868 jbyte CallByteMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1870 java_objectheader *o;
1875 o = (java_objectheader *) obj;
1876 m = (methodinfo *) methodID;
1878 va_start(ap, methodID);
1879 b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
1886 jbyte CallByteMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1888 java_objectheader *o;
1892 o = (java_objectheader *) obj;
1893 m = (methodinfo *) methodID;
1895 b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
1901 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1903 log_text("JNI-Call: CallByteMethodA: IMPLEMENT ME!");
1909 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1911 java_objectheader *o;
1916 o = (java_objectheader *) obj;
1917 m = (methodinfo *) methodID;
1919 va_start(ap, methodID);
1920 c = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
1927 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1929 java_objectheader *o;
1933 o = (java_objectheader *) obj;
1934 m = (methodinfo *) methodID;
1936 c = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
1942 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1944 log_text("JNI-Call: CallCharMethodA: IMPLEMENT ME!");
1950 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1952 java_objectheader *o;
1957 o = (java_objectheader *) obj;
1958 m = (methodinfo *) methodID;
1960 va_start(ap, methodID);
1961 s = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
1968 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1970 java_objectheader *o;
1974 o = (java_objectheader *) obj;
1975 m = (methodinfo *) methodID;
1977 s = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
1983 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1985 log_text("JNI-Call: CallShortMethodA: IMPLEMENT ME!");
1992 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1994 java_objectheader *o;
1999 o = (java_objectheader *) obj;
2000 m = (methodinfo *) methodID;
2002 va_start(ap, methodID);
2003 i = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2010 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2012 java_objectheader *o;
2016 o = (java_objectheader *) obj;
2017 m = (methodinfo *) methodID;
2019 i = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2025 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2027 log_text("JNI-Call: CallIntMethodA: IMPLEMENT ME!");
2034 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2036 java_objectheader *o;
2041 o = (java_objectheader *) obj;
2042 m = (methodinfo *) methodID;
2044 va_start(ap, methodID);
2045 l = _Jv_jni_CallLongMethod(o, o->vftbl, m, ap);
2052 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2054 java_objectheader *o;
2058 o = (java_objectheader *) obj;
2059 m = (methodinfo *) methodID;
2061 l = _Jv_jni_CallLongMethod(o, o->vftbl, m, args);
2067 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2069 log_text("JNI-Call: CallLongMethodA: IMPLEMENT ME!");
2076 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2078 java_objectheader *o;
2083 o = (java_objectheader *) obj;
2084 m = (methodinfo *) methodID;
2086 va_start(ap, methodID);
2087 f = _Jv_jni_CallFloatMethod(o, o->vftbl, m, ap);
2094 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2096 java_objectheader *o;
2100 o = (java_objectheader *) obj;
2101 m = (methodinfo *) methodID;
2103 f = _Jv_jni_CallFloatMethod(o, o->vftbl, m, args);
2109 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2111 log_text("JNI-Call: CallFloatMethodA: IMPLEMENT ME!");
2118 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2120 java_objectheader *o;
2125 o = (java_objectheader *) obj;
2126 m = (methodinfo *) methodID;
2128 va_start(ap, methodID);
2129 d = _Jv_jni_CallDoubleMethod(o, o->vftbl, m, ap);
2136 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2138 java_objectheader *o;
2142 o = (java_objectheader *) obj;
2143 m = (methodinfo *) methodID;
2145 d = _Jv_jni_CallDoubleMethod(o, o->vftbl, m, args);
2151 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2153 log_text("JNI-Call: CallDoubleMethodA: IMPLEMENT ME!");
2160 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2162 java_objectheader *o;
2166 o = (java_objectheader *) obj;
2167 m = (methodinfo *) methodID;
2169 va_start(ap, methodID);
2170 _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
2175 void CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2177 java_objectheader *o;
2180 o = (java_objectheader *) obj;
2181 m = (methodinfo *) methodID;
2183 _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
2187 void CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2189 java_objectheader *o;
2192 o = (java_objectheader *) obj;
2193 m = (methodinfo *) methodID;
2195 _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
2200 jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2202 java_objectheader *o;
2205 java_objectheader *r;
2208 o = (java_objectheader *) obj;
2209 c = (classinfo *) clazz;
2210 m = (methodinfo *) methodID;
2212 va_start(ap, methodID);
2213 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2216 return NewLocalRef(env, r);
2220 jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2222 java_objectheader *o;
2225 java_objectheader *r;
2227 o = (java_objectheader *) obj;
2228 c = (classinfo *) clazz;
2229 m = (methodinfo *) methodID;
2231 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2233 return NewLocalRef(env, r);
2237 jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2239 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2241 return NewLocalRef(env, NULL);
2246 jboolean CallNonvirtualBooleanMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2248 java_objectheader *o;
2254 o = (java_objectheader *) obj;
2255 c = (classinfo *) clazz;
2256 m = (methodinfo *) methodID;
2258 va_start(ap, methodID);
2259 b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2266 jboolean CallNonvirtualBooleanMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2268 java_objectheader *o;
2273 o = (java_objectheader *) obj;
2274 c = (classinfo *) clazz;
2275 m = (methodinfo *) methodID;
2277 b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2283 jboolean CallNonvirtualBooleanMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2285 log_text("JNI-Call: CallNonvirtualBooleanMethodA: IMPLEMENT ME!");
2291 jbyte CallNonvirtualByteMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2293 java_objectheader *o;
2299 o = (java_objectheader *) obj;
2300 c = (classinfo *) clazz;
2301 m = (methodinfo *) methodID;
2303 va_start(ap, methodID);
2304 b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2311 jbyte CallNonvirtualByteMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2313 java_objectheader *o;
2318 o = (java_objectheader *) obj;
2319 c = (classinfo *) clazz;
2320 m = (methodinfo *) methodID;
2322 b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2328 jbyte CallNonvirtualByteMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2330 log_text("JNI-Call: CallNonvirtualByteMethodA: IMPLEMENT ME!");
2337 jchar CallNonvirtualCharMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2339 java_objectheader *o;
2345 o = (java_objectheader *) obj;
2346 c = (classinfo *) clazz;
2347 m = (methodinfo *) methodID;
2349 va_start(ap, methodID);
2350 ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2357 jchar CallNonvirtualCharMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2359 java_objectheader *o;
2364 o = (java_objectheader *) obj;
2365 c = (classinfo *) clazz;
2366 m = (methodinfo *) methodID;
2368 ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2374 jchar CallNonvirtualCharMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2376 log_text("JNI-Call: CallNonvirtualCharMethodA: IMPLEMENT ME!");
2383 jshort CallNonvirtualShortMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2385 java_objectheader *o;
2391 o = (java_objectheader *) obj;
2392 c = (classinfo *) clazz;
2393 m = (methodinfo *) methodID;
2395 va_start(ap, methodID);
2396 s = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2403 jshort CallNonvirtualShortMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2405 java_objectheader *o;
2410 o = (java_objectheader *) obj;
2411 c = (classinfo *) clazz;
2412 m = (methodinfo *) methodID;
2414 s = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2420 jshort CallNonvirtualShortMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2422 log_text("JNI-Call: CallNonvirtualShortMethodA: IMPLEMENT ME!");
2429 jint CallNonvirtualIntMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2431 java_objectheader *o;
2437 o = (java_objectheader *) obj;
2438 c = (classinfo *) clazz;
2439 m = (methodinfo *) methodID;
2441 va_start(ap, methodID);
2442 i = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2449 jint CallNonvirtualIntMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2451 java_objectheader *o;
2456 o = (java_objectheader *) obj;
2457 c = (classinfo *) clazz;
2458 m = (methodinfo *) methodID;
2460 i = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2466 jint CallNonvirtualIntMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2468 log_text("JNI-Call: CallNonvirtualIntMethodA: IMPLEMENT ME!");
2475 jlong CallNonvirtualLongMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2477 java_objectheader *o;
2483 o = (java_objectheader *) obj;
2484 c = (classinfo *) clazz;
2485 m = (methodinfo *) methodID;
2487 va_start(ap, methodID);
2488 l = _Jv_jni_CallLongMethod(o, c->vftbl, m, ap);
2495 jlong CallNonvirtualLongMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2497 java_objectheader *o;
2502 o = (java_objectheader *) obj;
2503 c = (classinfo *) clazz;
2504 m = (methodinfo *) methodID;
2506 l = _Jv_jni_CallLongMethod(o, c->vftbl, m, args);
2512 jlong CallNonvirtualLongMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2514 log_text("JNI-Call: CallNonvirtualLongMethodA: IMPLEMENT ME!");
2521 jfloat CallNonvirtualFloatMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2523 java_objectheader *o;
2529 o = (java_objectheader *) obj;
2530 c = (classinfo *) clazz;
2531 m = (methodinfo *) methodID;
2533 va_start(ap, methodID);
2534 f = _Jv_jni_CallFloatMethod(o, c->vftbl, m, ap);
2541 jfloat CallNonvirtualFloatMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2543 java_objectheader *o;
2548 o = (java_objectheader *) obj;
2549 c = (classinfo *) clazz;
2550 m = (methodinfo *) methodID;
2552 f = _Jv_jni_CallFloatMethod(o, c->vftbl, m, args);
2558 jfloat CallNonvirtualFloatMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2560 log_text("JNI-Call: CallNonvirtualFloatMethodA: IMPLEMENT ME!");
2567 jdouble CallNonvirtualDoubleMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2569 java_objectheader *o;
2575 o = (java_objectheader *) obj;
2576 c = (classinfo *) clazz;
2577 m = (methodinfo *) methodID;
2579 va_start(ap, methodID);
2580 d = _Jv_jni_CallDoubleMethod(o, c->vftbl, m, ap);
2587 jdouble CallNonvirtualDoubleMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2589 java_objectheader *o;
2594 o = (java_objectheader *) obj;
2595 c = (classinfo *) clazz;
2596 m = (methodinfo *) methodID;
2598 d = _Jv_jni_CallDoubleMethod(o, c->vftbl, m, args);
2604 jdouble CallNonvirtualDoubleMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2606 log_text("JNI-Call: CallNonvirtualDoubleMethodA: IMPLEMENT ME!");
2613 void CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2615 java_objectheader *o;
2620 o = (java_objectheader *) obj;
2621 c = (classinfo *) clazz;
2622 m = (methodinfo *) methodID;
2624 va_start(ap, methodID);
2625 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2630 void CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2632 java_objectheader *o;
2636 o = (java_objectheader *) obj;
2637 c = (classinfo *) clazz;
2638 m = (methodinfo *) methodID;
2640 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2644 void CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
2646 java_objectheader *o;
2650 o = (java_objectheader *) obj;
2651 c = (classinfo *) clazz;
2652 m = (methodinfo *) methodID;
2654 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2658 /* Accessing Fields of Objects ************************************************/
2660 /* GetFieldID ******************************************************************
2662 Returns the field ID for an instance (nonstatic) field of a
2663 class. The field is specified by its name and signature. The
2664 Get<type>Field and Set<type>Field families of accessor functions
2665 use field IDs to retrieve object fields.
2667 *******************************************************************************/
2669 jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2676 STATISTICS(jniinvokation());
2678 uname = utf_new_char((char *) name);
2679 udesc = utf_new_char((char *) sig);
2681 f = class_findfield(clazz, uname, udesc);
2684 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2686 return (jfieldID) f;
2690 /* Get<type>Field Routines *****************************************************
2692 This family of accessor routines returns the value of an instance
2693 (nonstatic) field of an object. The field to access is specified by
2694 a field ID obtained by calling GetFieldID().
2696 *******************************************************************************/
2698 jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2700 java_objectheader *o;
2702 STATISTICS(jniinvokation());
2704 o = GET_FIELD(obj, java_objectheader*, fieldID);
2706 return NewLocalRef(env, o);
2710 jboolean GetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID)
2714 STATISTICS(jniinvokation());
2716 i = GET_FIELD(obj, s4, fieldID);
2718 return (jboolean) i;
2722 jbyte GetByteField(JNIEnv *env, jobject obj, jfieldID fieldID)
2726 STATISTICS(jniinvokation());
2728 i = GET_FIELD(obj, s4, fieldID);
2734 jchar GetCharField(JNIEnv *env, jobject obj, jfieldID fieldID)
2738 STATISTICS(jniinvokation());
2740 i = GET_FIELD(obj, s4, fieldID);
2746 jshort GetShortField(JNIEnv *env, jobject obj, jfieldID fieldID)
2750 STATISTICS(jniinvokation());
2752 i = GET_FIELD(obj, s4, fieldID);
2758 jint GetIntField(JNIEnv *env, jobject obj, jfieldID fieldID)
2760 java_objectheader *o;
2764 STATISTICS(jniinvokation());
2766 o = (java_objectheader *) obj;
2767 f = (fieldinfo *) fieldID;
2769 i = GET_FIELD(o, s4, f);
2775 jlong GetLongField(JNIEnv *env, jobject obj, jfieldID fieldID)
2779 STATISTICS(jniinvokation());
2781 l = GET_FIELD(obj, s8, fieldID);
2787 jfloat GetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID)
2791 STATISTICS(jniinvokation());
2793 f = GET_FIELD(obj, float, fieldID);
2799 jdouble GetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID)
2803 STATISTICS(jniinvokation());
2805 d = GET_FIELD(obj, double, fieldID);
2811 /* Set<type>Field Routines *****************************************************
2813 This family of accessor routines sets the value of an instance
2814 (nonstatic) field of an object. The field to access is specified by
2815 a field ID obtained by calling GetFieldID().
2817 *******************************************************************************/
2819 void SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value)
2821 STATISTICS(jniinvokation());
2823 SET_FIELD(obj, java_objectheader*, fieldID, value);
2827 void SetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID, jboolean value)
2829 STATISTICS(jniinvokation());
2831 SET_FIELD(obj, s4, fieldID, value);
2835 void SetByteField(JNIEnv *env, jobject obj, jfieldID fieldID, jbyte value)
2837 STATISTICS(jniinvokation());
2839 SET_FIELD(obj, s4, fieldID, value);
2843 void SetCharField(JNIEnv *env, jobject obj, jfieldID fieldID, jchar value)
2845 STATISTICS(jniinvokation());
2847 SET_FIELD(obj, s4, fieldID, value);
2851 void SetShortField(JNIEnv *env, jobject obj, jfieldID fieldID, jshort value)
2853 STATISTICS(jniinvokation());
2855 SET_FIELD(obj, s4, fieldID, value);
2859 void SetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint value)
2861 STATISTICS(jniinvokation());
2863 SET_FIELD(obj, s4, fieldID, value);
2867 void SetLongField(JNIEnv *env, jobject obj, jfieldID fieldID, jlong value)
2869 STATISTICS(jniinvokation());
2871 SET_FIELD(obj, s8, fieldID, value);
2875 void SetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID, jfloat value)
2877 STATISTICS(jniinvokation());
2879 SET_FIELD(obj, float, fieldID, value);
2883 void SetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID, jdouble value)
2885 STATISTICS(jniinvokation());
2887 SET_FIELD(obj, double, fieldID, value);
2891 /* Calling Static Methods *****************************************************/
2893 /* GetStaticMethodID ***********************************************************
2895 Returns the method ID for a static method of a class. The method is
2896 specified by its name and signature.
2898 GetStaticMethodID() causes an uninitialized class to be
2901 *******************************************************************************/
2903 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2911 STATISTICS(jniinvokation());
2913 c = (classinfo *) clazz;
2918 if (!(c->state & CLASS_INITIALIZED))
2919 if (!initialize_class(c))
2922 /* try to get the static method of the class */
2924 uname = utf_new_char((char *) name);
2925 udesc = utf_new_char((char *) sig);
2927 m = class_resolvemethod(c, uname, udesc);
2929 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2930 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2935 return (jmethodID) m;
2939 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2942 java_objectheader *o;
2945 m = (methodinfo *) methodID;
2947 va_start(ap, methodID);
2948 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2951 return NewLocalRef(env, o);
2955 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2958 java_objectheader *o;
2960 m = (methodinfo *) methodID;
2962 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2964 return NewLocalRef(env, o);
2968 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2970 log_text("JNI-Call: CallStaticObjectMethodA: IMPLEMENT ME!");
2972 return NewLocalRef(env, NULL);
2976 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2982 m = (methodinfo *) methodID;
2984 va_start(ap, methodID);
2985 b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
2992 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2997 m = (methodinfo *) methodID;
2999 b = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3005 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3007 log_text("JNI-Call: CallStaticBooleanMethodA: IMPLEMENT ME!");
3013 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3019 m = (methodinfo *) methodID;
3021 va_start(ap, methodID);
3022 b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3029 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3034 m = (methodinfo *) methodID;
3036 b = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3042 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3044 log_text("JNI-Call: CallStaticByteMethodA: IMPLEMENT ME!");
3050 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3056 m = (methodinfo *) methodID;
3058 va_start(ap, methodID);
3059 c = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3066 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3071 m = (methodinfo *) methodID;
3073 c = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3079 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3081 log_text("JNI-Call: CallStaticCharMethodA: IMPLEMENT ME!");
3087 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3093 m = (methodinfo *) methodID;
3095 va_start(ap, methodID);
3096 s = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3103 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3108 m = (methodinfo *) methodID;
3110 s = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3116 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3118 log_text("JNI-Call: CallStaticShortMethodA: IMPLEMENT ME!");
3124 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3130 m = (methodinfo *) methodID;
3132 va_start(ap, methodID);
3133 i = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3140 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3145 m = (methodinfo *) methodID;
3147 i = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3153 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3155 log_text("JNI-Call: CallStaticIntMethodA: IMPLEMENT ME!");
3161 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3167 m = (methodinfo *) methodID;
3169 va_start(ap, methodID);
3170 l = _Jv_jni_CallLongMethod(NULL, NULL, m, ap);
3177 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
3183 m = (methodinfo *) methodID;
3185 l = _Jv_jni_CallLongMethod(NULL, NULL, m, args);
3191 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3193 log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!");
3200 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3206 m = (methodinfo *) methodID;
3208 va_start(ap, methodID);
3209 f = _Jv_jni_CallFloatMethod(NULL, NULL, m, ap);
3216 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3221 m = (methodinfo *) methodID;
3223 f = _Jv_jni_CallFloatMethod(NULL, NULL, m, args);
3229 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3231 log_text("JNI-Call: CallStaticFloatMethodA: IMPLEMENT ME!");
3237 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3243 m = (methodinfo *) methodID;
3245 va_start(ap, methodID);
3246 d = _Jv_jni_CallDoubleMethod(NULL, NULL, m, ap);
3253 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3258 m = (methodinfo *) methodID;
3260 d = _Jv_jni_CallDoubleMethod(NULL, NULL, m, args);
3266 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3268 log_text("JNI-Call: CallStaticDoubleMethodA: IMPLEMENT ME!");
3274 void CallStaticVoidMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3279 m = (methodinfo *) methodID;
3281 va_start(ap, methodID);
3282 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
3287 void CallStaticVoidMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3291 m = (methodinfo *) methodID;
3293 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
3297 void CallStaticVoidMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue * args)
3301 m = (methodinfo *) methodID;
3303 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
3307 /* Accessing Static Fields ****************************************************/
3309 /* GetStaticFieldID ************************************************************
3311 Returns the field ID for a static field of a class. The field is
3312 specified by its name and signature. The GetStatic<type>Field and
3313 SetStatic<type>Field families of accessor functions use field IDs
3314 to retrieve static fields.
3316 *******************************************************************************/
3318 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
3322 STATISTICS(jniinvokation());
3324 f = class_findfield(clazz,
3325 utf_new_char((char *) name),
3326 utf_new_char((char *) sig));
3329 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
3331 return (jfieldID) f;
3335 /* GetStatic<type>Field ********************************************************
3337 This family of accessor routines returns the value of a static
3340 *******************************************************************************/
3342 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3347 STATISTICS(jniinvokation());
3349 c = (classinfo *) clazz;
3350 f = (fieldinfo *) fieldID;
3352 if (!(c->state & CLASS_INITIALIZED))
3353 if (!initialize_class(c))
3356 return NewLocalRef(env, f->value.a);
3360 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3365 STATISTICS(jniinvokation());
3367 c = (classinfo *) clazz;
3368 f = (fieldinfo *) fieldID;
3370 if (!(c->state & CLASS_INITIALIZED))
3371 if (!initialize_class(c))
3378 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3383 STATISTICS(jniinvokation());
3385 c = (classinfo *) clazz;
3386 f = (fieldinfo *) fieldID;
3388 if (!(c->state & CLASS_INITIALIZED))
3389 if (!initialize_class(c))
3396 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3401 STATISTICS(jniinvokation());
3403 c = (classinfo *) clazz;
3404 f = (fieldinfo *) fieldID;
3406 if (!(c->state & CLASS_INITIALIZED))
3407 if (!initialize_class(c))
3414 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3419 STATISTICS(jniinvokation());
3421 c = (classinfo *) clazz;
3422 f = (fieldinfo *) fieldID;
3424 if (!(c->state & CLASS_INITIALIZED))
3425 if (!initialize_class(c))
3432 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3437 STATISTICS(jniinvokation());
3439 c = (classinfo *) clazz;
3440 f = (fieldinfo *) fieldID;
3442 if (!(c->state & CLASS_INITIALIZED))
3443 if (!initialize_class(c))
3450 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3455 STATISTICS(jniinvokation());
3457 c = (classinfo *) clazz;
3458 f = (fieldinfo *) fieldID;
3460 if (!(c->state & CLASS_INITIALIZED))
3461 if (!initialize_class(c))
3468 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3473 STATISTICS(jniinvokation());
3475 c = (classinfo *) clazz;
3476 f = (fieldinfo *) fieldID;
3478 if (!(c->state & CLASS_INITIALIZED))
3479 if (!initialize_class(c))
3486 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3491 STATISTICS(jniinvokation());
3493 c = (classinfo *) clazz;
3494 f = (fieldinfo *) fieldID;
3496 if (!(c->state & CLASS_INITIALIZED))
3497 if (!initialize_class(c))
3504 /* SetStatic<type>Field *******************************************************
3506 This family of accessor routines sets the value of a static field
3509 *******************************************************************************/
3511 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
3516 STATISTICS(jniinvokation());
3518 c = (classinfo *) clazz;
3519 f = (fieldinfo *) fieldID;
3521 if (!(c->state & CLASS_INITIALIZED))
3522 if (!initialize_class(c))
3529 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
3534 STATISTICS(jniinvokation());
3536 c = (classinfo *) clazz;
3537 f = (fieldinfo *) fieldID;
3539 if (!(c->state & CLASS_INITIALIZED))
3540 if (!initialize_class(c))
3547 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
3552 STATISTICS(jniinvokation());
3554 c = (classinfo *) clazz;
3555 f = (fieldinfo *) fieldID;
3557 if (!(c->state & CLASS_INITIALIZED))
3558 if (!initialize_class(c))
3565 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
3570 STATISTICS(jniinvokation());
3572 c = (classinfo *) clazz;
3573 f = (fieldinfo *) fieldID;
3575 if (!(c->state & CLASS_INITIALIZED))
3576 if (!initialize_class(c))
3583 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
3588 STATISTICS(jniinvokation());
3590 c = (classinfo *) clazz;
3591 f = (fieldinfo *) fieldID;
3593 if (!(c->state & CLASS_INITIALIZED))
3594 if (!initialize_class(c))
3601 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
3606 STATISTICS(jniinvokation());
3608 c = (classinfo *) clazz;
3609 f = (fieldinfo *) fieldID;
3611 if (!(c->state & CLASS_INITIALIZED))
3612 if (!initialize_class(c))
3619 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
3624 STATISTICS(jniinvokation());
3626 c = (classinfo *) clazz;
3627 f = (fieldinfo *) fieldID;
3629 if (!(c->state & CLASS_INITIALIZED))
3630 if (!initialize_class(c))
3637 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
3642 STATISTICS(jniinvokation());
3644 c = (classinfo *) clazz;
3645 f = (fieldinfo *) fieldID;
3647 if (!(c->state & CLASS_INITIALIZED))
3648 if (!initialize_class(c))
3655 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
3660 STATISTICS(jniinvokation());
3662 c = (classinfo *) clazz;
3663 f = (fieldinfo *) fieldID;
3665 if (!(c->state & CLASS_INITIALIZED))
3666 if (!initialize_class(c))
3673 /* String Operations **********************************************************/
3675 /* NewString *******************************************************************
3677 Create new java.lang.String object from an array of Unicode
3680 *******************************************************************************/
3682 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
3684 java_lang_String *s;
3688 STATISTICS(jniinvokation());
3690 s = (java_lang_String *) builtin_new(class_java_lang_String);
3691 a = builtin_newarray_char(len);
3693 /* javastring or characterarray could not be created */
3698 for (i = 0; i < len; i++)
3699 a->data[i] = buf[i];
3705 return (jstring) NewLocalRef(env, (jobject) s);
3709 static jchar emptyStringJ[]={0,0};
3711 /* GetStringLength *************************************************************
3713 Returns the length (the count of Unicode characters) of a Java
3716 *******************************************************************************/
3718 jsize GetStringLength(JNIEnv *env, jstring str)
3720 return ((java_lang_String *) str)->count;
3724 /******************** convertes javastring to u2-array ****************************/
3726 u2 *javastring_tou2(jstring so)
3728 java_lang_String *s;
3733 STATISTICS(jniinvokation());
3735 s = (java_lang_String *) so;
3745 /* allocate memory */
3747 stringbuffer = MNEW(u2, s->count + 1);
3751 for (i = 0; i < s->count; i++)
3752 stringbuffer[i] = a->data[s->offset + i];
3754 /* terminate string */
3756 stringbuffer[i] = '\0';
3758 return stringbuffer;
3762 /* GetStringChars **************************************************************
3764 Returns a pointer to the array of Unicode characters of the
3765 string. This pointer is valid until ReleaseStringchars() is called.
3767 *******************************************************************************/
3769 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
3773 STATISTICS(jniinvokation());
3775 jc = javastring_tou2(str);
3787 return emptyStringJ;
3791 /* ReleaseStringChars **********************************************************
3793 Informs the VM that the native code no longer needs access to
3794 chars. The chars argument is a pointer obtained from string using
3797 *******************************************************************************/
3799 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
3801 STATISTICS(jniinvokation());
3803 if (chars == emptyStringJ)
3806 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
3810 /* NewStringUTF ****************************************************************
3812 Constructs a new java.lang.String object from an array of UTF-8 characters.
3814 *******************************************************************************/
3816 jstring NewStringUTF(JNIEnv *env, const char *bytes)
3818 java_lang_String *s;
3820 STATISTICS(jniinvokation());
3822 s = javastring_new(utf_new_char(bytes));
3824 return (jstring) NewLocalRef(env, (jobject) s);
3828 /****************** returns the utf8 length in bytes of a string *******************/
3830 jsize GetStringUTFLength (JNIEnv *env, jstring string)
3832 java_lang_String *s = (java_lang_String*) string;
3834 STATISTICS(jniinvokation());
3836 return (jsize) u2_utflength(s->value->data, s->count);
3840 /* GetStringUTFChars ***********************************************************
3842 Returns a pointer to an array of UTF-8 characters of the
3843 string. This array is valid until it is released by
3844 ReleaseStringUTFChars().
3846 *******************************************************************************/
3848 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
3852 STATISTICS(jniinvokation());
3860 u = javastring_toutf((java_lang_String *) string, false);
3869 /* ReleaseStringUTFChars *******************************************************
3871 Informs the VM that the native code no longer needs access to
3872 utf. The utf argument is a pointer derived from string using
3873 GetStringUTFChars().
3875 *******************************************************************************/
3877 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
3879 STATISTICS(jniinvokation());
3881 /* XXX we don't release utf chars right now, perhaps that should be done
3882 later. Since there is always one reference the garbage collector will
3887 /* Array Operations ***********************************************************/
3889 /* GetArrayLength **************************************************************
3891 Returns the number of elements in the array.
3893 *******************************************************************************/
3895 jsize GetArrayLength(JNIEnv *env, jarray array)
3897 java_arrayheader *a;
3899 STATISTICS(jniinvokation());
3901 a = (java_arrayheader *) array;
3907 /* NewObjectArray **************************************************************
3909 Constructs a new array holding objects in class elementClass. All
3910 elements are initially set to initialElement.
3912 *******************************************************************************/
3914 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
3916 java_objectarray *oa;
3919 STATISTICS(jniinvokation());
3922 exceptions_throw_negativearraysizeexception();
3926 oa = builtin_anewarray(length, elementClass);
3931 /* set all elements to initialElement */
3933 for (i = 0; i < length; i++)
3934 oa->data[i] = initialElement;
3936 return (jobjectArray) NewLocalRef(env, (jobject) oa);
3940 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
3942 java_objectarray *oa;
3945 STATISTICS(jniinvokation());
3947 oa = (java_objectarray *) array;
3949 if (index >= oa->header.size) {
3950 exceptions_throw_arrayindexoutofboundsexception();
3954 o = oa->data[index];
3956 return NewLocalRef(env, o);
3960 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3962 java_objectarray *oa;
3963 java_objectheader *o;
3965 STATISTICS(jniinvokation());
3967 oa = (java_objectarray *) array;
3968 o = (java_objectheader *) val;
3970 if (index >= oa->header.size) {
3971 exceptions_throw_arrayindexoutofboundsexception();
3975 /* check if the class of value is a subclass of the element class
3978 if (!builtin_canstore(oa, o)) {
3979 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3984 oa->data[index] = val;
3988 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3990 java_booleanarray *ba;
3992 STATISTICS(jniinvokation());
3995 exceptions_throw_negativearraysizeexception();
3999 ba = builtin_newarray_boolean(len);
4001 return (jbooleanArray) NewLocalRef(env, (jobject) ba);
4005 jbyteArray NewByteArray(JNIEnv *env, jsize len)
4009 STATISTICS(jniinvokation());
4012 exceptions_throw_negativearraysizeexception();
4016 ba = builtin_newarray_byte(len);
4018 return (jbyteArray) NewLocalRef(env, (jobject) ba);
4022 jcharArray NewCharArray(JNIEnv *env, jsize len)
4026 STATISTICS(jniinvokation());
4029 exceptions_throw_negativearraysizeexception();
4033 ca = builtin_newarray_char(len);
4035 return (jcharArray) NewLocalRef(env, (jobject) ca);
4039 jshortArray NewShortArray(JNIEnv *env, jsize len)
4041 java_shortarray *sa;
4043 STATISTICS(jniinvokation());
4046 exceptions_throw_negativearraysizeexception();
4050 sa = builtin_newarray_short(len);
4052 return (jshortArray) NewLocalRef(env, (jobject) sa);
4056 jintArray NewIntArray(JNIEnv *env, jsize len)
4060 STATISTICS(jniinvokation());
4063 exceptions_throw_negativearraysizeexception();
4067 ia = builtin_newarray_int(len);
4069 return (jintArray) NewLocalRef(env, (jobject) ia);
4073 jlongArray NewLongArray(JNIEnv *env, jsize len)
4077 STATISTICS(jniinvokation());
4080 exceptions_throw_negativearraysizeexception();
4084 la = builtin_newarray_long(len);
4086 return (jlongArray) NewLocalRef(env, (jobject) la);
4090 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
4092 java_floatarray *fa;
4094 STATISTICS(jniinvokation());
4097 exceptions_throw_negativearraysizeexception();
4101 fa = builtin_newarray_float(len);
4103 return (jfloatArray) NewLocalRef(env, (jobject) fa);
4107 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
4109 java_doublearray *da;
4111 STATISTICS(jniinvokation());
4114 exceptions_throw_negativearraysizeexception();
4118 da = builtin_newarray_double(len);
4120 return (jdoubleArray) NewLocalRef(env, (jobject) da);
4124 /* Get<PrimitiveType>ArrayElements *********************************************
4126 A family of functions that returns the body of the primitive array.
4128 *******************************************************************************/
4130 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
4133 java_booleanarray *ba;
4135 STATISTICS(jniinvokation());
4137 ba = (java_booleanarray *) array;
4140 *isCopy = JNI_FALSE;
4146 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
4150 STATISTICS(jniinvokation());
4152 ba = (java_bytearray *) array;
4155 *isCopy = JNI_FALSE;
4161 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
4165 STATISTICS(jniinvokation());
4167 ca = (java_chararray *) array;
4170 *isCopy = JNI_FALSE;
4176 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
4178 java_shortarray *sa;
4180 STATISTICS(jniinvokation());
4182 sa = (java_shortarray *) array;
4185 *isCopy = JNI_FALSE;
4191 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
4195 STATISTICS(jniinvokation());
4197 ia = (java_intarray *) array;
4200 *isCopy = JNI_FALSE;
4206 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
4210 STATISTICS(jniinvokation());
4212 la = (java_longarray *) array;
4215 *isCopy = JNI_FALSE;
4217 /* We cast this one to prevent a compiler warning on 64-bit
4218 systems since GNU Classpath typedef jlong to long long. */
4220 return (jlong *) la->data;
4224 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
4226 java_floatarray *fa;
4228 STATISTICS(jniinvokation());
4230 fa = (java_floatarray *) array;
4233 *isCopy = JNI_FALSE;
4239 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
4242 java_doublearray *da;
4244 STATISTICS(jniinvokation());
4246 da = (java_doublearray *) array;
4249 *isCopy = JNI_FALSE;
4255 /* Release<PrimitiveType>ArrayElements *****************************************
4257 A family of functions that informs the VM that the native code no
4258 longer needs access to elems. The elems argument is a pointer
4259 derived from array using the corresponding
4260 Get<PrimitiveType>ArrayElements() function. If necessary, this
4261 function copies back all changes made to elems to the original
4264 *******************************************************************************/
4266 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
4267 jboolean *elems, jint mode)
4269 java_booleanarray *ba;
4271 STATISTICS(jniinvokation());
4273 ba = (java_booleanarray *) array;
4275 if (elems != ba->data) {
4278 MCOPY(ba->data, elems, u1, ba->header.size);
4281 MCOPY(ba->data, elems, u1, ba->header.size);
4282 /* XXX TWISTI how should it be freed? */
4285 /* XXX TWISTI how should it be freed? */
4292 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
4297 STATISTICS(jniinvokation());
4299 ba = (java_bytearray *) array;
4301 if (elems != ba->data) {
4304 MCOPY(ba->data, elems, s1, ba->header.size);
4307 MCOPY(ba->data, elems, s1, ba->header.size);
4308 /* XXX TWISTI how should it be freed? */
4311 /* XXX TWISTI how should it be freed? */
4318 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
4323 STATISTICS(jniinvokation());
4325 ca = (java_chararray *) array;
4327 if (elems != ca->data) {
4330 MCOPY(ca->data, elems, u2, ca->header.size);
4333 MCOPY(ca->data, elems, u2, ca->header.size);
4334 /* XXX TWISTI how should it be freed? */
4337 /* XXX TWISTI how should it be freed? */
4344 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
4347 java_shortarray *sa;
4349 STATISTICS(jniinvokation());
4351 sa = (java_shortarray *) array;
4353 if (elems != sa->data) {
4356 MCOPY(sa->data, elems, s2, sa->header.size);
4359 MCOPY(sa->data, elems, s2, sa->header.size);
4360 /* XXX TWISTI how should it be freed? */
4363 /* XXX TWISTI how should it be freed? */
4370 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
4375 STATISTICS(jniinvokation());
4377 ia = (java_intarray *) array;
4379 if (elems != ia->data) {
4382 MCOPY(ia->data, elems, s4, ia->header.size);
4385 MCOPY(ia->data, elems, s4, ia->header.size);
4386 /* XXX TWISTI how should it be freed? */
4389 /* XXX TWISTI how should it be freed? */
4396 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
4401 STATISTICS(jniinvokation());
4403 la = (java_longarray *) array;
4405 /* We cast this one to prevent a compiler warning on 64-bit
4406 systems since GNU Classpath typedef jlong to long long. */
4408 if ((s8 *) elems != la->data) {
4411 MCOPY(la->data, elems, s8, la->header.size);
4414 MCOPY(la->data, elems, s8, la->header.size);
4415 /* XXX TWISTI how should it be freed? */
4418 /* XXX TWISTI how should it be freed? */
4425 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
4428 java_floatarray *fa;
4430 STATISTICS(jniinvokation());
4432 fa = (java_floatarray *) array;
4434 if (elems != fa->data) {
4437 MCOPY(fa->data, elems, float, fa->header.size);
4440 MCOPY(fa->data, elems, float, fa->header.size);
4441 /* XXX TWISTI how should it be freed? */
4444 /* XXX TWISTI how should it be freed? */
4451 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
4452 jdouble *elems, jint mode)
4454 java_doublearray *da;
4456 STATISTICS(jniinvokation());
4458 da = (java_doublearray *) array;
4460 if (elems != da->data) {
4463 MCOPY(da->data, elems, double, da->header.size);
4466 MCOPY(da->data, elems, double, da->header.size);
4467 /* XXX TWISTI how should it be freed? */
4470 /* XXX TWISTI how should it be freed? */
4477 /* Get<PrimitiveType>ArrayRegion **********************************************
4479 A family of functions that copies a region of a primitive array
4482 *******************************************************************************/
4484 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
4485 jsize len, jboolean *buf)
4487 java_booleanarray *ba;
4489 STATISTICS(jniinvokation());
4491 ba = (java_booleanarray *) array;
4493 if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4494 exceptions_throw_arrayindexoutofboundsexception();
4496 MCOPY(buf, &ba->data[start], u1, len);
4500 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
4505 STATISTICS(jniinvokation());
4507 ba = (java_bytearray *) array;
4509 if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4510 exceptions_throw_arrayindexoutofboundsexception();
4512 MCOPY(buf, &ba->data[start], s1, len);
4516 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
4521 STATISTICS(jniinvokation());
4523 ca = (java_chararray *) array;
4525 if ((start < 0) || (len < 0) || (start + len > ca->header.size))
4526 exceptions_throw_arrayindexoutofboundsexception();
4528 MCOPY(buf, &ca->data[start], u2, len);
4532 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
4533 jsize len, jshort *buf)
4535 java_shortarray *sa;
4537 STATISTICS(jniinvokation());
4539 sa = (java_shortarray *) array;
4541 if ((start < 0) || (len < 0) || (start + len > sa->header.size))
4542 exceptions_throw_arrayindexoutofboundsexception();
4544 MCOPY(buf, &sa->data[start], s2, len);
4548 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
4553 STATISTICS(jniinvokation());
4555 ia = (java_intarray *) array;
4557 if ((start < 0) || (len < 0) || (start + len > ia->header.size))
4558 exceptions_throw_arrayindexoutofboundsexception();
4560 MCOPY(buf, &ia->data[start], s4, len);
4564 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
4569 STATISTICS(jniinvokation());
4571 la = (java_longarray *) array;
4573 if ((start < 0) || (len < 0) || (start + len > la->header.size))
4574 exceptions_throw_arrayindexoutofboundsexception();
4576 MCOPY(buf, &la->data[start], s8, len);
4580 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
4581 jsize len, jfloat *buf)
4583 java_floatarray *fa;
4585 STATISTICS(jniinvokation());
4587 fa = (java_floatarray *) array;
4589 if ((start < 0) || (len < 0) || (start + len > fa->header.size))
4590 exceptions_throw_arrayindexoutofboundsexception();
4592 MCOPY(buf, &fa->data[start], float, len);
4596 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
4597 jsize len, jdouble *buf)
4599 java_doublearray *da;
4601 STATISTICS(jniinvokation());
4603 da = (java_doublearray *) array;
4605 if ((start < 0) || (len < 0) || (start + len > da->header.size))
4606 exceptions_throw_arrayindexoutofboundsexception();
4608 MCOPY(buf, &da->data[start], double, len);
4612 /* Set<PrimitiveType>ArrayRegion **********************************************
4614 A family of functions that copies back a region of a primitive
4615 array from a buffer.
4617 *******************************************************************************/
4619 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
4620 jsize len, jboolean *buf)
4622 java_booleanarray *ba;
4624 STATISTICS(jniinvokation());
4626 ba = (java_booleanarray *) array;
4628 if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4629 exceptions_throw_arrayindexoutofboundsexception();
4631 MCOPY(&ba->data[start], buf, u1, len);
4635 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
4640 STATISTICS(jniinvokation());
4642 ba = (java_bytearray *) array;
4644 if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4645 exceptions_throw_arrayindexoutofboundsexception();
4647 MCOPY(&ba->data[start], buf, s1, len);
4651 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
4656 STATISTICS(jniinvokation());
4658 ca = (java_chararray *) array;
4660 if ((start < 0) || (len < 0) || (start + len > ca->header.size))
4661 exceptions_throw_arrayindexoutofboundsexception();
4663 MCOPY(&ca->data[start], buf, u2, len);
4667 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
4668 jsize len, jshort *buf)
4670 java_shortarray *sa;
4672 STATISTICS(jniinvokation());
4674 sa = (java_shortarray *) array;
4676 if ((start < 0) || (len < 0) || (start + len > sa->header.size))
4677 exceptions_throw_arrayindexoutofboundsexception();
4679 MCOPY(&sa->data[start], buf, s2, len);
4683 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
4688 STATISTICS(jniinvokation());
4690 ia = (java_intarray *) array;
4692 if ((start < 0) || (len < 0) || (start + len > ia->header.size))
4693 exceptions_throw_arrayindexoutofboundsexception();
4695 MCOPY(&ia->data[start], buf, s4, len);
4699 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
4704 STATISTICS(jniinvokation());
4706 la = (java_longarray *) array;
4708 if ((start < 0) || (len < 0) || (start + len > la->header.size))
4709 exceptions_throw_arrayindexoutofboundsexception();
4711 MCOPY(&la->data[start], buf, s8, len);
4715 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
4716 jsize len, jfloat *buf)
4718 java_floatarray *fa;
4720 STATISTICS(jniinvokation());
4722 fa = (java_floatarray *) array;
4724 if ((start < 0) || (len < 0) || (start + len > fa->header.size))
4725 exceptions_throw_arrayindexoutofboundsexception();
4727 MCOPY(&fa->data[start], buf, float, len);
4731 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
4732 jsize len, jdouble *buf)
4734 java_doublearray *da;
4736 STATISTICS(jniinvokation());
4738 da = (java_doublearray *) array;
4740 if ((start < 0) || (len < 0) || (start + len > da->header.size))
4741 exceptions_throw_arrayindexoutofboundsexception();
4743 MCOPY(&da->data[start], buf, double, len);
4747 /* Registering Native Methods *************************************************/
4749 /* RegisterNatives *************************************************************
4751 Registers native methods with the class specified by the clazz
4752 argument. The methods parameter specifies an array of
4753 JNINativeMethod structures that contain the names, signatures, and
4754 function pointers of the native methods. The nMethods parameter
4755 specifies the number of native methods in the array.
4757 *******************************************************************************/
4759 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
4762 STATISTICS(jniinvokation());
4764 log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
4770 /* UnregisterNatives ***********************************************************
4772 Unregisters native methods of a class. The class goes back to the
4773 state before it was linked or registered with its native method
4776 This function should not be used in normal native code. Instead, it
4777 provides special programs a way to reload and relink native
4780 *******************************************************************************/
4782 jint UnregisterNatives(JNIEnv *env, jclass clazz)
4784 STATISTICS(jniinvokation());
4786 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
4788 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
4794 /* Monitor Operations *********************************************************/
4796 /* MonitorEnter ****************************************************************
4798 Enters the monitor associated with the underlying Java object
4801 *******************************************************************************/
4803 jint MonitorEnter(JNIEnv *env, jobject obj)
4805 STATISTICS(jniinvokation());
4808 exceptions_throw_nullpointerexception();
4812 #if defined(USE_THREADS)
4813 builtin_monitorenter(obj);
4820 /* MonitorExit *****************************************************************
4822 The current thread must be the owner of the monitor associated with
4823 the underlying Java object referred to by obj. The thread
4824 decrements the counter indicating the number of times it has
4825 entered this monitor. If the value of the counter becomes zero, the
4826 current thread releases the monitor.
4828 *******************************************************************************/
4830 jint MonitorExit(JNIEnv *env, jobject obj)
4832 STATISTICS(jniinvokation());
4835 exceptions_throw_nullpointerexception();
4839 #if defined(USE_THREADS)
4840 builtin_monitorexit(obj);
4847 /* JavaVM Interface ***********************************************************/
4849 /* GetJavaVM *******************************************************************
4851 Returns the Java VM interface (used in the Invocation API)
4852 associated with the current thread. The result is placed at the
4853 location pointed to by the second argument, vm.
4855 *******************************************************************************/
4857 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
4859 STATISTICS(jniinvokation());
4867 void GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
4869 STATISTICS(jniinvokation());
4871 log_text("JNI-Call: GetStringRegion: IMPLEMENT ME!");
4875 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
4877 STATISTICS(jniinvokation());
4879 log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
4883 /* GetPrimitiveArrayCritical ***************************************************
4885 Obtain a direct pointer to array elements.
4887 *******************************************************************************/
4889 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
4894 ba = (java_bytearray *) array;
4896 /* do the same as Kaffe does */
4898 bp = GetByteArrayElements(env, ba, isCopy);
4904 /* ReleasePrimitiveArrayCritical ***********************************************
4906 No specific documentation.
4908 *******************************************************************************/
4910 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
4913 STATISTICS(jniinvokation());
4915 /* do the same as Kaffe does */
4917 ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
4921 /* GetStringCritical ***********************************************************
4923 The semantics of these two functions are similar to the existing
4924 Get/ReleaseStringChars functions.
4926 *******************************************************************************/
4928 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
4930 STATISTICS(jniinvokation());
4932 return GetStringChars(env, string, isCopy);
4936 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
4938 STATISTICS(jniinvokation());
4940 ReleaseStringChars(env, string, cstring);
4944 jweak NewWeakGlobalRef(JNIEnv* env, jobject obj)
4946 STATISTICS(jniinvokation());
4948 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
4954 void DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
4956 STATISTICS(jniinvokation());
4958 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
4962 /* NewGlobalRef ****************************************************************
4964 Creates a new global reference to the object referred to by the obj
4967 *******************************************************************************/
4969 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4971 java_objectheader *o;
4972 java_lang_Integer *refcount;
4973 java_objectheader *newval;
4975 STATISTICS(jniinvokation());
4977 #if defined(USE_THREADS)
4978 builtin_monitorenter(*global_ref_table);
4981 o = vm_call_method(getmid, *global_ref_table, lobj);
4983 refcount = (java_lang_Integer *) o;
4985 if (refcount == NULL) {
4986 newval = native_new_and_init_int(class_java_lang_Integer, 1);
4988 if (newval == NULL) {
4989 #if defined(USE_THREADS)
4990 builtin_monitorexit(*global_ref_table);
4995 (void) vm_call_method(putmid, *global_ref_table, lobj, newval);
4998 /* we can access the object itself, as we are in a
4999 synchronized section */
5004 #if defined(USE_THREADS)
5005 builtin_monitorexit(*global_ref_table);
5012 /* DeleteGlobalRef *************************************************************
5014 Deletes the global reference pointed to by globalRef.
5016 *******************************************************************************/
5018 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
5020 java_objectheader *o;
5021 java_lang_Integer *refcount;
5024 STATISTICS(jniinvokation());
5026 #if defined(USE_THREADS)
5027 builtin_monitorenter(*global_ref_table);
5030 o = vm_call_method(getmid, *global_ref_table, globalRef);
5032 refcount = (java_lang_Integer *) o;
5034 if (refcount == NULL) {
5035 log_text("JNI-DeleteGlobalRef: unable to find global reference");
5039 /* we can access the object itself, as we are in a synchronized
5042 val = refcount->value - 1;
5045 (void) vm_call_method(removemid, *global_ref_table, refcount);
5048 /* we do not create a new object, but set the new value into
5051 refcount->value = val;
5054 #if defined(USE_THREADS)
5055 builtin_monitorexit(*global_ref_table);
5060 /* ExceptionCheck **************************************************************
5062 Returns JNI_TRUE when there is a pending exception; otherwise,
5065 *******************************************************************************/
5067 jboolean ExceptionCheck(JNIEnv *env)
5069 STATISTICS(jniinvokation());
5071 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
5075 /* New JNI 1.4 functions ******************************************************/
5077 /* NewDirectByteBuffer *********************************************************
5079 Allocates and returns a direct java.nio.ByteBuffer referring to the
5080 block of memory starting at the memory address address and
5081 extending capacity bytes.
5083 *******************************************************************************/
5085 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
5087 java_objectheader *nbuf;
5088 #if SIZEOF_VOID_P == 8
5089 gnu_classpath_Pointer64 *paddress;
5091 gnu_classpath_Pointer32 *paddress;
5094 STATISTICS(jniinvokation());
5096 /* alocate a gnu.classpath.Pointer{32,64} object */
5098 #if SIZEOF_VOID_P == 8
5099 if (!(paddress = (gnu_classpath_Pointer64 *)
5100 builtin_new(class_gnu_classpath_Pointer64)))
5102 if (!(paddress = (gnu_classpath_Pointer32 *)
5103 builtin_new(class_gnu_classpath_Pointer32)))
5107 /* fill gnu.classpath.Pointer{32,64} with address */
5109 paddress->data = (ptrint) address;
5111 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
5113 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
5114 (jmethodID) dbbirw_init, NULL, paddress,
5115 (jint) capacity, (jint) capacity, (jint) 0);
5117 /* add local reference and return the value */
5119 return NewLocalRef(env, nbuf);
5123 /* GetDirectBufferAddress ******************************************************
5125 Fetches and returns the starting address of the memory region
5126 referenced by the given direct java.nio.Buffer.
5128 *******************************************************************************/
5130 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
5132 java_nio_DirectByteBufferImpl *nbuf;
5133 #if SIZEOF_VOID_P == 8
5134 gnu_classpath_Pointer64 *address;
5136 gnu_classpath_Pointer32 *address;
5139 STATISTICS(jniinvokation());
5141 if (!builtin_instanceof(buf, class_java_nio_Buffer))
5144 nbuf = (java_nio_DirectByteBufferImpl *) buf;
5146 #if SIZEOF_VOID_P == 8
5147 address = (gnu_classpath_Pointer64 *) nbuf->address;
5149 address = (gnu_classpath_Pointer32 *) nbuf->address;
5152 return (void *) address->data;
5156 /* GetDirectBufferCapacity *****************************************************
5158 Fetches and returns the capacity in bytes of the memory region
5159 referenced by the given direct java.nio.Buffer.
5161 *******************************************************************************/
5163 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
5165 java_nio_Buffer *nbuf;
5167 STATISTICS(jniinvokation());
5169 if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
5172 nbuf = (java_nio_Buffer *) buf;
5174 return (jlong) nbuf->cap;
5178 /* DestroyJavaVM ***************************************************************
5180 Unloads a Java VM and reclaims its resources. Only the main thread
5181 can unload the VM. The system waits until the main thread is only
5182 remaining user thread before it destroys the VM.
5184 *******************************************************************************/
5186 jint DestroyJavaVM(JavaVM *vm)
5190 STATISTICS(jniinvokation());
5192 status = vm_destroy(vm);
5198 /* AttachCurrentThread *********************************************************
5200 Attaches the current thread to a Java VM. Returns a JNI interface
5201 pointer in the JNIEnv argument.
5203 Trying to attach a thread that is already attached is a no-op.
5205 A native thread cannot be attached simultaneously to two Java VMs.
5207 When a thread is attached to the VM, the context class loader is
5208 the bootstrap loader.
5210 *******************************************************************************/
5212 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
5214 STATISTICS(jniinvokation());
5216 log_text("JNI-Call: AttachCurrentThread: IMPLEMENT ME!");
5218 #if !defined(HAVE___THREAD)
5219 /* cacao_thread_attach();*/
5221 #error "No idea how to implement that. Perhaps Stefan knows"
5230 jint DetachCurrentThread(JavaVM *vm)
5232 STATISTICS(jniinvokation());
5234 log_text("JNI-Call: DetachCurrentThread: IMPLEMENT ME!");
5240 /* GetEnv **********************************************************************
5242 If the current thread is not attached to the VM, sets *env to NULL,
5243 and returns JNI_EDETACHED. If the specified version is not
5244 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
5245 sets *env to the appropriate interface, and returns JNI_OK.
5247 *******************************************************************************/
5249 jint GetEnv(JavaVM *vm, void **env, jint version)
5251 STATISTICS(jniinvokation());
5253 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
5254 if (thread_getself() == NULL) {
5257 return JNI_EDETACHED;
5261 if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
5262 (version == JNI_VERSION_1_4)) {
5268 #if defined(ENABLE_JVMTI)
5269 if (version == JVMTI_VERSION_1_0) {
5270 *env = (void *) new_jvmtienv();
5279 return JNI_EVERSION;
5284 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
5286 STATISTICS(jniinvokation());
5288 log_text("JNI-Call: AttachCurrentThreadAsDaemon: IMPLEMENT ME!");
5294 /* JNI invocation table *******************************************************/
5296 const struct JNIInvokeInterface JNI_JavaVMTable = {
5302 AttachCurrentThread,
5303 DetachCurrentThread,
5305 AttachCurrentThreadAsDaemon
5309 /* JNI function table *********************************************************/
5311 struct JNINativeInterface JNI_JNIEnvTable = {
5320 FromReflectedMethod,
5341 EnsureLocalCapacity,
5384 CallNonvirtualObjectMethod,
5385 CallNonvirtualObjectMethodV,
5386 CallNonvirtualObjectMethodA,
5387 CallNonvirtualBooleanMethod,
5388 CallNonvirtualBooleanMethodV,
5389 CallNonvirtualBooleanMethodA,
5390 CallNonvirtualByteMethod,
5391 CallNonvirtualByteMethodV,
5392 CallNonvirtualByteMethodA,
5393 CallNonvirtualCharMethod,
5394 CallNonvirtualCharMethodV,
5395 CallNonvirtualCharMethodA,
5396 CallNonvirtualShortMethod,
5397 CallNonvirtualShortMethodV,
5398 CallNonvirtualShortMethodA,
5399 CallNonvirtualIntMethod,
5400 CallNonvirtualIntMethodV,
5401 CallNonvirtualIntMethodA,
5402 CallNonvirtualLongMethod,
5403 CallNonvirtualLongMethodV,
5404 CallNonvirtualLongMethodA,
5405 CallNonvirtualFloatMethod,
5406 CallNonvirtualFloatMethodV,
5407 CallNonvirtualFloatMethodA,
5408 CallNonvirtualDoubleMethod,
5409 CallNonvirtualDoubleMethodV,
5410 CallNonvirtualDoubleMethodA,
5411 CallNonvirtualVoidMethod,
5412 CallNonvirtualVoidMethodV,
5413 CallNonvirtualVoidMethodA,
5438 CallStaticObjectMethod,
5439 CallStaticObjectMethodV,
5440 CallStaticObjectMethodA,
5441 CallStaticBooleanMethod,
5442 CallStaticBooleanMethodV,
5443 CallStaticBooleanMethodA,
5444 CallStaticByteMethod,
5445 CallStaticByteMethodV,
5446 CallStaticByteMethodA,
5447 CallStaticCharMethod,
5448 CallStaticCharMethodV,
5449 CallStaticCharMethodA,
5450 CallStaticShortMethod,
5451 CallStaticShortMethodV,
5452 CallStaticShortMethodA,
5453 CallStaticIntMethod,
5454 CallStaticIntMethodV,
5455 CallStaticIntMethodA,
5456 CallStaticLongMethod,
5457 CallStaticLongMethodV,
5458 CallStaticLongMethodA,
5459 CallStaticFloatMethod,
5460 CallStaticFloatMethodV,
5461 CallStaticFloatMethodA,
5462 CallStaticDoubleMethod,
5463 CallStaticDoubleMethodV,
5464 CallStaticDoubleMethodA,
5465 CallStaticVoidMethod,
5466 CallStaticVoidMethodV,
5467 CallStaticVoidMethodA,
5471 GetStaticObjectField,
5472 GetStaticBooleanField,
5475 GetStaticShortField,
5478 GetStaticFloatField,
5479 GetStaticDoubleField,
5480 SetStaticObjectField,
5481 SetStaticBooleanField,
5484 SetStaticShortField,
5487 SetStaticFloatField,
5488 SetStaticDoubleField,
5498 ReleaseStringUTFChars,
5503 GetObjectArrayElement,
5504 SetObjectArrayElement,
5515 GetBooleanArrayElements,
5516 GetByteArrayElements,
5517 GetCharArrayElements,
5518 GetShortArrayElements,
5519 GetIntArrayElements,
5520 GetLongArrayElements,
5521 GetFloatArrayElements,
5522 GetDoubleArrayElements,
5524 ReleaseBooleanArrayElements,
5525 ReleaseByteArrayElements,
5526 ReleaseCharArrayElements,
5527 ReleaseShortArrayElements,
5528 ReleaseIntArrayElements,
5529 ReleaseLongArrayElements,
5530 ReleaseFloatArrayElements,
5531 ReleaseDoubleArrayElements,
5533 GetBooleanArrayRegion,
5536 GetShortArrayRegion,
5539 GetFloatArrayRegion,
5540 GetDoubleArrayRegion,
5541 SetBooleanArrayRegion,
5544 SetShortArrayRegion,
5547 SetFloatArrayRegion,
5548 SetDoubleArrayRegion,
5558 /* new JNI 1.2 functions */
5563 GetPrimitiveArrayCritical,
5564 ReleasePrimitiveArrayCritical,
5567 ReleaseStringCritical,
5570 DeleteWeakGlobalRef,
5574 /* new JNI 1.4 functions */
5576 NewDirectByteBuffer,
5577 GetDirectBufferAddress,
5578 GetDirectBufferCapacity
5582 /* Invocation API Functions ***************************************************/
5584 /* JNI_GetDefaultJavaVMInitArgs ************************************************
5586 Returns a default configuration for the Java VM.
5588 *******************************************************************************/
5590 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
5592 JavaVMInitArgs *_vm_args;
5594 _vm_args = (JavaVMInitArgs *) vm_args;
5596 /* GNU classpath currently supports JNI 1.2 */
5598 switch (_vm_args->version) {
5599 case JNI_VERSION_1_1:
5600 _vm_args->version = JNI_VERSION_1_1;
5603 case JNI_VERSION_1_2:
5604 case JNI_VERSION_1_4:
5605 _vm_args->ignoreUnrecognized = JNI_FALSE;
5606 _vm_args->options = NULL;
5607 _vm_args->nOptions = 0;
5618 /* JNI_GetCreatedJavaVMs *******************************************************
5620 Returns all Java VMs that have been created. Pointers to VMs are written in
5621 the buffer vmBuf in the order they are created. At most bufLen number of
5622 entries will be written. The total number of created VMs is returned in
5625 *******************************************************************************/
5627 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
5629 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
5635 /* JNI_CreateJavaVM ************************************************************
5637 Loads and initializes a Java VM. The current thread becomes the main thread.
5638 Sets the env argument to the JNI interface pointer of the main thread.
5640 *******************************************************************************/
5642 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
5644 JavaVMInitArgs *_vm_args;
5646 localref_table *lrt;
5648 /* get the arguments for the new JVM */
5650 _vm_args = (JavaVMInitArgs *) vm_args;
5652 /* get the VM and Env tables (must be set before vm_create) */
5654 env = NEW(_Jv_JNIEnv);
5656 env->env = &JNI_JNIEnvTable;
5658 *p_vm = (JavaVM *) &JNI_JavaVMTable;
5659 *p_env = (void *) env;
5661 /* XXX Set the global env variable. Maybe we should do that differently. */
5665 /* actually create the JVM */
5667 if (!vm_create(_vm_args))
5670 /* setup the local ref table (must be created after vm_create) */
5672 lrt = GCNEW(localref_table);
5674 lrt->capacity = LOCALREFTABLE_CAPACITY;
5676 lrt->localframes = 1;
5677 lrt->prev = LOCALREFTABLE;
5679 /* clear the references array (memset is faster then a for-loop) */
5681 MSET(lrt->refs, 0, java_objectheader*, LOCALREFTABLE_CAPACITY);
5683 LOCALREFTABLE = lrt;
5690 * These are local overrides for various environment variables in Emacs.
5691 * Please do not remove this and leave it at the end of the file, where
5692 * Emacs will automagically detect them.
5693 * ---------------------------------------------------------------------
5696 * indent-tabs-mode: t
5700 * vim:noexpandtab:sw=4:ts=4: