1 /* src/native/jni.c - implementation of the Java Native Interface functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Rainhard Grafl
30 Changes: Joseph Wenninger
34 $Id: jni.c 4082 2006-01-03 23:08:58Z twisti $
47 #include "mm/memory.h"
48 #include "native/jni.h"
49 #include "native/native.h"
51 #include "native/include/gnu_classpath_Pointer.h"
53 #if SIZEOF_VOID_P == 8
54 # include "native/include/gnu_classpath_Pointer64.h"
56 # include "native/include/gnu_classpath_Pointer32.h"
59 #include "native/include/java_lang_Object.h"
60 #include "native/include/java_lang_Byte.h"
61 #include "native/include/java_lang_Character.h"
62 #include "native/include/java_lang_Short.h"
63 #include "native/include/java_lang_Integer.h"
64 #include "native/include/java_lang_Boolean.h"
65 #include "native/include/java_lang_Long.h"
66 #include "native/include/java_lang_Float.h"
67 #include "native/include/java_lang_Double.h"
68 #include "native/include/java_lang_Throwable.h"
69 #include "native/include/java_lang_reflect_Method.h"
70 #include "native/include/java_lang_reflect_Constructor.h"
71 #include "native/include/java_lang_reflect_Field.h"
73 #include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
74 #include "native/include/java_lang_VMClass.h"
75 #include "native/include/java_lang_VMClassLoader.h"
76 #include "native/include/java_nio_Buffer.h"
77 #include "native/include/java_nio_DirectByteBufferImpl.h"
79 #if defined(ENABLE_JVMTI)
80 # include "native/jvmti/jvmti.h"
83 #if defined(USE_THREADS)
84 # if defined(NATIVE_THREADS)
85 # include "threads/native/threads.h"
87 # include "threads/green/threads.h"
91 #include "toolbox/logging.h"
92 #include "vm/builtin.h"
93 #include "vm/exceptions.h"
94 #include "vm/global.h"
95 #include "vm/initialize.h"
96 #include "vm/loader.h"
97 #include "vm/options.h"
98 #include "vm/resolve.h"
99 #include "vm/statistics.h"
100 #include "vm/stringlocal.h"
101 #include "vm/jit/asmpart.h"
102 #include "vm/jit/jit.h"
103 #include "vm/statistics.h"
106 /* XXX TWISTI hack: define it extern so they can be found in this file */
108 extern const struct JNIInvokeInterface JNI_JavaVMTable;
109 extern struct JNINativeInterface JNI_JNIEnvTable;
111 /* pointers to VM and the environment needed by GetJavaVM and GetEnv */
113 static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
114 void *ptr_env = (void*) &JNI_JNIEnvTable;
117 #define PTR_TO_ITEM(ptr) ((u8)(size_t)(ptr))
119 /* global variables ***********************************************************/
121 /* global reference table *****************************************************/
123 static java_objectheader **global_ref_table;
125 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
126 static classinfo *ihmclass = NULL;
127 static methodinfo *putmid = NULL;
128 static methodinfo *getmid = NULL;
129 static methodinfo *removemid = NULL;
132 /* direct buffer stuff ********************************************************/
134 static utf *utf_java_nio_DirectByteBufferImpl_ReadWrite;
135 #if SIZEOF_VOID_P == 8
136 static utf *utf_gnu_classpath_Pointer64;
138 static utf *utf_gnu_classpath_Pointer32;
141 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
142 #if SIZEOF_VOID_P == 8
143 static classinfo *class_gnu_classpath_Pointer64;
145 static classinfo *class_gnu_classpath_Pointer32;
148 static methodinfo *dbbirw_init;
151 /* local reference table ******************************************************/
153 #if !defined(USE_THREADS)
154 localref_table *_no_threads_localref_table;
158 /* accessing instance fields macros *******************************************/
160 #define SET_FIELD(obj,type,var,value) \
161 *((type *) ((ptrint) (obj) + (ptrint) (var)->offset)) = (type) (value)
163 #define GET_FIELD(obj,type,var) \
164 *((type *) ((ptrint) (obj) + (ptrint) (var)->offset))
167 /* some forward declarations **************************************************/
169 jobject NewLocalRef(JNIEnv *env, jobject ref);
172 /* jni_init ********************************************************************
174 Initialize the JNI subsystem.
176 *******************************************************************************/
180 /* initalize global reference table */
183 load_class_bootstrap(utf_new_char("java/util/IdentityHashMap"))))
186 global_ref_table = GCNEW(jobject, 1);
188 if (!(*global_ref_table = native_new_and_init(ihmclass)))
191 if (!(getmid = class_resolvemethod(ihmclass, utf_get,
192 utf_java_lang_Object__java_lang_Object)))
195 if (!(putmid = class_resolvemethod(ihmclass, utf_put,
196 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))))
200 class_resolvemethod(ihmclass, utf_remove,
201 utf_java_lang_Object__java_lang_Object)))
205 /* direct buffer stuff */
207 utf_java_nio_DirectByteBufferImpl_ReadWrite =
208 utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite");
210 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
211 load_class_bootstrap(utf_java_nio_DirectByteBufferImpl_ReadWrite)))
214 if (!link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
218 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
220 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
223 #if SIZEOF_VOID_P == 8
224 utf_gnu_classpath_Pointer64 = utf_new_char("gnu/classpath/Pointer64");
226 if (!(class_gnu_classpath_Pointer64 =
227 load_class_bootstrap(utf_gnu_classpath_Pointer64)))
230 if (!link_class(class_gnu_classpath_Pointer64))
233 utf_gnu_classpath_Pointer32 = utf_new_char("gnu/classpath/Pointer32");
235 if (!(class_gnu_classpath_Pointer32 =
236 load_class_bootstrap(utf_gnu_classpath_Pointer32)))
239 if (!link_class(class_gnu_classpath_Pointer32))
247 static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
248 jni_callblock blk[], va_list data,
251 typedesc *paramtypes;
254 paramtypes = descr->paramtypes;
256 /* if method is non-static fill first block and skip `this' pointer */
261 /* the `this' pointer */
262 blk[0].itemtype = TYPE_ADR;
263 blk[0].item = PTR_TO_ITEM(obj);
269 for (; i < descr->paramcount; i++, paramtypes++) {
270 switch (paramtypes->decltype) {
271 /* primitive types */
272 case PRIMITIVETYPE_BYTE:
273 case PRIMITIVETYPE_CHAR:
274 case PRIMITIVETYPE_SHORT:
275 case PRIMITIVETYPE_BOOLEAN:
276 blk[i].itemtype = TYPE_INT;
277 blk[i].item = (s8) va_arg(data, s4);
280 case PRIMITIVETYPE_INT:
281 blk[i].itemtype = TYPE_INT;
282 blk[i].item = (s8) va_arg(data, s4);
285 case PRIMITIVETYPE_LONG:
286 blk[i].itemtype = TYPE_LNG;
287 blk[i].item = (s8) va_arg(data, s8);
290 case PRIMITIVETYPE_FLOAT:
291 blk[i].itemtype = TYPE_FLT;
292 #if defined(__ALPHA__)
293 /* this keeps the assembler function much simpler */
295 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
297 *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
301 case PRIMITIVETYPE_DOUBLE:
302 blk[i].itemtype = TYPE_DBL;
303 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
307 blk[i].itemtype = TYPE_ADR;
308 blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
313 /* The standard doesn't say anything about return value checking, but it */
314 /* appears to be useful. */
316 if (rettype != descr->returntype.decltype)
317 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
321 /* XXX it could be considered if we should do typechecking here in the future */
323 static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
325 java_objectarray *params)
329 typedesc *paramtypes;
334 paramcount = descr->paramcount;
335 paramtypes = descr->paramtypes;
337 /* if method is non-static fill first block and skip `this' pointer */
343 blk[0].itemtype = TYPE_ADR;
344 blk[0].item = PTR_TO_ITEM(obj);
351 for (j = 0; j < paramcount; i++, j++, paramtypes++) {
352 switch (paramtypes->type) {
353 /* primitive types */
358 param = params->data[j];
362 /* internally used data type */
363 blk[i].itemtype = paramtypes->type;
365 /* convert the value according to its declared type */
367 c = param->vftbl->class;
369 switch (paramtypes->decltype) {
370 case PRIMITIVETYPE_BOOLEAN:
371 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
372 blk[i].item = (s8) ((java_lang_Boolean *) param)->value;
377 case PRIMITIVETYPE_BYTE:
378 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
379 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
384 case PRIMITIVETYPE_CHAR:
385 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
386 blk[i].item = (s8) ((java_lang_Character *) param)->value;
391 case PRIMITIVETYPE_SHORT:
392 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
393 blk[i].item = (s8) ((java_lang_Short *) param)->value;
394 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
395 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
400 case PRIMITIVETYPE_INT:
401 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
402 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
403 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
404 blk[i].item = (s8) ((java_lang_Short *) param)->value;
405 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
406 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
411 case PRIMITIVETYPE_LONG:
412 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
413 blk[i].item = (s8) ((java_lang_Long *) param)->value;
414 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
415 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
416 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
417 blk[i].item = (s8) ((java_lang_Short *) param)->value;
418 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
419 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
424 case PRIMITIVETYPE_FLOAT:
425 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
426 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
431 case PRIMITIVETYPE_DOUBLE:
432 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
433 *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Float *) param)->value;
434 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
435 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
442 } /* end declared type switch */
446 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
449 if (params->data[j] != 0) {
450 if (paramtypes->arraydim > 0) {
451 if (!builtin_arrayinstanceof(params->data[j], c))
455 if (!builtin_instanceof(params->data[j], c))
459 blk[i].itemtype = TYPE_ADR;
460 blk[i].item = PTR_TO_ITEM(params->data[j]);
465 } /* end param type switch */
467 } /* end param loop */
470 /* *rettype = descr->returntype.decltype; */
475 *exceptionptr = new_illegalargumentexception();
480 static jmethodID get_virtual(jobject obj, jmethodID methodID)
482 if (obj->vftbl->class == methodID->class)
485 return class_resolvemethod(obj->vftbl->class, methodID->name,
486 methodID->descriptor);
490 static jmethodID get_nonvirtual(jclass clazz, jmethodID methodID)
492 if (clazz == methodID->class)
495 /* class_resolvemethod -> classfindmethod? (JOWENN) */
496 return class_resolvemethod(clazz, methodID->name, methodID->descriptor);
500 static jobject callObjectMethod(jobject obj, jmethodID methodID, va_list args)
507 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
511 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
512 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
513 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
517 if (obj && !builtin_instanceof(obj, methodID->class)) {
518 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
522 argcount = methodID->parseddesc->paramcount;
524 blk = MNEW(jni_callblock, argcount);
526 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_ADR);
528 STATISTICS(jnicallXmethodnvokation());
530 ret = asm_calljavafunction2(methodID,
532 argcount * sizeof(jni_callblock),
535 MFREE(blk, jni_callblock, argcount);
542 core function for integer class methods (bool, byte, short, integer)
543 This is basically needed for i386
545 static jint callIntegerMethod(jobject obj, jmethodID methodID, int retType, va_list args)
551 STATISTICS(jniinvokation());
554 log_text("JNI-Call: CallObjectMethodV");
555 utf_display(methodID->name);
556 utf_display(methodID->descriptor);
557 printf("\nParmaeter count: %d\n",argcount);
558 utf_display(obj->vftbl->class->name);
562 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
566 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
567 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
568 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
572 if (obj && !builtin_instanceof(obj, methodID->class)) {
573 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
577 argcount = methodID->parseddesc->paramcount;
579 blk = MNEW(jni_callblock, argcount);
581 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
583 STATISTICS(jnicallXmethodnvokation());
585 ret = asm_calljavafunction2int(methodID,
587 argcount * sizeof(jni_callblock),
590 MFREE(blk, jni_callblock, argcount);
596 /* callLongMethod **************************************************************
598 Core function for long class functions.
600 *******************************************************************************/
602 static jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
608 STATISTICS(jniinvokation());
611 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
615 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
616 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
617 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
621 if (obj && !builtin_instanceof(obj, methodID->class)) {
622 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
626 argcount = methodID->parseddesc->paramcount;
628 blk = MNEW(jni_callblock, argcount);
630 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_LNG);
632 STATISTICS(jnicallXmethodnvokation());
634 ret = asm_calljavafunction2long(methodID,
636 argcount * sizeof(jni_callblock),
639 MFREE(blk, jni_callblock, argcount);
645 /*core function for float class methods (float,double)*/
646 static jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,int retType)
648 int argcount = methodID->parseddesc->paramcount;
652 STATISTICS(jniinvokation());
657 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
658 log_text("Too many arguments. CallObjectMethod does not support that");
662 blk = MNEW(jni_callblock, /*4 */ argcount+2);
664 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
666 /* printf("parameter: obj: %p",blk[0].item); */
668 STATISTICS(jnicallXmethodnvokation());
670 ret = asm_calljavafunction2double(methodID,
672 (argcount + 1) * sizeof(jni_callblock),
675 MFREE(blk, jni_callblock, argcount + 1);
676 /* printf("(CallObjectMethodV)-->%p\n",ret); */
682 static void cacao_jni_CallVoidMethod(jobject obj, jmethodID m, va_list ap)
688 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
692 if (!( ((m->flags & ACC_STATIC) && (obj == 0)) ||
693 ((!(m->flags & ACC_STATIC)) && (obj != 0)) )) {
694 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
698 if (obj && !builtin_instanceof(obj, m->class)) {
699 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
703 paramcount = m->parseddesc->paramcount;
705 /* #error XXX does not work on intrp, but on JIT */
706 if (!(m->flags & ACC_STATIC))
709 blk = MNEW(jni_callblock, paramcount);
711 fill_callblock_from_vargs(obj, m->parseddesc, blk, ap, TYPE_VOID);
713 STATISTICS(jnicallXmethodnvokation());
715 (void) asm_calljavafunction2(m,
717 paramcount * sizeof(jni_callblock),
720 MFREE(blk, jni_callblock, paramcount);
726 /* GetVersion ******************************************************************
728 Returns the major version number in the higher 16 bits and the
729 minor version number in the lower 16 bits.
731 *******************************************************************************/
733 jint GetVersion(JNIEnv *env)
735 STATISTICS(jniinvokation());
737 /* we support JNI 1.4 */
739 return JNI_VERSION_1_4;
743 /* Class Operations ***********************************************************/
745 /* DefineClass *****************************************************************
747 Loads a class from a buffer of raw class data. The buffer
748 containing the raw class data is not referenced by the VM after the
749 DefineClass call returns, and it may be discarded if desired.
751 *******************************************************************************/
753 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
754 const jbyte *buf, jsize bufLen)
756 java_lang_ClassLoader *cl;
761 STATISTICS(jniinvokation());
763 cl = (java_lang_ClassLoader *) loader;
764 s = javastring_new_char(name);
765 ba = (java_bytearray *) buf;
767 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
770 return (jclass) NewLocalRef(env, (jobject) c);
774 /* FindClass *******************************************************************
776 This function loads a locally-defined class. It searches the
777 directories and zip files specified by the CLASSPATH environment
778 variable for the class with the specified name.
780 *******************************************************************************/
782 jclass FindClass(JNIEnv *env, const char *name)
786 java_objectheader *cl;
788 STATISTICS(jniinvokation());
790 u = utf_new_char_classname((char *) name);
792 /* check stacktrace for classloader, if one found use it, otherwise use */
793 /* the system classloader */
795 #if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__)
796 /* these JITs support stacktraces, and so does the interpreter */
798 cl = cacao_currentClassLoader();
800 # if defined(ENABLE_INTRP)
801 /* the interpreter supports stacktraces, even if the JIT does not */
804 cl = cacao_currentClassLoader();
810 if (!(c = load_class_from_classloader(u, cl)))
816 return (jclass) NewLocalRef(env, (jobject) c);
820 /* FromReflectedMethod *********************************************************
822 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
823 object to a method ID.
825 *******************************************************************************/
827 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
833 STATISTICS(jniinvokation());
838 if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
839 java_lang_reflect_Method *rm;
841 rm = (java_lang_reflect_Method *) method;
842 c = (classinfo *) (rm->declaringClass);
845 } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
846 java_lang_reflect_Constructor *rc;
848 rc = (java_lang_reflect_Constructor *) method;
849 c = (classinfo *) (rc->clazz);
855 if ((slot < 0) || (slot >= c->methodscount)) {
856 /* this usually means a severe internal cacao error or somebody
857 tempered around with the reflected method */
858 log_text("error illegal slot for method in class(FromReflectedMethod)");
862 mi = &(c->methods[slot]);
868 /* GetSuperclass ***************************************************************
870 If clazz represents any class other than the class Object, then
871 this function returns the object that represents the superclass of
872 the class specified by clazz.
874 *******************************************************************************/
876 jclass GetSuperclass(JNIEnv *env, jclass sub)
880 STATISTICS(jniinvokation());
882 c = ((classinfo *) sub)->super.cls;
887 return (jclass) NewLocalRef(env, (jobject) c);
891 /* IsAssignableFrom ************************************************************
893 Determines whether an object of sub can be safely cast to sup.
895 *******************************************************************************/
897 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
899 STATISTICS(jniinvokation());
901 return Java_java_lang_VMClass_isAssignableFrom(env,
903 (java_lang_Class *) sup,
904 (java_lang_Class *) sub);
908 /* Throw ***********************************************************************
910 Causes a java.lang.Throwable object to be thrown.
912 *******************************************************************************/
914 jint Throw(JNIEnv *env, jthrowable obj)
916 STATISTICS(jniinvokation());
918 *exceptionptr = (java_objectheader *) obj;
924 /* ThrowNew ********************************************************************
926 Constructs an exception object from the specified class with the
927 message specified by message and causes that exception to be
930 *******************************************************************************/
932 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
934 java_lang_Throwable *o;
937 STATISTICS(jniinvokation());
939 s = (java_lang_String *) javastring_new_char(msg);
941 /* instantiate exception object */
943 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
949 *exceptionptr = (java_objectheader *) o;
955 /* ExceptionOccurred ***********************************************************
957 Determines if an exception is being thrown. The exception stays
958 being thrown until either the native code calls ExceptionClear(),
959 or the Java code handles the exception.
961 *******************************************************************************/
963 jthrowable ExceptionOccurred(JNIEnv *env)
965 java_objectheader *e;
967 STATISTICS(jniinvokation());
971 return NewLocalRef(env, (jthrowable) e);
975 /* ExceptionDescribe ***********************************************************
977 Prints an exception and a backtrace of the stack to a system
978 error-reporting channel, such as stderr. This is a convenience
979 routine provided for debugging.
981 *******************************************************************************/
983 void ExceptionDescribe(JNIEnv *env)
985 java_objectheader *e;
988 STATISTICS(jniinvokation());
993 /* clear exception, because we are calling jit code again */
995 *exceptionptr = NULL;
997 /* get printStackTrace method from exception class */
999 m = class_resolveclassmethod(e->vftbl->class,
1000 utf_printStackTrace,
1006 /* XXX what should we do? */
1009 /* print the stacktrace */
1011 asm_calljavafunction(m, e, NULL, NULL, NULL);
1016 /* ExceptionClear **************************************************************
1018 Clears any exception that is currently being thrown. If no
1019 exception is currently being thrown, this routine has no effect.
1021 *******************************************************************************/
1023 void ExceptionClear(JNIEnv *env)
1025 STATISTICS(jniinvokation());
1027 *exceptionptr = NULL;
1031 /* FatalError ******************************************************************
1033 Raises a fatal error and does not expect the VM to recover. This
1034 function does not return.
1036 *******************************************************************************/
1038 void FatalError(JNIEnv *env, const char *msg)
1040 STATISTICS(jniinvokation());
1042 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
1046 /* PushLocalFrame **************************************************************
1048 Creates a new local reference frame, in which at least a given
1049 number of local references can be created.
1051 *******************************************************************************/
1053 jint PushLocalFrame(JNIEnv* env, jint capacity)
1055 STATISTICS(jniinvokation());
1057 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
1064 /* PopLocalFrame ***************************************************************
1066 Pops off the current local reference frame, frees all the local
1067 references, and returns a local reference in the previous local
1068 reference frame for the given result object.
1070 *******************************************************************************/
1072 jobject PopLocalFrame(JNIEnv* env, jobject result)
1074 STATISTICS(jniinvokation());
1076 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
1080 /* add local reference and return the value */
1082 return NewLocalRef(env, NULL);
1086 /* DeleteLocalRef **************************************************************
1088 Deletes the local reference pointed to by localRef.
1090 *******************************************************************************/
1092 void DeleteLocalRef(JNIEnv *env, jobject localRef)
1094 java_objectheader *o;
1095 localref_table *lrt;
1098 STATISTICS(jniinvokation());
1100 o = (java_objectheader *) localRef;
1102 /* get local reference table (thread specific) */
1104 lrt = LOCALREFTABLE;
1106 /* remove the reference */
1108 for (i = 0; i < lrt->capacity; i++) {
1109 if (lrt->refs[i] == o) {
1110 lrt->refs[i] = NULL;
1117 /* this should not happen */
1119 /* if (opt_checkjni) */
1120 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1121 log_text("JNI-DeleteLocalRef: Bad global or local ref passed to JNI");
1125 /* IsSameObject ****************************************************************
1127 Tests whether two references refer to the same Java object.
1129 *******************************************************************************/
1131 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1133 STATISTICS(jniinvokation());
1142 /* NewLocalRef *****************************************************************
1144 Creates a new local reference that refers to the same object as ref.
1146 *******************************************************************************/
1148 jobject NewLocalRef(JNIEnv *env, jobject ref)
1150 localref_table *lrt;
1153 STATISTICS(jniinvokation());
1158 /* get local reference table (thread specific) */
1160 lrt = LOCALREFTABLE;
1162 /* check if we have space for the requested reference */
1164 if (lrt->used == lrt->capacity)
1165 throw_cacao_exception_exit(string_java_lang_InternalError,
1166 "Too many local references");
1168 /* insert the reference */
1170 for (i = 0; i < lrt->capacity; i++) {
1171 if (lrt->refs[i] == NULL) {
1172 lrt->refs[i] = (java_objectheader *) ref;
1179 /* should not happen, just to be sure */
1183 /* keep compiler happy */
1189 /* EnsureLocalCapacity *********************************************************
1191 Ensures that at least a given number of local references can be
1192 created in the current thread
1194 *******************************************************************************/
1196 jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
1198 localref_table *lrt;
1200 STATISTICS(jniinvokation());
1202 /* get local reference table (thread specific) */
1204 lrt = LOCALREFTABLE;
1206 /* check if capacity elements are available in the local references table */
1208 if ((lrt->used + capacity) > lrt->capacity) {
1209 *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
1217 /* AllocObject *****************************************************************
1219 Allocates a new Java object without invoking any of the
1220 constructors for the object. Returns a reference to the object.
1222 *******************************************************************************/
1224 jobject AllocObject(JNIEnv *env, jclass clazz)
1226 java_objectheader *o;
1228 STATISTICS(jniinvokation());
1230 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1232 new_exception_utfmessage(string_java_lang_InstantiationException,
1237 o = builtin_new(clazz);
1239 return NewLocalRef(env, o);
1243 /* NewObject *******************************************************************
1245 Programmers place all arguments that are to be passed to the
1246 constructor immediately following the methodID
1247 argument. NewObject() accepts these arguments and passes them to
1248 the Java method that the programmer wishes to invoke.
1250 *******************************************************************************/
1252 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1254 java_objectheader *o;
1257 STATISTICS(jniinvokation());
1261 o = builtin_new(clazz);
1266 /* call constructor */
1268 va_start(ap, methodID);
1269 cacao_jni_CallVoidMethod(o, methodID, ap);
1272 return NewLocalRef(env, o);
1276 /***********************************************************************************
1278 Constructs a new Java object
1279 arguments that are to be passed to the constructor are placed in va_list args
1281 ***********************************************************************************/
1283 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1285 STATISTICS(jniinvokation());
1287 log_text("JNI-Call: NewObjectV: IMPLEMENT ME!");
1289 return NewLocalRef(env, NULL);
1293 /***********************************************************************************
1295 Constructs a new Java object
1296 arguments that are to be passed to the constructor are placed in
1297 args array of jvalues
1299 ***********************************************************************************/
1301 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1303 STATISTICS(jniinvokation());
1305 log_text("JNI-Call: NewObjectA: IMPLEMENT ME!");
1307 return NewLocalRef(env, NULL);
1311 /* GetObjectClass **************************************************************
1313 Returns the class of an object.
1315 *******************************************************************************/
1317 jclass GetObjectClass(JNIEnv *env, jobject obj)
1321 STATISTICS(jniinvokation());
1323 if (!obj || !obj->vftbl)
1326 c = obj->vftbl->class;
1328 return (jclass) NewLocalRef(env, (jobject) c);
1332 /* IsInstanceOf ****************************************************************
1334 Tests whether an object is an instance of a class.
1336 *******************************************************************************/
1338 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1340 STATISTICS(jniinvokation());
1342 return Java_java_lang_VMClass_isInstance(env,
1344 (java_lang_Class *) clazz,
1345 (java_lang_Object *) obj);
1349 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1351 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1353 java_lang_reflect_Field *f;
1355 jfieldID fid; /* the JNI-fieldid of the wrapping object */
1357 STATISTICS(jniinvokation());
1359 /*log_text("JNI-Call: FromReflectedField");*/
1361 f=(java_lang_reflect_Field *)field;
1363 c=(classinfo*)(f->declaringClass);
1364 if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1365 /*this usually means a severe internal cacao error or somebody
1366 tempered around with the reflected method*/
1367 log_text("error illegal slot for field in class(FromReflectedField)");
1370 fid=&(c->fields[f->slot]);
1375 /* ToReflectedMethod ***********************************************************
1377 Converts a method ID derived from cls to an instance of the
1378 java.lang.reflect.Method class or to an instance of the
1379 java.lang.reflect.Constructor class.
1381 *******************************************************************************/
1383 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1385 STATISTICS(jniinvokation());
1387 log_text("JNI-Call: ToReflectedMethod: IMPLEMENT ME!");
1393 /* ToReflectedField ************************************************************
1395 Converts a field ID derived from cls to an instance of the
1396 java.lang.reflect.Field class.
1398 *******************************************************************************/
1400 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1403 STATISTICS(jniinvokation());
1405 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1411 /* Calling Instance Methods ***************************************************/
1413 /* GetMethodID *****************************************************************
1415 Returns the method ID for an instance (nonstatic) method of a class
1416 or interface. The method may be defined in one of the clazz's
1417 superclasses and inherited by clazz. The method is determined by
1418 its name and signature.
1420 GetMethodID() causes an uninitialized class to be initialized.
1422 *******************************************************************************/
1424 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1432 STATISTICS(jniinvokation());
1434 c = (classinfo *) clazz;
1439 if (!(c->state & CLASS_INITIALIZED))
1440 if (!initialize_class(c))
1443 /* try to get the method of the class or one of it's superclasses */
1445 uname = utf_new_char((char *) name);
1446 udesc = utf_new_char((char *) sig);
1448 m = class_resolvemethod(clazz, uname, udesc);
1450 if (!m || (m->flags & ACC_STATIC)) {
1451 *exceptionptr = exceptions_new_nosuchmethoderror(c, uname, udesc);
1460 /******************** JNI-functions for calling instance methods ******************/
1462 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1464 java_objectheader* ret;
1467 STATISTICS(jniinvokation());
1469 va_start(vaargs, methodID);
1470 ret = callObjectMethod(obj, methodID, vaargs);
1473 return NewLocalRef(env, ret);
1477 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1479 java_objectheader* ret;
1481 STATISTICS(jniinvokation());
1483 ret = callObjectMethod(obj, methodID, args);
1485 return NewLocalRef(env, ret);
1489 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1491 STATISTICS(jniinvokation());
1493 log_text("JNI-Call: CallObjectMethodA: IMPLEMENT ME!");
1495 return NewLocalRef(env, NULL);
1501 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1506 STATISTICS(jniinvokation());
1508 /* log_text("JNI-Call: CallBooleanMethod");*/
1510 va_start(vaargs,methodID);
1511 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1517 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1519 STATISTICS(jniinvokation());
1521 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
1525 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1527 STATISTICS(jniinvokation());
1529 log_text("JNI-Call: CallBooleanMethodA");
1534 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1539 STATISTICS(jniinvokation());
1541 /* log_text("JNI-Call: CallVyteMethod");*/
1543 va_start(vaargs,methodID);
1544 ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
1550 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1552 /* log_text("JNI-Call: CallByteMethodV");*/
1554 STATISTICS(jniinvokation());
1556 return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
1560 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1562 STATISTICS(jniinvokation());
1564 log_text("JNI-Call: CallByteMethodA: IMPLEMENT ME!");
1570 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1575 STATISTICS(jniinvokation());
1577 /* log_text("JNI-Call: CallCharMethod");*/
1579 va_start(vaargs,methodID);
1580 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
1587 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1589 STATISTICS(jniinvokation());
1591 /* log_text("JNI-Call: CallCharMethodV");*/
1593 return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
1597 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1599 STATISTICS(jniinvokation());
1601 log_text("JNI-Call: CallCharMethodA: IMPLEMENT ME!");
1607 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1612 STATISTICS(jniinvokation());
1614 /* log_text("JNI-Call: CallShortMethod");*/
1616 va_start(vaargs, methodID);
1617 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
1624 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1626 STATISTICS(jniinvokation());
1628 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
1632 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1634 STATISTICS(jniinvokation());
1636 log_text("JNI-Call: CallShortMethodA: IMPLEMENT ME!");
1643 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1648 STATISTICS(jniinvokation());
1650 va_start(vaargs,methodID);
1651 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
1658 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1660 STATISTICS(jniinvokation());
1662 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
1666 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1668 STATISTICS(jniinvokation());
1670 log_text("JNI-Call: CallIntMethodA: IMPLEMENT ME!");
1677 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1682 STATISTICS(jniinvokation());
1684 va_start(vaargs,methodID);
1685 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1692 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1694 STATISTICS(jniinvokation());
1696 return callLongMethod(obj,get_virtual(obj, methodID),args);
1700 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1702 STATISTICS(jniinvokation());
1704 log_text("JNI-Call: CallLongMethodA: IMPLEMENT ME!");
1711 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1716 STATISTICS(jniinvokation());
1718 /* log_text("JNI-Call: CallFloatMethod");*/
1720 va_start(vaargs,methodID);
1721 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
1728 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1730 STATISTICS(jniinvokation());
1732 /* log_text("JNI-Call: CallFloatMethodV"); */
1734 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
1738 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1740 STATISTICS(jniinvokation());
1742 log_text("JNI-Call: CallFloatMethodA: IMPLEMENT ME!");
1749 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1754 STATISTICS(jniinvokation());
1756 /* log_text("JNI-Call: CallDoubleMethod");*/
1758 va_start(vaargs,methodID);
1759 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
1766 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1768 STATISTICS(jniinvokation());
1770 /* log_text("JNI-Call: CallDoubleMethodV"); */
1772 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
1776 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1778 STATISTICS(jniinvokation());
1780 log_text("JNI-Call: CallDoubleMethodA: IMPLEMENT ME!");
1787 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1791 STATISTICS(jniinvokation());
1793 va_start(vaargs,methodID);
1794 (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
1799 void CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1801 STATISTICS(jniinvokation());
1803 /* log_text("JNI-Call: CallVoidMethodV"); */
1805 (void) callIntegerMethod(obj, get_virtual(obj, methodID), TYPE_VOID,args);
1809 void CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1811 STATISTICS(jniinvokation());
1813 log_text("JNI-Call: CallVoidMethodA: IMPLEMENT ME!");
1818 jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1820 STATISTICS(jniinvokation());
1822 log_text("JNI-Call: CallNonvirtualObjectMethod: IMPLEMENT ME!");
1824 return NewLocalRef(env, NULL);
1828 jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1830 STATISTICS(jniinvokation());
1832 log_text("JNI-Call: CallNonvirtualObjectMethodV: IMPLEMENT ME!");
1834 return NewLocalRef(env, NULL);
1838 jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1840 STATISTICS(jniinvokation());
1842 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1844 return NewLocalRef(env, NULL);
1849 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1854 STATISTICS(jniinvokation());
1856 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1858 va_start(vaargs,methodID);
1859 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1867 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1869 STATISTICS(jniinvokation());
1871 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1873 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
1877 jboolean CallNonvirtualBooleanMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1879 STATISTICS(jniinvokation());
1881 log_text("JNI-Call: CallNonvirtualBooleanMethodA: IMPLEMENT ME!");
1887 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1892 STATISTICS(jniinvokation());
1894 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1896 va_start(vaargs,methodID);
1897 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
1904 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1906 STATISTICS(jniinvokation());
1908 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1910 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
1914 jbyte CallNonvirtualByteMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1916 STATISTICS(jniinvokation());
1918 log_text("JNI-Call: CallNonvirtualByteMethodA: IMPLEMENT ME!");
1925 jchar CallNonvirtualCharMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1930 STATISTICS(jniinvokation());
1932 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1934 va_start(vaargs,methodID);
1935 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
1942 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1944 STATISTICS(jniinvokation());
1946 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1948 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
1952 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1954 STATISTICS(jniinvokation());
1956 log_text("JNI-Call: CallNonvirtualCharMethodA: IMPLEMENT ME!");
1963 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1968 STATISTICS(jniinvokation());
1970 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1972 va_start(vaargs,methodID);
1973 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
1980 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1982 STATISTICS(jniinvokation());
1984 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1986 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
1990 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1992 STATISTICS(jniinvokation());
1994 log_text("JNI-Call: CallNonvirtualShortMethodA: IMPLEMENT ME!");
2001 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2006 STATISTICS(jniinvokation());
2008 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
2010 va_start(vaargs,methodID);
2011 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
2018 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2020 STATISTICS(jniinvokation());
2022 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
2024 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
2028 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2030 STATISTICS(jniinvokation());
2032 log_text("JNI-Call: CallNonvirtualIntMethodA: IMPLEMENT ME!");
2039 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2041 STATISTICS(jniinvokation());
2043 log_text("JNI-Call: CallNonvirtualLongMethod: IMPLEMENT ME!");
2049 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2051 STATISTICS(jniinvokation());
2053 log_text("JNI-Call: CallNonvirtualLongMethodV: IMPLEMENT ME!");
2059 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2061 STATISTICS(jniinvokation());
2063 log_text("JNI-Call: CallNonvirtualLongMethodA: IMPLEMENT ME!");
2070 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2075 STATISTICS(jniinvokation());
2077 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
2079 va_start(vaargs,methodID);
2080 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
2087 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2089 STATISTICS(jniinvokation());
2091 /* log_text("JNI-Call: CallNonvirtualFloatMethodV"); */
2093 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
2097 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2099 STATISTICS(jniinvokation());
2101 log_text("JNI-Call: CallNonvirtualFloatMethodA: IMPLEMENT ME!");
2108 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2113 STATISTICS(jniinvokation());
2115 /* log_text("JNI-Call: CallNonvirtualDoubleMethod"); */
2117 va_start(vaargs,methodID);
2118 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
2125 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2127 STATISTICS(jniinvokation());
2129 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
2131 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
2135 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2137 STATISTICS(jniinvokation());
2139 log_text("JNI-Call: CallNonvirtualDoubleMethodA: IMPLEMENT ME!");
2146 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2150 STATISTICS(jniinvokation());
2152 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
2154 va_start(vaargs,methodID);
2155 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
2160 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2162 STATISTICS(jniinvokation());
2164 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
2166 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
2170 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
2172 STATISTICS(jniinvokation());
2174 log_text("JNI-Call: CallNonvirtualVoidMethodA: IMPLEMENT ME!");
2178 /* Accessing Fields of Objects ************************************************/
2180 /* GetFieldID ******************************************************************
2182 Returns the field ID for an instance (nonstatic) field of a
2183 class. The field is specified by its name and signature. The
2184 Get<type>Field and Set<type>Field families of accessor functions
2185 use field IDs to retrieve object fields.
2187 *******************************************************************************/
2189 jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2196 STATISTICS(jniinvokation());
2198 uname = utf_new_char((char *) name);
2199 udesc = utf_new_char((char *) sig);
2201 f = class_findfield(clazz, uname, udesc);
2204 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2210 /* Get<type>Field Routines *****************************************************
2212 This family of accessor routines returns the value of an instance
2213 (nonstatic) field of an object. The field to access is specified by
2214 a field ID obtained by calling GetFieldID().
2216 *******************************************************************************/
2218 jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2220 java_objectheader *o;
2222 STATISTICS(jniinvokation());
2224 o = GET_FIELD(obj, java_objectheader*, fieldID);
2226 return NewLocalRef(env, o);
2230 jboolean GetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID)
2234 STATISTICS(jniinvokation());
2236 i = GET_FIELD(obj, s4, fieldID);
2238 return (jboolean) i;
2242 jbyte GetByteField(JNIEnv *env, jobject obj, jfieldID fieldID)
2246 STATISTICS(jniinvokation());
2248 i = GET_FIELD(obj, s4, fieldID);
2254 jchar GetCharField(JNIEnv *env, jobject obj, jfieldID fieldID)
2258 STATISTICS(jniinvokation());
2260 i = GET_FIELD(obj, s4, fieldID);
2266 jshort GetShortField(JNIEnv *env, jobject obj, jfieldID fieldID)
2270 STATISTICS(jniinvokation());
2272 i = GET_FIELD(obj, s4, fieldID);
2278 jint GetIntField(JNIEnv *env, jobject obj, jfieldID fieldID)
2282 STATISTICS(jniinvokation());
2284 i = GET_FIELD(obj, s4, fieldID);
2290 jlong GetLongField(JNIEnv *env, jobject obj, jfieldID fieldID)
2294 STATISTICS(jniinvokation());
2296 l = GET_FIELD(obj, s8, fieldID);
2302 jfloat GetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID)
2306 STATISTICS(jniinvokation());
2308 f = GET_FIELD(obj, float, fieldID);
2314 jdouble GetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID)
2318 STATISTICS(jniinvokation());
2320 d = GET_FIELD(obj, double, fieldID);
2326 /* Set<type>Field Routines *****************************************************
2328 This family of accessor routines sets the value of an instance
2329 (nonstatic) field of an object. The field to access is specified by
2330 a field ID obtained by calling GetFieldID().
2332 *******************************************************************************/
2334 void SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value)
2336 STATISTICS(jniinvokation());
2338 SET_FIELD(obj, java_objectheader*, fieldID, value);
2342 void SetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID, jboolean value)
2344 STATISTICS(jniinvokation());
2346 SET_FIELD(obj, s4, fieldID, value);
2350 void SetByteField(JNIEnv *env, jobject obj, jfieldID fieldID, jbyte value)
2352 STATISTICS(jniinvokation());
2354 SET_FIELD(obj, s4, fieldID, value);
2358 void SetCharField(JNIEnv *env, jobject obj, jfieldID fieldID, jchar value)
2360 STATISTICS(jniinvokation());
2362 SET_FIELD(obj, s4, fieldID, value);
2366 void SetShortField(JNIEnv *env, jobject obj, jfieldID fieldID, jshort value)
2368 STATISTICS(jniinvokation());
2370 SET_FIELD(obj, s4, fieldID, value);
2374 void SetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint value)
2376 STATISTICS(jniinvokation());
2378 SET_FIELD(obj, s4, fieldID, value);
2382 void SetLongField(JNIEnv *env, jobject obj, jfieldID fieldID, jlong value)
2384 STATISTICS(jniinvokation());
2386 SET_FIELD(obj, s8, fieldID, value);
2390 void SetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID, jfloat value)
2392 STATISTICS(jniinvokation());
2394 SET_FIELD(obj, float, fieldID, value);
2398 void SetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID, jdouble value)
2400 STATISTICS(jniinvokation());
2402 SET_FIELD(obj, double, fieldID, value);
2406 /* Calling Static Methods *****************************************************/
2408 /* GetStaticMethodID ***********************************************************
2410 Returns the method ID for a static method of a class. The method is
2411 specified by its name and signature.
2413 GetStaticMethodID() causes an uninitialized class to be
2416 *******************************************************************************/
2418 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2426 STATISTICS(jniinvokation());
2428 c = (classinfo *) clazz;
2433 if (!(c->state & CLASS_INITIALIZED))
2434 if (!initialize_class(c))
2437 /* try to get the static method of the class */
2439 uname = utf_new_char((char *) name);
2440 udesc = utf_new_char((char *) sig);
2442 m = class_resolvemethod(c, uname, udesc);
2444 if (!m || !(m->flags & ACC_STATIC)) {
2445 *exceptionptr = exceptions_new_nosuchmethoderror(c, uname, udesc);
2454 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2456 java_objectheader *ret;
2459 STATISTICS(jniinvokation());
2461 va_start(vaargs, methodID);
2462 ret = callObjectMethod(0, methodID, vaargs);
2465 return NewLocalRef(env, ret);
2469 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2471 java_objectheader *ret;
2473 STATISTICS(jniinvokation());
2475 ret = callObjectMethod(0, methodID, args);
2477 return NewLocalRef(env, ret);
2481 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2483 STATISTICS(jniinvokation());
2485 log_text("JNI-Call: CallStaticObjectMethodA: IMPLEMENT ME!");
2487 return NewLocalRef(env, NULL);
2491 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2496 STATISTICS(jniinvokation());
2498 va_start(vaargs, methodID);
2499 ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
2506 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2508 STATISTICS(jniinvokation());
2510 return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
2514 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2516 STATISTICS(jniinvokation());
2518 log_text("JNI-Call: CallStaticBooleanMethodA: IMPLEMENT ME!");
2524 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2529 STATISTICS(jniinvokation());
2531 va_start(vaargs, methodID);
2532 ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
2539 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2541 STATISTICS(jniinvokation());
2543 return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
2547 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2549 STATISTICS(jniinvokation());
2551 log_text("JNI-Call: CallStaticByteMethodA: IMPLEMENT ME!");
2557 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2562 STATISTICS(jniinvokation());
2564 va_start(vaargs, methodID);
2565 ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
2572 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2574 STATISTICS(jniinvokation());
2576 return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
2580 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2582 STATISTICS(jniinvokation());
2584 log_text("JNI-Call: CallStaticCharMethodA: IMPLEMENT ME!");
2590 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2595 STATISTICS(jniinvokation());
2597 va_start(vaargs, methodID);
2598 ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
2605 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2607 STATISTICS(jniinvokation());
2609 return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
2613 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2615 STATISTICS(jniinvokation());
2617 log_text("JNI-Call: CallStaticShortMethodA: IMPLEMENT ME!");
2623 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2628 STATISTICS(jniinvokation());
2630 va_start(vaargs, methodID);
2631 ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
2638 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2640 STATISTICS(jniinvokation());
2642 return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
2646 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2648 STATISTICS(jniinvokation());
2650 log_text("JNI-Call: CallStaticIntMethodA: IMPLEMENT ME!");
2656 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2661 STATISTICS(jniinvokation());
2663 va_start(vaargs, methodID);
2664 ret = callLongMethod(0, methodID, vaargs);
2671 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
2674 STATISTICS(jniinvokation());
2676 return callLongMethod(0, methodID, args);
2680 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2682 STATISTICS(jniinvokation());
2684 log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!");
2691 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2696 STATISTICS(jniinvokation());
2698 va_start(vaargs, methodID);
2699 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
2706 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2708 STATISTICS(jniinvokation());
2710 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
2715 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2717 STATISTICS(jniinvokation());
2719 log_text("JNI-Call: CallStaticFloatMethodA: IMPLEMENT ME!");
2725 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2730 STATISTICS(jniinvokation());
2732 va_start(vaargs,methodID);
2733 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
2740 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2742 STATISTICS(jniinvokation());
2744 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
2748 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2750 STATISTICS(jniinvokation());
2752 log_text("JNI-Call: CallStaticDoubleMethodA: IMPLEMENT ME!");
2758 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2762 STATISTICS(jniinvokation());
2764 va_start(vaargs, methodID);
2765 (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
2770 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2772 STATISTICS(jniinvokation());
2774 (void) callIntegerMethod(0, methodID, TYPE_VOID, args);
2778 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2780 STATISTICS(jniinvokation());
2782 log_text("JNI-Call: CallStaticVoidMethodA: IMPLEMENT ME!");
2786 /* Accessing Static Fields ****************************************************/
2788 /* GetStaticFieldID ************************************************************
2790 Returns the field ID for a static field of a class. The field is
2791 specified by its name and signature. The GetStatic<type>Field and
2792 SetStatic<type>Field families of accessor functions use field IDs
2793 to retrieve static fields.
2795 *******************************************************************************/
2797 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2801 STATISTICS(jniinvokation());
2803 f = class_findfield(clazz,
2804 utf_new_char((char *) name),
2805 utf_new_char((char *) sig));
2808 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2814 /* GetStatic<type>Field ********************************************************
2816 This family of accessor routines returns the value of a static
2819 *******************************************************************************/
2821 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2823 STATISTICS(jniinvokation());
2825 if (!(clazz->state & CLASS_INITIALIZED))
2826 if (!initialize_class(clazz))
2829 return NewLocalRef(env, fieldID->value.a);
2833 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2835 STATISTICS(jniinvokation());
2837 if (!(clazz->state & CLASS_INITIALIZED))
2838 if (!initialize_class(clazz))
2841 return fieldID->value.i;
2845 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2847 STATISTICS(jniinvokation());
2849 if (!(clazz->state & CLASS_INITIALIZED))
2850 if (!initialize_class(clazz))
2853 return fieldID->value.i;
2857 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2859 STATISTICS(jniinvokation());
2861 if (!(clazz->state & CLASS_INITIALIZED))
2862 if (!initialize_class(clazz))
2865 return fieldID->value.i;
2869 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2871 STATISTICS(jniinvokation());
2873 if (!(clazz->state & CLASS_INITIALIZED))
2874 if (!initialize_class(clazz))
2877 return fieldID->value.i;
2881 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2883 STATISTICS(jniinvokation());
2885 if (!(clazz->state & CLASS_INITIALIZED))
2886 if (!initialize_class(clazz))
2889 return fieldID->value.i;
2893 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2895 STATISTICS(jniinvokation());
2897 if (!(clazz->state & CLASS_INITIALIZED))
2898 if (!initialize_class(clazz))
2901 return fieldID->value.l;
2905 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2907 STATISTICS(jniinvokation());
2909 if (!(clazz->state & CLASS_INITIALIZED))
2910 if (!initialize_class(clazz))
2913 return fieldID->value.f;
2917 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2919 STATISTICS(jniinvokation());
2921 if (!(clazz->state & CLASS_INITIALIZED))
2922 if (!initialize_class(clazz))
2925 return fieldID->value.d;
2929 /* SetStatic<type>Field *******************************************************
2931 This family of accessor routines sets the value of a static field
2934 *******************************************************************************/
2936 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2938 STATISTICS(jniinvokation());
2940 if (!(clazz->state & CLASS_INITIALIZED))
2941 if (!initialize_class(clazz))
2944 fieldID->value.a = value;
2948 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2950 STATISTICS(jniinvokation());
2952 if (!(clazz->state & CLASS_INITIALIZED))
2953 if (!initialize_class(clazz))
2956 fieldID->value.i = value;
2960 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2962 STATISTICS(jniinvokation());
2964 if (!(clazz->state & CLASS_INITIALIZED))
2965 if (!initialize_class(clazz))
2968 fieldID->value.i = value;
2972 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2974 STATISTICS(jniinvokation());
2976 if (!(clazz->state & CLASS_INITIALIZED))
2977 if (!initialize_class(clazz))
2980 fieldID->value.i = value;
2984 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2986 STATISTICS(jniinvokation());
2988 if (!(clazz->state & CLASS_INITIALIZED))
2989 if (!initialize_class(clazz))
2992 fieldID->value.i = value;
2996 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2998 STATISTICS(jniinvokation());
3000 if (!(clazz->state & CLASS_INITIALIZED))
3001 if (!initialize_class(clazz))
3004 fieldID->value.i = value;
3008 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
3010 STATISTICS(jniinvokation());
3012 if (!(clazz->state & CLASS_INITIALIZED))
3013 if (!initialize_class(clazz))
3016 fieldID->value.l = value;
3020 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
3022 STATISTICS(jniinvokation());
3024 if (!(clazz->state & CLASS_INITIALIZED))
3025 if (!initialize_class(clazz))
3028 fieldID->value.f = value;
3032 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
3034 STATISTICS(jniinvokation());
3036 if (!(clazz->state & CLASS_INITIALIZED))
3037 if (!initialize_class(clazz))
3040 fieldID->value.d = value;
3044 /* String Operations **********************************************************/
3046 /* NewString *******************************************************************
3048 Create new java.lang.String object from an array of Unicode
3051 *******************************************************************************/
3053 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
3055 java_lang_String *s;
3059 STATISTICS(jniinvokation());
3061 s = (java_lang_String *) builtin_new(class_java_lang_String);
3062 a = builtin_newarray_char(len);
3064 /* javastring or characterarray could not be created */
3069 for (i = 0; i < len; i++)
3070 a->data[i] = buf[i];
3076 return (jstring) NewLocalRef(env, (jobject) s);
3080 static jchar emptyStringJ[]={0,0};
3082 /* GetStringLength *************************************************************
3084 Returns the length (the count of Unicode characters) of a Java
3087 *******************************************************************************/
3089 jsize GetStringLength(JNIEnv *env, jstring str)
3091 return ((java_lang_String *) str)->count;
3095 /******************** convertes javastring to u2-array ****************************/
3097 u2 *javastring_tou2(jstring so)
3099 java_lang_String *s;
3104 STATISTICS(jniinvokation());
3106 s = (java_lang_String *) so;
3116 /* allocate memory */
3118 stringbuffer = MNEW(u2, s->count + 1);
3122 for (i = 0; i < s->count; i++)
3123 stringbuffer[i] = a->data[s->offset + i];
3125 /* terminate string */
3127 stringbuffer[i] = '\0';
3129 return stringbuffer;
3133 /* GetStringChars **************************************************************
3135 Returns a pointer to the array of Unicode characters of the
3136 string. This pointer is valid until ReleaseStringchars() is called.
3138 *******************************************************************************/
3140 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
3144 STATISTICS(jniinvokation());
3146 jc = javastring_tou2(str);
3158 return emptyStringJ;
3162 /* ReleaseStringChars **********************************************************
3164 Informs the VM that the native code no longer needs access to
3165 chars. The chars argument is a pointer obtained from string using
3168 *******************************************************************************/
3170 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
3172 STATISTICS(jniinvokation());
3174 if (chars == emptyStringJ)
3177 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
3181 /* NewStringUTF ****************************************************************
3183 Constructs a new java.lang.String object from an array of UTF-8 characters.
3185 *******************************************************************************/
3187 jstring NewStringUTF(JNIEnv *env, const char *bytes)
3189 java_lang_String *s;
3191 STATISTICS(jniinvokation());
3193 s = javastring_new(utf_new_char(bytes));
3195 return (jstring) NewLocalRef(env, (jobject) s);
3199 /****************** returns the utf8 length in bytes of a string *******************/
3201 jsize GetStringUTFLength (JNIEnv *env, jstring string)
3203 java_lang_String *s = (java_lang_String*) string;
3205 STATISTICS(jniinvokation());
3207 return (jsize) u2_utflength(s->value->data, s->count);
3211 /* GetStringUTFChars ***********************************************************
3213 Returns a pointer to an array of UTF-8 characters of the
3214 string. This array is valid until it is released by
3215 ReleaseStringUTFChars().
3217 *******************************************************************************/
3219 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
3223 STATISTICS(jniinvokation());
3231 u = javastring_toutf((java_lang_String *) string, false);
3240 /* ReleaseStringUTFChars *******************************************************
3242 Informs the VM that the native code no longer needs access to
3243 utf. The utf argument is a pointer derived from string using
3244 GetStringUTFChars().
3246 *******************************************************************************/
3248 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
3250 STATISTICS(jniinvokation());
3252 /* XXX we don't release utf chars right now, perhaps that should be done
3253 later. Since there is always one reference the garbage collector will
3258 /* Array Operations ***********************************************************/
3260 /* GetArrayLength **************************************************************
3262 Returns the number of elements in the array.
3264 *******************************************************************************/
3266 jsize GetArrayLength(JNIEnv *env, jarray array)
3268 STATISTICS(jniinvokation());
3274 /* NewObjectArray **************************************************************
3276 Constructs a new array holding objects in class elementClass. All
3277 elements are initially set to initialElement.
3279 *******************************************************************************/
3281 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
3283 java_objectarray *oa;
3286 STATISTICS(jniinvokation());
3289 *exceptionptr = new_negativearraysizeexception();
3293 oa = builtin_anewarray(length, elementClass);
3298 /* set all elements to initialElement */
3300 for (i = 0; i < length; i++)
3301 oa->data[i] = initialElement;
3303 return (jobjectArray) NewLocalRef(env, (jobject) oa);
3307 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
3311 STATISTICS(jniinvokation());
3313 if (index >= array->header.size) {
3315 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3320 o = array->data[index];
3322 return NewLocalRef(env, o);
3326 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3328 java_objectarray *oa;
3329 java_objectheader *o;
3331 STATISTICS(jniinvokation());
3333 oa = (java_objectarray *) array;
3334 o = (java_objectheader *) val;
3336 if (index >= array->header.size) {
3338 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3343 /* check if the class of value is a subclass of the element class
3346 if (!builtin_canstore(oa, o)) {
3347 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3352 array->data[index] = val;
3356 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3358 java_booleanarray *ba;
3360 STATISTICS(jniinvokation());
3363 *exceptionptr = new_negativearraysizeexception();
3367 ba = builtin_newarray_boolean(len);
3369 return (jbooleanArray) NewLocalRef(env, (jobject) ba);
3373 jbyteArray NewByteArray(JNIEnv *env, jsize len)
3377 STATISTICS(jniinvokation());
3380 *exceptionptr = new_negativearraysizeexception();
3384 ba = builtin_newarray_byte(len);
3386 return (jbyteArray) NewLocalRef(env, (jobject) ba);
3390 jcharArray NewCharArray(JNIEnv *env, jsize len)
3394 STATISTICS(jniinvokation());
3397 *exceptionptr = new_negativearraysizeexception();
3401 ca = builtin_newarray_char(len);
3403 return (jcharArray) NewLocalRef(env, (jobject) ca);
3407 jshortArray NewShortArray(JNIEnv *env, jsize len)
3409 java_shortarray *sa;
3411 STATISTICS(jniinvokation());
3414 *exceptionptr = new_negativearraysizeexception();
3418 sa = builtin_newarray_short(len);
3420 return (jshortArray) NewLocalRef(env, (jobject) sa);
3424 jintArray NewIntArray(JNIEnv *env, jsize len)
3428 STATISTICS(jniinvokation());
3431 *exceptionptr = new_negativearraysizeexception();
3435 ia = builtin_newarray_int(len);
3437 return (jintArray) NewLocalRef(env, (jobject) ia);
3441 jlongArray NewLongArray(JNIEnv *env, jsize len)
3445 STATISTICS(jniinvokation());
3448 *exceptionptr = new_negativearraysizeexception();
3452 la = builtin_newarray_long(len);
3454 return (jlongArray) NewLocalRef(env, (jobject) la);
3458 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3460 java_floatarray *fa;
3462 STATISTICS(jniinvokation());
3465 *exceptionptr = new_negativearraysizeexception();
3469 fa = builtin_newarray_float(len);
3471 return (jfloatArray) NewLocalRef(env, (jobject) fa);
3475 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3477 java_doublearray *da;
3479 STATISTICS(jniinvokation());
3482 *exceptionptr = new_negativearraysizeexception();
3486 da = builtin_newarray_double(len);
3488 return (jdoubleArray) NewLocalRef(env, (jobject) da);
3492 /* Get<PrimitiveType>ArrayElements *********************************************
3494 A family of functions that returns the body of the primitive array.
3496 *******************************************************************************/
3498 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3501 STATISTICS(jniinvokation());
3504 *isCopy = JNI_FALSE;
3510 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3512 STATISTICS(jniinvokation());
3515 *isCopy = JNI_FALSE;
3521 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3523 STATISTICS(jniinvokation());
3526 *isCopy = JNI_FALSE;
3532 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3534 STATISTICS(jniinvokation());
3537 *isCopy = JNI_FALSE;
3543 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3545 STATISTICS(jniinvokation());
3548 *isCopy = JNI_FALSE;
3554 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3556 STATISTICS(jniinvokation());
3559 *isCopy = JNI_FALSE;
3565 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3567 STATISTICS(jniinvokation());
3570 *isCopy = JNI_FALSE;
3576 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3579 STATISTICS(jniinvokation());
3582 *isCopy = JNI_FALSE;
3588 /* Release<PrimitiveType>ArrayElements *****************************************
3590 A family of functions that informs the VM that the native code no
3591 longer needs access to elems. The elems argument is a pointer
3592 derived from array using the corresponding
3593 Get<PrimitiveType>ArrayElements() function. If necessary, this
3594 function copies back all changes made to elems to the original
3597 *******************************************************************************/
3599 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3600 jboolean *elems, jint mode)
3602 STATISTICS(jniinvokation());
3604 if (elems != array->data) {
3607 MCOPY(array->data, elems, jboolean, array->header.size);
3610 MCOPY(array->data, elems, jboolean, array->header.size);
3611 /* XXX TWISTI how should it be freed? */
3614 /* XXX TWISTI how should it be freed? */
3621 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
3624 STATISTICS(jniinvokation());
3626 if (elems != array->data) {
3629 MCOPY(array->data, elems, jboolean, array->header.size);
3632 MCOPY(array->data, elems, jboolean, array->header.size);
3633 /* XXX TWISTI how should it be freed? */
3636 /* XXX TWISTI how should it be freed? */
3643 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
3646 STATISTICS(jniinvokation());
3648 if (elems != array->data) {
3651 MCOPY(array->data, elems, jboolean, array->header.size);
3654 MCOPY(array->data, elems, jboolean, array->header.size);
3655 /* XXX TWISTI how should it be freed? */
3658 /* XXX TWISTI how should it be freed? */
3665 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
3668 STATISTICS(jniinvokation());
3670 if (elems != array->data) {
3673 MCOPY(array->data, elems, jboolean, array->header.size);
3676 MCOPY(array->data, elems, jboolean, array->header.size);
3677 /* XXX TWISTI how should it be freed? */
3680 /* XXX TWISTI how should it be freed? */
3687 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
3690 STATISTICS(jniinvokation());
3692 if (elems != array->data) {
3695 MCOPY(array->data, elems, jboolean, array->header.size);
3698 MCOPY(array->data, elems, jboolean, array->header.size);
3699 /* XXX TWISTI how should it be freed? */
3702 /* XXX TWISTI how should it be freed? */
3709 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
3712 STATISTICS(jniinvokation());
3714 if (elems != array->data) {
3717 MCOPY(array->data, elems, jboolean, array->header.size);
3720 MCOPY(array->data, elems, jboolean, array->header.size);
3721 /* XXX TWISTI how should it be freed? */
3724 /* XXX TWISTI how should it be freed? */
3731 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
3734 STATISTICS(jniinvokation());
3736 if (elems != array->data) {
3739 MCOPY(array->data, elems, jboolean, array->header.size);
3742 MCOPY(array->data, elems, jboolean, array->header.size);
3743 /* XXX TWISTI how should it be freed? */
3746 /* XXX TWISTI how should it be freed? */
3753 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3754 jdouble *elems, jint mode)
3756 STATISTICS(jniinvokation());
3758 if (elems != array->data) {
3761 MCOPY(array->data, elems, jboolean, array->header.size);
3764 MCOPY(array->data, elems, jboolean, array->header.size);
3765 /* XXX TWISTI how should it be freed? */
3768 /* XXX TWISTI how should it be freed? */
3775 /* Get<PrimitiveType>ArrayRegion **********************************************
3777 A family of functions that copies a region of a primitive array
3780 *******************************************************************************/
3782 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3783 jsize len, jboolean *buf)
3785 STATISTICS(jniinvokation());
3787 if (start < 0 || len < 0 || start + len > array->header.size)
3789 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3792 MCOPY(buf, &array->data[start], jboolean, len);
3796 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3799 STATISTICS(jniinvokation());
3801 if (start < 0 || len < 0 || start + len > array->header.size)
3803 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3806 MCOPY(buf, &array->data[start], jbyte, len);
3810 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3813 STATISTICS(jniinvokation());
3815 if (start < 0 || len < 0 || start + len > array->header.size)
3817 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3820 MCOPY(buf, &array->data[start], jchar, len);
3824 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3825 jsize len, jshort *buf)
3827 STATISTICS(jniinvokation());
3829 if (start < 0 || len < 0 || start + len > array->header.size)
3831 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3834 MCOPY(buf, &array->data[start], jshort, len);
3838 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3841 STATISTICS(jniinvokation());
3843 if (start < 0 || len < 0 || start + len > array->header.size)
3845 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3848 MCOPY(buf, &array->data[start], jint, len);
3852 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
3855 STATISTICS(jniinvokation());
3857 if (start < 0 || len < 0 || start + len > array->header.size)
3859 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3862 MCOPY(buf, &array->data[start], jlong, len);
3866 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3867 jsize len, jfloat *buf)
3869 STATISTICS(jniinvokation());
3871 if (start < 0 || len < 0 || start + len > array->header.size)
3873 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3876 MCOPY(buf, &array->data[start], jfloat, len);
3880 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3881 jsize len, jdouble *buf)
3883 STATISTICS(jniinvokation());
3885 if (start < 0 || len < 0 || start+len>array->header.size)
3887 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3890 MCOPY(buf, &array->data[start], jdouble, len);
3894 /* Set<PrimitiveType>ArrayRegion **********************************************
3896 A family of functions that copies back a region of a primitive
3897 array from a buffer.
3899 *******************************************************************************/
3901 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3902 jsize len, jboolean *buf)
3904 STATISTICS(jniinvokation());
3906 if (start < 0 || len < 0 || start + len > array->header.size)
3908 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3911 MCOPY(&array->data[start], buf, jboolean, len);
3915 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3918 STATISTICS(jniinvokation());
3920 if (start < 0 || len < 0 || start + len > array->header.size)
3922 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3925 MCOPY(&array->data[start], buf, jbyte, len);
3929 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3932 STATISTICS(jniinvokation());
3934 if (start < 0 || len < 0 || start + len > array->header.size)
3936 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3939 MCOPY(&array->data[start], buf, jchar, len);
3944 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3945 jsize len, jshort *buf)
3947 STATISTICS(jniinvokation());
3949 if (start < 0 || len < 0 || start + len > array->header.size)
3951 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3954 MCOPY(&array->data[start], buf, jshort, len);
3958 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3961 STATISTICS(jniinvokation());
3963 if (start < 0 || len < 0 || start + len > array->header.size)
3965 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3968 MCOPY(&array->data[start], buf, jint, len);
3973 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
3976 STATISTICS(jniinvokation());
3978 if (start < 0 || len < 0 || start + len > array->header.size)
3980 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3983 MCOPY(&array->data[start], buf, jlong, len);
3988 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3989 jsize len, jfloat *buf)
3991 STATISTICS(jniinvokation());
3993 if (start < 0 || len < 0 || start + len > array->header.size)
3995 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3998 MCOPY(&array->data[start], buf, jfloat, len);
4003 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
4004 jsize len, jdouble *buf)
4006 STATISTICS(jniinvokation());
4008 if (start < 0 || len < 0 || start + len > array->header.size)
4010 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
4013 MCOPY(&array->data[start], buf, jdouble, len);
4017 /* Registering Native Methods *************************************************/
4019 /* RegisterNatives *************************************************************
4021 Registers native methods with the class specified by the clazz
4022 argument. The methods parameter specifies an array of
4023 JNINativeMethod structures that contain the names, signatures, and
4024 function pointers of the native methods. The nMethods parameter
4025 specifies the number of native methods in the array.
4027 *******************************************************************************/
4029 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
4032 STATISTICS(jniinvokation());
4034 log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
4040 /* UnregisterNatives ***********************************************************
4042 Unregisters native methods of a class. The class goes back to the
4043 state before it was linked or registered with its native method
4046 This function should not be used in normal native code. Instead, it
4047 provides special programs a way to reload and relink native
4050 *******************************************************************************/
4052 jint UnregisterNatives(JNIEnv *env, jclass clazz)
4054 STATISTICS(jniinvokation());
4056 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
4058 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
4064 /* Monitor Operations *********************************************************/
4066 /* MonitorEnter ****************************************************************
4068 Enters the monitor associated with the underlying Java object
4071 *******************************************************************************/
4073 jint MonitorEnter(JNIEnv *env, jobject obj)
4075 STATISTICS(jniinvokation());
4078 *exceptionptr = new_nullpointerexception();
4082 #if defined(USE_THREADS)
4083 builtin_monitorenter(obj);
4090 /* MonitorExit *****************************************************************
4092 The current thread must be the owner of the monitor associated with
4093 the underlying Java object referred to by obj. The thread
4094 decrements the counter indicating the number of times it has
4095 entered this monitor. If the value of the counter becomes zero, the
4096 current thread releases the monitor.
4098 *******************************************************************************/
4100 jint MonitorExit(JNIEnv *env, jobject obj)
4102 STATISTICS(jniinvokation());
4104 *exceptionptr = new_nullpointerexception();
4108 #if defined(USE_THREADS)
4109 builtin_monitorexit(obj);
4116 /* JavaVM Interface ***********************************************************/
4118 /* GetJavaVM *******************************************************************
4120 Returns the Java VM interface (used in the Invocation API)
4121 associated with the current thread. The result is placed at the
4122 location pointed to by the second argument, vm.
4124 *******************************************************************************/
4126 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
4128 STATISTICS(jniinvokation());
4136 void GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
4138 STATISTICS(jniinvokation());
4140 log_text("JNI-Call: GetStringRegion: IMPLEMENT ME!");
4144 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
4146 STATISTICS(jniinvokation());
4148 log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
4152 /* GetPrimitiveArrayCritical ***************************************************
4154 Obtain a direct pointer to array elements.
4156 *******************************************************************************/
4158 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
4163 ba = (java_bytearray *) array;
4165 /* do the same as Kaffe does */
4167 bp = GetByteArrayElements(env, ba, isCopy);
4173 /* ReleasePrimitiveArrayCritical ***********************************************
4175 No specific documentation.
4177 *******************************************************************************/
4179 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
4182 STATISTICS(jniinvokation());
4184 /* do the same as Kaffe does */
4186 ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
4190 /* GetStringCritical ***********************************************************
4192 The semantics of these two functions are similar to the existing
4193 Get/ReleaseStringChars functions.
4195 *******************************************************************************/
4197 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
4199 STATISTICS(jniinvokation());
4201 return GetStringChars(env, string, isCopy);
4205 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
4207 STATISTICS(jniinvokation());
4209 ReleaseStringChars(env, string, cstring);
4213 jweak NewWeakGlobalRef(JNIEnv* env, jobject obj)
4215 STATISTICS(jniinvokation());
4217 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
4223 void DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
4225 STATISTICS(jniinvokation());
4227 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
4231 /* NewGlobalRef ****************************************************************
4233 Creates a new global reference to the object referred to by the obj
4236 *******************************************************************************/
4238 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4240 java_lang_Integer *refcount;
4241 java_objectheader *newval;
4243 STATISTICS(jniinvokation());
4245 #if defined(USE_THREADS)
4246 builtin_monitorenter(*global_ref_table);
4249 refcount = (java_lang_Integer *)
4250 asm_calljavafunction(getmid, *global_ref_table, lobj, NULL, NULL);
4252 if (refcount == NULL) {
4253 newval = native_new_and_init_int(class_java_lang_Integer, 1);
4255 if (newval == NULL) {
4256 #if defined(USE_THREADS)
4257 builtin_monitorexit(*global_ref_table);
4262 asm_calljavafunction(putmid, *global_ref_table, lobj, newval, NULL);
4265 /* we can access the object itself, as we are in a
4266 synchronized section */
4271 #if defined(USE_THREADS)
4272 builtin_monitorexit(*global_ref_table);
4279 /* DeleteGlobalRef *************************************************************
4281 Deletes the global reference pointed to by globalRef.
4283 *******************************************************************************/
4285 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
4287 java_lang_Integer *refcount;
4290 STATISTICS(jniinvokation());
4292 #if defined(USE_THREADS)
4293 builtin_monitorenter(*global_ref_table);
4296 refcount = (java_lang_Integer *)
4297 asm_calljavafunction(getmid, *global_ref_table, globalRef, NULL, NULL);
4299 if (refcount == NULL) {
4300 log_text("JNI-DeleteGlobalRef: unable to find global reference");
4304 /* we can access the object itself, as we are in a synchronized
4307 val = refcount->value - 1;
4310 asm_calljavafunction(removemid, *global_ref_table, refcount, NULL,
4314 /* we do not create a new object, but set the new value into
4317 refcount->value = val;
4320 #if defined(USE_THREADS)
4321 builtin_monitorexit(*global_ref_table);
4326 /* ExceptionCheck **************************************************************
4328 Returns JNI_TRUE when there is a pending exception; otherwise,
4331 *******************************************************************************/
4333 jboolean ExceptionCheck(JNIEnv *env)
4335 STATISTICS(jniinvokation());
4337 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
4341 /* New JNI 1.4 functions ******************************************************/
4343 /* NewDirectByteBuffer *********************************************************
4345 Allocates and returns a direct java.nio.ByteBuffer referring to the
4346 block of memory starting at the memory address address and
4347 extending capacity bytes.
4349 *******************************************************************************/
4351 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
4353 java_objectheader *nbuf;
4354 #if SIZEOF_VOID_P == 8
4355 gnu_classpath_Pointer64 *paddress;
4357 gnu_classpath_Pointer32 *paddress;
4360 STATISTICS(jniinvokation());
4362 log_text("JNI-NewDirectByteBuffer: called");
4365 /* allocate a java.nio.DirectByteBufferImpl$ReadWrite object */
4367 if (!(nbuf = (java_nio_DirectByteBufferImpl$ReadWrite *)
4368 builtin_new(class_java_nio_DirectByteBufferImpl_ReadWrite)))
4372 /* alocate a gnu.classpath.Pointer{32,64} object */
4374 #if SIZEOF_VOID_P == 8
4375 if (!(paddress = (gnu_classpath_Pointer64 *)
4376 builtin_new(class_gnu_classpath_Pointer64)))
4378 if (!(paddress = (gnu_classpath_Pointer32 *)
4379 builtin_new(class_gnu_classpath_Pointer32)))
4383 /* fill gnu.classpath.Pointer{32,64} with address */
4385 paddress->data = (ptrint) address;
4388 /* fill java.nio.Buffer object */
4390 nbuf->cap = (s4) capacity;
4391 nbuf->limit = (s4) capacity;
4393 nbuf->address = (gnu_classpath_Pointer *) paddress;
4396 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
4397 dbbirw_init, NULL, paddress,
4398 (jint) capacity, (jint) capacity, (jint) 0);
4400 /* add local reference and return the value */
4402 return NewLocalRef(env, nbuf);
4406 /* GetDirectBufferAddress ******************************************************
4408 Fetches and returns the starting address of the memory region
4409 referenced by the given direct java.nio.Buffer.
4411 *******************************************************************************/
4413 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
4415 java_nio_DirectByteBufferImpl *nbuf;
4416 #if SIZEOF_VOID_P == 8
4417 gnu_classpath_Pointer64 *address;
4419 gnu_classpath_Pointer32 *address;
4422 STATISTICS(jniinvokation());
4425 if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
4429 nbuf = (java_nio_DirectByteBufferImpl *) buf;
4431 #if SIZEOF_VOID_P == 8
4432 address = (gnu_classpath_Pointer64 *) nbuf->address;
4434 address = (gnu_classpath_Pointer32 *) nbuf->address;
4437 return (void *) address->data;
4441 /* GetDirectBufferCapacity *****************************************************
4443 Fetches and returns the capacity in bytes of the memory region
4444 referenced by the given direct java.nio.Buffer.
4446 *******************************************************************************/
4448 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
4450 java_nio_Buffer *nbuf;
4452 STATISTICS(jniinvokation());
4457 nbuf = (java_nio_Buffer *) buf;
4459 return (jlong) nbuf->cap;
4463 jint DestroyJavaVM(JavaVM *vm)
4465 STATISTICS(jniinvokation());
4467 log_text("JNI-Call: DestroyJavaVM: IMPLEMENT ME!");
4473 /* AttachCurrentThread *********************************************************
4475 Attaches the current thread to a Java VM. Returns a JNI interface
4476 pointer in the JNIEnv argument.
4478 Trying to attach a thread that is already attached is a no-op.
4480 A native thread cannot be attached simultaneously to two Java VMs.
4482 When a thread is attached to the VM, the context class loader is
4483 the bootstrap loader.
4485 *******************************************************************************/
4487 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
4489 STATISTICS(jniinvokation());
4491 log_text("JNI-Call: AttachCurrentThread: IMPLEMENT ME!");
4493 #if !defined(HAVE___THREAD)
4494 /* cacao_thread_attach();*/
4496 #error "No idea how to implement that. Perhaps Stefan knows"
4505 jint DetachCurrentThread(JavaVM *vm)
4507 STATISTICS(jniinvokation());
4509 log_text("JNI-Call: DetachCurrentThread: IMPLEMENT ME!");
4515 /* GetEnv **********************************************************************
4517 If the current thread is not attached to the VM, sets *env to NULL,
4518 and returns JNI_EDETACHED. If the specified version is not
4519 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
4520 sets *env to the appropriate interface, and returns JNI_OK.
4522 *******************************************************************************/
4524 jint GetEnv(JavaVM *vm, void **env, jint version)
4526 STATISTICS(jniinvokation());
4528 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4529 if (thread_getself() == NULL) {
4532 return JNI_EDETACHED;
4536 if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
4537 (version == JNI_VERSION_1_4)) {
4543 #if defined(ENABLE_JVMTI)
4544 if (version == JVMTI_VERSION_1_0) {
4545 *env = (void *) new_jvmtienv();
4554 return JNI_EVERSION;
4559 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4561 STATISTICS(jniinvokation());
4563 log_text("JNI-Call: AttachCurrentThreadAsDaemon: IMPLEMENT ME!");
4569 /* JNI invocation table *******************************************************/
4571 const struct JNIInvokeInterface JNI_JavaVMTable = {
4577 AttachCurrentThread,
4578 DetachCurrentThread,
4580 AttachCurrentThreadAsDaemon
4584 /* JNI function table *********************************************************/
4586 struct JNINativeInterface JNI_JNIEnvTable = {
4595 &FromReflectedMethod,
4596 &FromReflectedField,
4616 &EnsureLocalCapacity,
4632 &CallBooleanMethodV,
4633 &CallBooleanMethodA,
4659 &CallNonvirtualObjectMethod,
4660 &CallNonvirtualObjectMethodV,
4661 &CallNonvirtualObjectMethodA,
4662 &CallNonvirtualBooleanMethod,
4663 &CallNonvirtualBooleanMethodV,
4664 &CallNonvirtualBooleanMethodA,
4665 &CallNonvirtualByteMethod,
4666 &CallNonvirtualByteMethodV,
4667 &CallNonvirtualByteMethodA,
4668 &CallNonvirtualCharMethod,
4669 &CallNonvirtualCharMethodV,
4670 &CallNonvirtualCharMethodA,
4671 &CallNonvirtualShortMethod,
4672 &CallNonvirtualShortMethodV,
4673 &CallNonvirtualShortMethodA,
4674 &CallNonvirtualIntMethod,
4675 &CallNonvirtualIntMethodV,
4676 &CallNonvirtualIntMethodA,
4677 &CallNonvirtualLongMethod,
4678 &CallNonvirtualLongMethodV,
4679 &CallNonvirtualLongMethodA,
4680 &CallNonvirtualFloatMethod,
4681 &CallNonvirtualFloatMethodV,
4682 &CallNonvirtualFloatMethodA,
4683 &CallNonvirtualDoubleMethod,
4684 &CallNonvirtualDoubleMethodV,
4685 &CallNonvirtualDoubleMethodA,
4686 &CallNonvirtualVoidMethod,
4687 &CallNonvirtualVoidMethodV,
4688 &CallNonvirtualVoidMethodA,
4713 &CallStaticObjectMethod,
4714 &CallStaticObjectMethodV,
4715 &CallStaticObjectMethodA,
4716 &CallStaticBooleanMethod,
4717 &CallStaticBooleanMethodV,
4718 &CallStaticBooleanMethodA,
4719 &CallStaticByteMethod,
4720 &CallStaticByteMethodV,
4721 &CallStaticByteMethodA,
4722 &CallStaticCharMethod,
4723 &CallStaticCharMethodV,
4724 &CallStaticCharMethodA,
4725 &CallStaticShortMethod,
4726 &CallStaticShortMethodV,
4727 &CallStaticShortMethodA,
4728 &CallStaticIntMethod,
4729 &CallStaticIntMethodV,
4730 &CallStaticIntMethodA,
4731 &CallStaticLongMethod,
4732 &CallStaticLongMethodV,
4733 &CallStaticLongMethodA,
4734 &CallStaticFloatMethod,
4735 &CallStaticFloatMethodV,
4736 &CallStaticFloatMethodA,
4737 &CallStaticDoubleMethod,
4738 &CallStaticDoubleMethodV,
4739 &CallStaticDoubleMethodA,
4740 &CallStaticVoidMethod,
4741 &CallStaticVoidMethodV,
4742 &CallStaticVoidMethodA,
4746 &GetStaticObjectField,
4747 &GetStaticBooleanField,
4748 &GetStaticByteField,
4749 &GetStaticCharField,
4750 &GetStaticShortField,
4752 &GetStaticLongField,
4753 &GetStaticFloatField,
4754 &GetStaticDoubleField,
4755 &SetStaticObjectField,
4756 &SetStaticBooleanField,
4757 &SetStaticByteField,
4758 &SetStaticCharField,
4759 &SetStaticShortField,
4761 &SetStaticLongField,
4762 &SetStaticFloatField,
4763 &SetStaticDoubleField,
4768 &ReleaseStringChars,
4771 &GetStringUTFLength,
4773 &ReleaseStringUTFChars,
4778 &GetObjectArrayElement,
4779 &SetObjectArrayElement,
4790 &GetBooleanArrayElements,
4791 &GetByteArrayElements,
4792 &GetCharArrayElements,
4793 &GetShortArrayElements,
4794 &GetIntArrayElements,
4795 &GetLongArrayElements,
4796 &GetFloatArrayElements,
4797 &GetDoubleArrayElements,
4799 &ReleaseBooleanArrayElements,
4800 &ReleaseByteArrayElements,
4801 &ReleaseCharArrayElements,
4802 &ReleaseShortArrayElements,
4803 &ReleaseIntArrayElements,
4804 &ReleaseLongArrayElements,
4805 &ReleaseFloatArrayElements,
4806 &ReleaseDoubleArrayElements,
4808 &GetBooleanArrayRegion,
4809 &GetByteArrayRegion,
4810 &GetCharArrayRegion,
4811 &GetShortArrayRegion,
4813 &GetLongArrayRegion,
4814 &GetFloatArrayRegion,
4815 &GetDoubleArrayRegion,
4816 &SetBooleanArrayRegion,
4817 &SetByteArrayRegion,
4818 &SetCharArrayRegion,
4819 &SetShortArrayRegion,
4821 &SetLongArrayRegion,
4822 &SetFloatArrayRegion,
4823 &SetDoubleArrayRegion,
4833 /* new JNI 1.2 functions */
4836 &GetStringUTFRegion,
4838 &GetPrimitiveArrayCritical,
4839 &ReleasePrimitiveArrayCritical,
4842 &ReleaseStringCritical,
4845 &DeleteWeakGlobalRef,
4849 /* new JNI 1.4 functions */
4851 &NewDirectByteBuffer,
4852 &GetDirectBufferAddress,
4853 &GetDirectBufferCapacity
4857 /* Invocation API Functions ***************************************************/
4859 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4861 Returns a default configuration for the Java VM.
4863 *******************************************************************************/
4865 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4867 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4869 /* GNU classpath currently supports JNI 1.2 */
4871 _vm_args->version = JNI_VERSION_1_2;
4877 /* JNI_GetCreatedJavaVMs *******************************************************
4879 Returns all Java VMs that have been created. Pointers to VMs are written in
4880 the buffer vmBuf in the order they are created. At most bufLen number of
4881 entries will be written. The total number of created VMs is returned in
4884 *******************************************************************************/
4886 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4888 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4894 /* JNI_CreateJavaVM ************************************************************
4896 Loads and initializes a Java VM. The current thread becomes the main thread.
4897 Sets the env argument to the JNI interface pointer of the main thread.
4899 *******************************************************************************/
4901 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4903 const struct JNIInvokeInterface *vm;
4904 struct JNINativeInterface *env;
4906 vm = &JNI_JavaVMTable;
4907 env = &JNI_JNIEnvTable;
4909 *p_vm = (JavaVM *) vm;
4910 *p_env = (JNIEnv *) env;
4916 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4917 jobject obj, java_objectarray *params)
4924 if (methodID == 0) {
4925 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
4929 argcount = methodID->parseddesc->paramcount;
4930 paramcount = argcount;
4932 /* if method is non-static, remove the `this' pointer */
4934 if (!(methodID->flags & ACC_STATIC))
4937 /* the method is an instance method the obj has to be an instance of the
4938 class the method belongs to. For static methods the obj parameter
4941 if (!(methodID->flags & ACC_STATIC) && obj &&
4942 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4944 new_exception_message(string_java_lang_IllegalArgumentException,
4945 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4949 if (((params == NULL) && (paramcount != 0)) ||
4950 (params && (params->header.size != paramcount))) {
4952 new_exception(string_java_lang_IllegalArgumentException);
4957 if (!(methodID->flags & ACC_STATIC) && !obj) {
4959 new_exception_message(string_java_lang_NullPointerException,
4960 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4964 if ((methodID->flags & ACC_STATIC) && (obj))
4968 if ((methodID->flags & ACC_ABSTRACT) ||
4969 (methodID->class->flags & ACC_INTERFACE)) {
4970 methodID = get_virtual(obj, methodID);
4974 blk = MNEW(jni_callblock, argcount);
4976 if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4980 switch (methodID->parseddesc->returntype.decltype) {
4982 (void) asm_calljavafunction2(methodID, argcount,
4983 argcount * sizeof(jni_callblock),
4985 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4988 case PRIMITIVETYPE_INT: {
4990 i = asm_calljavafunction2int(methodID, argcount,
4991 argcount * sizeof(jni_callblock),
4994 o = native_new_and_init_int(class_java_lang_Integer, i);
4998 case PRIMITIVETYPE_BYTE: {
5000 i = asm_calljavafunction2int(methodID, argcount,
5001 argcount * sizeof(jni_callblock),
5004 /* o = native_new_and_init_int(class_java_lang_Byte, i); */
5005 o = builtin_new(class_java_lang_Byte);
5008 class_resolvemethod(o->vftbl->class,
5015 case PRIMITIVETYPE_CHAR: {
5017 intVal = asm_calljavafunction2int(methodID,
5019 argcount * sizeof(jni_callblock),
5021 o = builtin_new(class_java_lang_Character);
5024 class_resolvemethod(o->vftbl->class,
5031 case PRIMITIVETYPE_SHORT: {
5033 intVal = asm_calljavafunction2int(methodID,
5035 argcount * sizeof(jni_callblock),
5037 o = builtin_new(class_java_lang_Short);
5040 class_resolvemethod(o->vftbl->class,
5047 case PRIMITIVETYPE_BOOLEAN: {
5049 intVal = asm_calljavafunction2int(methodID,
5051 argcount * sizeof(jni_callblock),
5053 o = builtin_new(class_java_lang_Boolean);
5056 class_resolvemethod(o->vftbl->class,
5063 case PRIMITIVETYPE_LONG: {
5065 longVal = asm_calljavafunction2long(methodID,
5067 argcount * sizeof(jni_callblock),
5069 o = builtin_new(class_java_lang_Long);
5072 class_resolvemethod(o->vftbl->class,
5079 case PRIMITIVETYPE_FLOAT: {
5081 floatVal = asm_calljavafunction2float(methodID,
5083 argcount * sizeof(jni_callblock),
5085 o = builtin_new(class_java_lang_Float);
5088 class_resolvemethod(o->vftbl->class,
5095 case PRIMITIVETYPE_DOUBLE: {
5097 doubleVal = asm_calljavafunction2double(methodID,
5099 argcount * sizeof(jni_callblock),
5101 o = builtin_new(class_java_lang_Double);
5104 class_resolvemethod(o->vftbl->class,
5112 o = asm_calljavafunction2(methodID, argcount,
5113 argcount * sizeof(jni_callblock), blk);
5117 /* if this happens the exception has already been set by */
5118 /* fill_callblock_from_objectarray */
5120 MFREE(blk, jni_callblock, argcount);
5121 return (jobject *) 0;
5124 MFREE(blk, jni_callblock, argcount);
5126 if (*exceptionptr) {
5127 java_objectheader *cause;
5129 cause = *exceptionptr;
5131 /* clear exception pointer, we are calling JIT code again */
5133 *exceptionptr = NULL;
5136 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
5137 (java_lang_Throwable *) cause);
5140 return (jobject *) o;
5145 * These are local overrides for various environment variables in Emacs.
5146 * Please do not remove this and leave it at the end of the file, where
5147 * Emacs will automagically detect them.
5148 * ---------------------------------------------------------------------
5151 * indent-tabs-mode: t