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 4123 2006-01-10 20:46:50Z 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 exceptions_throw_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 exceptions_throw_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) {
3314 exceptions_throw_arrayindexoutofboundsexception();
3318 o = array->data[index];
3320 return NewLocalRef(env, o);
3324 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3326 java_objectarray *oa;
3327 java_objectheader *o;
3329 STATISTICS(jniinvokation());
3331 oa = (java_objectarray *) array;
3332 o = (java_objectheader *) val;
3334 if (index >= array->header.size) {
3335 exceptions_throw_arrayindexoutofboundsexception();
3339 /* check if the class of value is a subclass of the element class
3342 if (!builtin_canstore(oa, o)) {
3343 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3348 array->data[index] = val;
3352 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3354 java_booleanarray *ba;
3356 STATISTICS(jniinvokation());
3359 exceptions_throw_negativearraysizeexception();
3363 ba = builtin_newarray_boolean(len);
3365 return (jbooleanArray) NewLocalRef(env, (jobject) ba);
3369 jbyteArray NewByteArray(JNIEnv *env, jsize len)
3373 STATISTICS(jniinvokation());
3376 exceptions_throw_negativearraysizeexception();
3380 ba = builtin_newarray_byte(len);
3382 return (jbyteArray) NewLocalRef(env, (jobject) ba);
3386 jcharArray NewCharArray(JNIEnv *env, jsize len)
3390 STATISTICS(jniinvokation());
3393 exceptions_throw_negativearraysizeexception();
3397 ca = builtin_newarray_char(len);
3399 return (jcharArray) NewLocalRef(env, (jobject) ca);
3403 jshortArray NewShortArray(JNIEnv *env, jsize len)
3405 java_shortarray *sa;
3407 STATISTICS(jniinvokation());
3410 exceptions_throw_negativearraysizeexception();
3414 sa = builtin_newarray_short(len);
3416 return (jshortArray) NewLocalRef(env, (jobject) sa);
3420 jintArray NewIntArray(JNIEnv *env, jsize len)
3424 STATISTICS(jniinvokation());
3427 exceptions_throw_negativearraysizeexception();
3431 ia = builtin_newarray_int(len);
3433 return (jintArray) NewLocalRef(env, (jobject) ia);
3437 jlongArray NewLongArray(JNIEnv *env, jsize len)
3441 STATISTICS(jniinvokation());
3444 exceptions_throw_negativearraysizeexception();
3448 la = builtin_newarray_long(len);
3450 return (jlongArray) NewLocalRef(env, (jobject) la);
3454 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3456 java_floatarray *fa;
3458 STATISTICS(jniinvokation());
3461 exceptions_throw_negativearraysizeexception();
3465 fa = builtin_newarray_float(len);
3467 return (jfloatArray) NewLocalRef(env, (jobject) fa);
3471 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3473 java_doublearray *da;
3475 STATISTICS(jniinvokation());
3478 exceptions_throw_negativearraysizeexception();
3482 da = builtin_newarray_double(len);
3484 return (jdoubleArray) NewLocalRef(env, (jobject) da);
3488 /* Get<PrimitiveType>ArrayElements *********************************************
3490 A family of functions that returns the body of the primitive array.
3492 *******************************************************************************/
3494 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3497 STATISTICS(jniinvokation());
3500 *isCopy = JNI_FALSE;
3506 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3508 STATISTICS(jniinvokation());
3511 *isCopy = JNI_FALSE;
3517 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3519 STATISTICS(jniinvokation());
3522 *isCopy = JNI_FALSE;
3528 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3530 STATISTICS(jniinvokation());
3533 *isCopy = JNI_FALSE;
3539 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3541 STATISTICS(jniinvokation());
3544 *isCopy = JNI_FALSE;
3550 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3552 STATISTICS(jniinvokation());
3555 *isCopy = JNI_FALSE;
3561 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3563 STATISTICS(jniinvokation());
3566 *isCopy = JNI_FALSE;
3572 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3575 STATISTICS(jniinvokation());
3578 *isCopy = JNI_FALSE;
3584 /* Release<PrimitiveType>ArrayElements *****************************************
3586 A family of functions that informs the VM that the native code no
3587 longer needs access to elems. The elems argument is a pointer
3588 derived from array using the corresponding
3589 Get<PrimitiveType>ArrayElements() function. If necessary, this
3590 function copies back all changes made to elems to the original
3593 *******************************************************************************/
3595 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3596 jboolean *elems, jint mode)
3598 STATISTICS(jniinvokation());
3600 if (elems != array->data) {
3603 MCOPY(array->data, elems, jboolean, array->header.size);
3606 MCOPY(array->data, elems, jboolean, array->header.size);
3607 /* XXX TWISTI how should it be freed? */
3610 /* XXX TWISTI how should it be freed? */
3617 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
3620 STATISTICS(jniinvokation());
3622 if (elems != array->data) {
3625 MCOPY(array->data, elems, jboolean, array->header.size);
3628 MCOPY(array->data, elems, jboolean, array->header.size);
3629 /* XXX TWISTI how should it be freed? */
3632 /* XXX TWISTI how should it be freed? */
3639 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
3642 STATISTICS(jniinvokation());
3644 if (elems != array->data) {
3647 MCOPY(array->data, elems, jboolean, array->header.size);
3650 MCOPY(array->data, elems, jboolean, array->header.size);
3651 /* XXX TWISTI how should it be freed? */
3654 /* XXX TWISTI how should it be freed? */
3661 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
3664 STATISTICS(jniinvokation());
3666 if (elems != array->data) {
3669 MCOPY(array->data, elems, jboolean, array->header.size);
3672 MCOPY(array->data, elems, jboolean, array->header.size);
3673 /* XXX TWISTI how should it be freed? */
3676 /* XXX TWISTI how should it be freed? */
3683 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
3686 STATISTICS(jniinvokation());
3688 if (elems != array->data) {
3691 MCOPY(array->data, elems, jboolean, array->header.size);
3694 MCOPY(array->data, elems, jboolean, array->header.size);
3695 /* XXX TWISTI how should it be freed? */
3698 /* XXX TWISTI how should it be freed? */
3705 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
3708 STATISTICS(jniinvokation());
3710 if (elems != array->data) {
3713 MCOPY(array->data, elems, jboolean, array->header.size);
3716 MCOPY(array->data, elems, jboolean, array->header.size);
3717 /* XXX TWISTI how should it be freed? */
3720 /* XXX TWISTI how should it be freed? */
3727 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
3730 STATISTICS(jniinvokation());
3732 if (elems != array->data) {
3735 MCOPY(array->data, elems, jboolean, array->header.size);
3738 MCOPY(array->data, elems, jboolean, array->header.size);
3739 /* XXX TWISTI how should it be freed? */
3742 /* XXX TWISTI how should it be freed? */
3749 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3750 jdouble *elems, jint mode)
3752 STATISTICS(jniinvokation());
3754 if (elems != array->data) {
3757 MCOPY(array->data, elems, jboolean, array->header.size);
3760 MCOPY(array->data, elems, jboolean, array->header.size);
3761 /* XXX TWISTI how should it be freed? */
3764 /* XXX TWISTI how should it be freed? */
3771 /* Get<PrimitiveType>ArrayRegion **********************************************
3773 A family of functions that copies a region of a primitive array
3776 *******************************************************************************/
3778 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3779 jsize len, jboolean *buf)
3781 STATISTICS(jniinvokation());
3783 if (start < 0 || len < 0 || start + len > array->header.size)
3784 exceptions_throw_arrayindexoutofboundsexception();
3786 MCOPY(buf, &array->data[start], jboolean, len);
3790 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3793 STATISTICS(jniinvokation());
3795 if (start < 0 || len < 0 || start + len > array->header.size)
3796 exceptions_throw_arrayindexoutofboundsexception();
3798 MCOPY(buf, &array->data[start], jbyte, len);
3802 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3805 STATISTICS(jniinvokation());
3807 if (start < 0 || len < 0 || start + len > array->header.size)
3808 exceptions_throw_arrayindexoutofboundsexception();
3810 MCOPY(buf, &array->data[start], jchar, len);
3814 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3815 jsize len, jshort *buf)
3817 STATISTICS(jniinvokation());
3819 if (start < 0 || len < 0 || start + len > array->header.size)
3820 exceptions_throw_arrayindexoutofboundsexception();
3822 MCOPY(buf, &array->data[start], jshort, len);
3826 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3829 STATISTICS(jniinvokation());
3831 if (start < 0 || len < 0 || start + len > array->header.size)
3832 exceptions_throw_arrayindexoutofboundsexception();
3834 MCOPY(buf, &array->data[start], jint, len);
3838 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
3841 STATISTICS(jniinvokation());
3843 if (start < 0 || len < 0 || start + len > array->header.size)
3844 exceptions_throw_arrayindexoutofboundsexception();
3846 MCOPY(buf, &array->data[start], jlong, len);
3850 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3851 jsize len, jfloat *buf)
3853 STATISTICS(jniinvokation());
3855 if (start < 0 || len < 0 || start + len > array->header.size)
3856 exceptions_throw_arrayindexoutofboundsexception();
3858 MCOPY(buf, &array->data[start], jfloat, len);
3862 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3863 jsize len, jdouble *buf)
3865 STATISTICS(jniinvokation());
3867 if (start < 0 || len < 0 || start+len>array->header.size)
3868 exceptions_throw_arrayindexoutofboundsexception();
3870 MCOPY(buf, &array->data[start], jdouble, len);
3874 /* Set<PrimitiveType>ArrayRegion **********************************************
3876 A family of functions that copies back a region of a primitive
3877 array from a buffer.
3879 *******************************************************************************/
3881 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3882 jsize len, jboolean *buf)
3884 STATISTICS(jniinvokation());
3886 if (start < 0 || len < 0 || start + len > array->header.size)
3887 exceptions_throw_arrayindexoutofboundsexception();
3889 MCOPY(&array->data[start], buf, jboolean, len);
3893 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3896 STATISTICS(jniinvokation());
3898 if (start < 0 || len < 0 || start + len > array->header.size)
3899 exceptions_throw_arrayindexoutofboundsexception();
3901 MCOPY(&array->data[start], buf, jbyte, len);
3905 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3908 STATISTICS(jniinvokation());
3910 if (start < 0 || len < 0 || start + len > array->header.size)
3911 exceptions_throw_arrayindexoutofboundsexception();
3913 MCOPY(&array->data[start], buf, jchar, len);
3917 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3918 jsize len, jshort *buf)
3920 STATISTICS(jniinvokation());
3922 if (start < 0 || len < 0 || start + len > array->header.size)
3923 exceptions_throw_arrayindexoutofboundsexception();
3925 MCOPY(&array->data[start], buf, jshort, len);
3929 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3932 STATISTICS(jniinvokation());
3934 if (start < 0 || len < 0 || start + len > array->header.size)
3935 exceptions_throw_arrayindexoutofboundsexception();
3937 MCOPY(&array->data[start], buf, jint, len);
3941 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
3944 STATISTICS(jniinvokation());
3946 if (start < 0 || len < 0 || start + len > array->header.size)
3947 exceptions_throw_arrayindexoutofboundsexception();
3949 MCOPY(&array->data[start], buf, jlong, len);
3953 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3954 jsize len, jfloat *buf)
3956 STATISTICS(jniinvokation());
3958 if (start < 0 || len < 0 || start + len > array->header.size)
3959 exceptions_throw_arrayindexoutofboundsexception();
3961 MCOPY(&array->data[start], buf, jfloat, len);
3965 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3966 jsize len, jdouble *buf)
3968 STATISTICS(jniinvokation());
3970 if (start < 0 || len < 0 || start + len > array->header.size)
3971 exceptions_throw_arrayindexoutofboundsexception();
3973 MCOPY(&array->data[start], buf, jdouble, len);
3977 /* Registering Native Methods *************************************************/
3979 /* RegisterNatives *************************************************************
3981 Registers native methods with the class specified by the clazz
3982 argument. The methods parameter specifies an array of
3983 JNINativeMethod structures that contain the names, signatures, and
3984 function pointers of the native methods. The nMethods parameter
3985 specifies the number of native methods in the array.
3987 *******************************************************************************/
3989 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
3992 STATISTICS(jniinvokation());
3994 log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
4000 /* UnregisterNatives ***********************************************************
4002 Unregisters native methods of a class. The class goes back to the
4003 state before it was linked or registered with its native method
4006 This function should not be used in normal native code. Instead, it
4007 provides special programs a way to reload and relink native
4010 *******************************************************************************/
4012 jint UnregisterNatives(JNIEnv *env, jclass clazz)
4014 STATISTICS(jniinvokation());
4016 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
4018 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
4024 /* Monitor Operations *********************************************************/
4026 /* MonitorEnter ****************************************************************
4028 Enters the monitor associated with the underlying Java object
4031 *******************************************************************************/
4033 jint MonitorEnter(JNIEnv *env, jobject obj)
4035 STATISTICS(jniinvokation());
4038 exceptions_throw_nullpointerexception();
4042 #if defined(USE_THREADS)
4043 builtin_monitorenter(obj);
4050 /* MonitorExit *****************************************************************
4052 The current thread must be the owner of the monitor associated with
4053 the underlying Java object referred to by obj. The thread
4054 decrements the counter indicating the number of times it has
4055 entered this monitor. If the value of the counter becomes zero, the
4056 current thread releases the monitor.
4058 *******************************************************************************/
4060 jint MonitorExit(JNIEnv *env, jobject obj)
4062 STATISTICS(jniinvokation());
4065 exceptions_throw_nullpointerexception();
4069 #if defined(USE_THREADS)
4070 builtin_monitorexit(obj);
4077 /* JavaVM Interface ***********************************************************/
4079 /* GetJavaVM *******************************************************************
4081 Returns the Java VM interface (used in the Invocation API)
4082 associated with the current thread. The result is placed at the
4083 location pointed to by the second argument, vm.
4085 *******************************************************************************/
4087 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
4089 STATISTICS(jniinvokation());
4097 void GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
4099 STATISTICS(jniinvokation());
4101 log_text("JNI-Call: GetStringRegion: IMPLEMENT ME!");
4105 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
4107 STATISTICS(jniinvokation());
4109 log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
4113 /* GetPrimitiveArrayCritical ***************************************************
4115 Obtain a direct pointer to array elements.
4117 *******************************************************************************/
4119 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
4124 ba = (java_bytearray *) array;
4126 /* do the same as Kaffe does */
4128 bp = GetByteArrayElements(env, ba, isCopy);
4134 /* ReleasePrimitiveArrayCritical ***********************************************
4136 No specific documentation.
4138 *******************************************************************************/
4140 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
4143 STATISTICS(jniinvokation());
4145 /* do the same as Kaffe does */
4147 ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
4151 /* GetStringCritical ***********************************************************
4153 The semantics of these two functions are similar to the existing
4154 Get/ReleaseStringChars functions.
4156 *******************************************************************************/
4158 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
4160 STATISTICS(jniinvokation());
4162 return GetStringChars(env, string, isCopy);
4166 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
4168 STATISTICS(jniinvokation());
4170 ReleaseStringChars(env, string, cstring);
4174 jweak NewWeakGlobalRef(JNIEnv* env, jobject obj)
4176 STATISTICS(jniinvokation());
4178 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
4184 void DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
4186 STATISTICS(jniinvokation());
4188 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
4192 /* NewGlobalRef ****************************************************************
4194 Creates a new global reference to the object referred to by the obj
4197 *******************************************************************************/
4199 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4201 java_lang_Integer *refcount;
4202 java_objectheader *newval;
4204 STATISTICS(jniinvokation());
4206 #if defined(USE_THREADS)
4207 builtin_monitorenter(*global_ref_table);
4210 refcount = (java_lang_Integer *)
4211 asm_calljavafunction(getmid, *global_ref_table, lobj, NULL, NULL);
4213 if (refcount == NULL) {
4214 newval = native_new_and_init_int(class_java_lang_Integer, 1);
4216 if (newval == NULL) {
4217 #if defined(USE_THREADS)
4218 builtin_monitorexit(*global_ref_table);
4223 asm_calljavafunction(putmid, *global_ref_table, lobj, newval, NULL);
4226 /* we can access the object itself, as we are in a
4227 synchronized section */
4232 #if defined(USE_THREADS)
4233 builtin_monitorexit(*global_ref_table);
4240 /* DeleteGlobalRef *************************************************************
4242 Deletes the global reference pointed to by globalRef.
4244 *******************************************************************************/
4246 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
4248 java_lang_Integer *refcount;
4251 STATISTICS(jniinvokation());
4253 #if defined(USE_THREADS)
4254 builtin_monitorenter(*global_ref_table);
4257 refcount = (java_lang_Integer *)
4258 asm_calljavafunction(getmid, *global_ref_table, globalRef, NULL, NULL);
4260 if (refcount == NULL) {
4261 log_text("JNI-DeleteGlobalRef: unable to find global reference");
4265 /* we can access the object itself, as we are in a synchronized
4268 val = refcount->value - 1;
4271 asm_calljavafunction(removemid, *global_ref_table, refcount, NULL,
4275 /* we do not create a new object, but set the new value into
4278 refcount->value = val;
4281 #if defined(USE_THREADS)
4282 builtin_monitorexit(*global_ref_table);
4287 /* ExceptionCheck **************************************************************
4289 Returns JNI_TRUE when there is a pending exception; otherwise,
4292 *******************************************************************************/
4294 jboolean ExceptionCheck(JNIEnv *env)
4296 STATISTICS(jniinvokation());
4298 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
4302 /* New JNI 1.4 functions ******************************************************/
4304 /* NewDirectByteBuffer *********************************************************
4306 Allocates and returns a direct java.nio.ByteBuffer referring to the
4307 block of memory starting at the memory address address and
4308 extending capacity bytes.
4310 *******************************************************************************/
4312 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
4314 java_objectheader *nbuf;
4315 #if SIZEOF_VOID_P == 8
4316 gnu_classpath_Pointer64 *paddress;
4318 gnu_classpath_Pointer32 *paddress;
4321 STATISTICS(jniinvokation());
4323 log_text("JNI-NewDirectByteBuffer: called");
4326 /* allocate a java.nio.DirectByteBufferImpl$ReadWrite object */
4328 if (!(nbuf = (java_nio_DirectByteBufferImpl$ReadWrite *)
4329 builtin_new(class_java_nio_DirectByteBufferImpl_ReadWrite)))
4333 /* alocate a gnu.classpath.Pointer{32,64} object */
4335 #if SIZEOF_VOID_P == 8
4336 if (!(paddress = (gnu_classpath_Pointer64 *)
4337 builtin_new(class_gnu_classpath_Pointer64)))
4339 if (!(paddress = (gnu_classpath_Pointer32 *)
4340 builtin_new(class_gnu_classpath_Pointer32)))
4344 /* fill gnu.classpath.Pointer{32,64} with address */
4346 paddress->data = (ptrint) address;
4349 /* fill java.nio.Buffer object */
4351 nbuf->cap = (s4) capacity;
4352 nbuf->limit = (s4) capacity;
4354 nbuf->address = (gnu_classpath_Pointer *) paddress;
4357 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
4358 dbbirw_init, NULL, paddress,
4359 (jint) capacity, (jint) capacity, (jint) 0);
4361 /* add local reference and return the value */
4363 return NewLocalRef(env, nbuf);
4367 /* GetDirectBufferAddress ******************************************************
4369 Fetches and returns the starting address of the memory region
4370 referenced by the given direct java.nio.Buffer.
4372 *******************************************************************************/
4374 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
4376 java_nio_DirectByteBufferImpl *nbuf;
4377 #if SIZEOF_VOID_P == 8
4378 gnu_classpath_Pointer64 *address;
4380 gnu_classpath_Pointer32 *address;
4383 STATISTICS(jniinvokation());
4386 if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
4390 nbuf = (java_nio_DirectByteBufferImpl *) buf;
4392 #if SIZEOF_VOID_P == 8
4393 address = (gnu_classpath_Pointer64 *) nbuf->address;
4395 address = (gnu_classpath_Pointer32 *) nbuf->address;
4398 return (void *) address->data;
4402 /* GetDirectBufferCapacity *****************************************************
4404 Fetches and returns the capacity in bytes of the memory region
4405 referenced by the given direct java.nio.Buffer.
4407 *******************************************************************************/
4409 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
4411 java_nio_Buffer *nbuf;
4413 STATISTICS(jniinvokation());
4418 nbuf = (java_nio_Buffer *) buf;
4420 return (jlong) nbuf->cap;
4424 jint DestroyJavaVM(JavaVM *vm)
4426 STATISTICS(jniinvokation());
4428 log_text("JNI-Call: DestroyJavaVM: IMPLEMENT ME!");
4434 /* AttachCurrentThread *********************************************************
4436 Attaches the current thread to a Java VM. Returns a JNI interface
4437 pointer in the JNIEnv argument.
4439 Trying to attach a thread that is already attached is a no-op.
4441 A native thread cannot be attached simultaneously to two Java VMs.
4443 When a thread is attached to the VM, the context class loader is
4444 the bootstrap loader.
4446 *******************************************************************************/
4448 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
4450 STATISTICS(jniinvokation());
4452 log_text("JNI-Call: AttachCurrentThread: IMPLEMENT ME!");
4454 #if !defined(HAVE___THREAD)
4455 /* cacao_thread_attach();*/
4457 #error "No idea how to implement that. Perhaps Stefan knows"
4466 jint DetachCurrentThread(JavaVM *vm)
4468 STATISTICS(jniinvokation());
4470 log_text("JNI-Call: DetachCurrentThread: IMPLEMENT ME!");
4476 /* GetEnv **********************************************************************
4478 If the current thread is not attached to the VM, sets *env to NULL,
4479 and returns JNI_EDETACHED. If the specified version is not
4480 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
4481 sets *env to the appropriate interface, and returns JNI_OK.
4483 *******************************************************************************/
4485 jint GetEnv(JavaVM *vm, void **env, jint version)
4487 STATISTICS(jniinvokation());
4489 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4490 if (thread_getself() == NULL) {
4493 return JNI_EDETACHED;
4497 if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
4498 (version == JNI_VERSION_1_4)) {
4504 #if defined(ENABLE_JVMTI)
4505 if (version == JVMTI_VERSION_1_0) {
4506 *env = (void *) new_jvmtienv();
4515 return JNI_EVERSION;
4520 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4522 STATISTICS(jniinvokation());
4524 log_text("JNI-Call: AttachCurrentThreadAsDaemon: IMPLEMENT ME!");
4530 /* JNI invocation table *******************************************************/
4532 const struct JNIInvokeInterface JNI_JavaVMTable = {
4538 AttachCurrentThread,
4539 DetachCurrentThread,
4541 AttachCurrentThreadAsDaemon
4545 /* JNI function table *********************************************************/
4547 struct JNINativeInterface JNI_JNIEnvTable = {
4556 &FromReflectedMethod,
4557 &FromReflectedField,
4577 &EnsureLocalCapacity,
4593 &CallBooleanMethodV,
4594 &CallBooleanMethodA,
4620 &CallNonvirtualObjectMethod,
4621 &CallNonvirtualObjectMethodV,
4622 &CallNonvirtualObjectMethodA,
4623 &CallNonvirtualBooleanMethod,
4624 &CallNonvirtualBooleanMethodV,
4625 &CallNonvirtualBooleanMethodA,
4626 &CallNonvirtualByteMethod,
4627 &CallNonvirtualByteMethodV,
4628 &CallNonvirtualByteMethodA,
4629 &CallNonvirtualCharMethod,
4630 &CallNonvirtualCharMethodV,
4631 &CallNonvirtualCharMethodA,
4632 &CallNonvirtualShortMethod,
4633 &CallNonvirtualShortMethodV,
4634 &CallNonvirtualShortMethodA,
4635 &CallNonvirtualIntMethod,
4636 &CallNonvirtualIntMethodV,
4637 &CallNonvirtualIntMethodA,
4638 &CallNonvirtualLongMethod,
4639 &CallNonvirtualLongMethodV,
4640 &CallNonvirtualLongMethodA,
4641 &CallNonvirtualFloatMethod,
4642 &CallNonvirtualFloatMethodV,
4643 &CallNonvirtualFloatMethodA,
4644 &CallNonvirtualDoubleMethod,
4645 &CallNonvirtualDoubleMethodV,
4646 &CallNonvirtualDoubleMethodA,
4647 &CallNonvirtualVoidMethod,
4648 &CallNonvirtualVoidMethodV,
4649 &CallNonvirtualVoidMethodA,
4674 &CallStaticObjectMethod,
4675 &CallStaticObjectMethodV,
4676 &CallStaticObjectMethodA,
4677 &CallStaticBooleanMethod,
4678 &CallStaticBooleanMethodV,
4679 &CallStaticBooleanMethodA,
4680 &CallStaticByteMethod,
4681 &CallStaticByteMethodV,
4682 &CallStaticByteMethodA,
4683 &CallStaticCharMethod,
4684 &CallStaticCharMethodV,
4685 &CallStaticCharMethodA,
4686 &CallStaticShortMethod,
4687 &CallStaticShortMethodV,
4688 &CallStaticShortMethodA,
4689 &CallStaticIntMethod,
4690 &CallStaticIntMethodV,
4691 &CallStaticIntMethodA,
4692 &CallStaticLongMethod,
4693 &CallStaticLongMethodV,
4694 &CallStaticLongMethodA,
4695 &CallStaticFloatMethod,
4696 &CallStaticFloatMethodV,
4697 &CallStaticFloatMethodA,
4698 &CallStaticDoubleMethod,
4699 &CallStaticDoubleMethodV,
4700 &CallStaticDoubleMethodA,
4701 &CallStaticVoidMethod,
4702 &CallStaticVoidMethodV,
4703 &CallStaticVoidMethodA,
4707 &GetStaticObjectField,
4708 &GetStaticBooleanField,
4709 &GetStaticByteField,
4710 &GetStaticCharField,
4711 &GetStaticShortField,
4713 &GetStaticLongField,
4714 &GetStaticFloatField,
4715 &GetStaticDoubleField,
4716 &SetStaticObjectField,
4717 &SetStaticBooleanField,
4718 &SetStaticByteField,
4719 &SetStaticCharField,
4720 &SetStaticShortField,
4722 &SetStaticLongField,
4723 &SetStaticFloatField,
4724 &SetStaticDoubleField,
4729 &ReleaseStringChars,
4732 &GetStringUTFLength,
4734 &ReleaseStringUTFChars,
4739 &GetObjectArrayElement,
4740 &SetObjectArrayElement,
4751 &GetBooleanArrayElements,
4752 &GetByteArrayElements,
4753 &GetCharArrayElements,
4754 &GetShortArrayElements,
4755 &GetIntArrayElements,
4756 &GetLongArrayElements,
4757 &GetFloatArrayElements,
4758 &GetDoubleArrayElements,
4760 &ReleaseBooleanArrayElements,
4761 &ReleaseByteArrayElements,
4762 &ReleaseCharArrayElements,
4763 &ReleaseShortArrayElements,
4764 &ReleaseIntArrayElements,
4765 &ReleaseLongArrayElements,
4766 &ReleaseFloatArrayElements,
4767 &ReleaseDoubleArrayElements,
4769 &GetBooleanArrayRegion,
4770 &GetByteArrayRegion,
4771 &GetCharArrayRegion,
4772 &GetShortArrayRegion,
4774 &GetLongArrayRegion,
4775 &GetFloatArrayRegion,
4776 &GetDoubleArrayRegion,
4777 &SetBooleanArrayRegion,
4778 &SetByteArrayRegion,
4779 &SetCharArrayRegion,
4780 &SetShortArrayRegion,
4782 &SetLongArrayRegion,
4783 &SetFloatArrayRegion,
4784 &SetDoubleArrayRegion,
4794 /* new JNI 1.2 functions */
4797 &GetStringUTFRegion,
4799 &GetPrimitiveArrayCritical,
4800 &ReleasePrimitiveArrayCritical,
4803 &ReleaseStringCritical,
4806 &DeleteWeakGlobalRef,
4810 /* new JNI 1.4 functions */
4812 &NewDirectByteBuffer,
4813 &GetDirectBufferAddress,
4814 &GetDirectBufferCapacity
4818 /* Invocation API Functions ***************************************************/
4820 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4822 Returns a default configuration for the Java VM.
4824 *******************************************************************************/
4826 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4828 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4830 /* GNU classpath currently supports JNI 1.2 */
4832 _vm_args->version = JNI_VERSION_1_2;
4838 /* JNI_GetCreatedJavaVMs *******************************************************
4840 Returns all Java VMs that have been created. Pointers to VMs are written in
4841 the buffer vmBuf in the order they are created. At most bufLen number of
4842 entries will be written. The total number of created VMs is returned in
4845 *******************************************************************************/
4847 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4849 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4855 /* JNI_CreateJavaVM ************************************************************
4857 Loads and initializes a Java VM. The current thread becomes the main thread.
4858 Sets the env argument to the JNI interface pointer of the main thread.
4860 *******************************************************************************/
4862 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4864 const struct JNIInvokeInterface *vm;
4865 struct JNINativeInterface *env;
4867 vm = &JNI_JavaVMTable;
4868 env = &JNI_JNIEnvTable;
4870 *p_vm = (JavaVM *) vm;
4871 *p_env = (JNIEnv *) env;
4877 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4878 jobject obj, java_objectarray *params)
4885 if (methodID == 0) {
4886 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
4890 argcount = methodID->parseddesc->paramcount;
4891 paramcount = argcount;
4893 /* if method is non-static, remove the `this' pointer */
4895 if (!(methodID->flags & ACC_STATIC))
4898 /* the method is an instance method the obj has to be an instance of the
4899 class the method belongs to. For static methods the obj parameter
4902 if (!(methodID->flags & ACC_STATIC) && obj &&
4903 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4905 new_exception_message(string_java_lang_IllegalArgumentException,
4906 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4910 if (((params == NULL) && (paramcount != 0)) ||
4911 (params && (params->header.size != paramcount))) {
4913 new_exception(string_java_lang_IllegalArgumentException);
4918 if (!(methodID->flags & ACC_STATIC) && !obj) {
4920 new_exception_message(string_java_lang_NullPointerException,
4921 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4925 if ((methodID->flags & ACC_STATIC) && (obj))
4929 if ((methodID->flags & ACC_ABSTRACT) ||
4930 (methodID->class->flags & ACC_INTERFACE)) {
4931 methodID = get_virtual(obj, methodID);
4935 blk = MNEW(jni_callblock, argcount);
4937 if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4941 switch (methodID->parseddesc->returntype.decltype) {
4943 (void) asm_calljavafunction2(methodID, argcount,
4944 argcount * sizeof(jni_callblock),
4946 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4949 case PRIMITIVETYPE_INT: {
4951 i = asm_calljavafunction2int(methodID, argcount,
4952 argcount * sizeof(jni_callblock),
4955 o = native_new_and_init_int(class_java_lang_Integer, i);
4959 case PRIMITIVETYPE_BYTE: {
4961 i = asm_calljavafunction2int(methodID, argcount,
4962 argcount * sizeof(jni_callblock),
4965 /* o = native_new_and_init_int(class_java_lang_Byte, i); */
4966 o = builtin_new(class_java_lang_Byte);
4969 class_resolvemethod(o->vftbl->class,
4976 case PRIMITIVETYPE_CHAR: {
4978 intVal = asm_calljavafunction2int(methodID,
4980 argcount * sizeof(jni_callblock),
4982 o = builtin_new(class_java_lang_Character);
4985 class_resolvemethod(o->vftbl->class,
4992 case PRIMITIVETYPE_SHORT: {
4994 intVal = asm_calljavafunction2int(methodID,
4996 argcount * sizeof(jni_callblock),
4998 o = builtin_new(class_java_lang_Short);
5001 class_resolvemethod(o->vftbl->class,
5008 case PRIMITIVETYPE_BOOLEAN: {
5010 intVal = asm_calljavafunction2int(methodID,
5012 argcount * sizeof(jni_callblock),
5014 o = builtin_new(class_java_lang_Boolean);
5017 class_resolvemethod(o->vftbl->class,
5024 case PRIMITIVETYPE_LONG: {
5026 longVal = asm_calljavafunction2long(methodID,
5028 argcount * sizeof(jni_callblock),
5030 o = builtin_new(class_java_lang_Long);
5033 class_resolvemethod(o->vftbl->class,
5040 case PRIMITIVETYPE_FLOAT: {
5042 floatVal = asm_calljavafunction2float(methodID,
5044 argcount * sizeof(jni_callblock),
5046 o = builtin_new(class_java_lang_Float);
5049 class_resolvemethod(o->vftbl->class,
5056 case PRIMITIVETYPE_DOUBLE: {
5058 doubleVal = asm_calljavafunction2double(methodID,
5060 argcount * sizeof(jni_callblock),
5062 o = builtin_new(class_java_lang_Double);
5065 class_resolvemethod(o->vftbl->class,
5073 o = asm_calljavafunction2(methodID, argcount,
5074 argcount * sizeof(jni_callblock), blk);
5078 /* if this happens the exception has already been set by */
5079 /* fill_callblock_from_objectarray */
5081 MFREE(blk, jni_callblock, argcount);
5082 return (jobject *) 0;
5085 MFREE(blk, jni_callblock, argcount);
5087 if (*exceptionptr) {
5088 java_objectheader *cause;
5090 cause = *exceptionptr;
5092 /* clear exception pointer, we are calling JIT code again */
5094 *exceptionptr = NULL;
5097 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
5098 (java_lang_Throwable *) cause);
5101 return (jobject *) o;
5106 * These are local overrides for various environment variables in Emacs.
5107 * Please do not remove this and leave it at the end of the file, where
5108 * Emacs will automagically detect them.
5109 * ---------------------------------------------------------------------
5112 * indent-tabs-mode: t