1 /* src/native/jni.c - implementation of the Java Native Interface functions
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Rainhard Grafl
30 Changes: Joseph Wenninger
34 $Id: jni.c 4357 2006-01-22 23:33:38Z 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 classinfo *class_java_nio_Buffer;
135 static classinfo *class_java_nio_DirectByteBufferImpl;
136 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
137 #if SIZEOF_VOID_P == 8
138 static classinfo *class_gnu_classpath_Pointer64;
140 static classinfo *class_gnu_classpath_Pointer32;
143 static methodinfo *dbbirw_init;
146 /* local reference table ******************************************************/
148 #if !defined(USE_THREADS)
149 localref_table *_no_threads_localref_table;
153 /* accessing instance fields macros *******************************************/
155 #define SET_FIELD(obj,type,var,value) \
156 *((type *) ((ptrint) (obj) + (ptrint) (var)->offset)) = (type) (value)
158 #define GET_FIELD(obj,type,var) \
159 *((type *) ((ptrint) (obj) + (ptrint) (var)->offset))
162 /* some forward declarations **************************************************/
164 jobject NewLocalRef(JNIEnv *env, jobject ref);
167 /* jni_init ********************************************************************
169 Initialize the JNI subsystem.
171 *******************************************************************************/
175 /* initalize global reference table */
178 load_class_bootstrap(utf_new_char("java/util/IdentityHashMap"))))
181 global_ref_table = GCNEW(jobject, 1);
183 if (!(*global_ref_table = native_new_and_init(ihmclass)))
186 if (!(getmid = class_resolvemethod(ihmclass, utf_get,
187 utf_java_lang_Object__java_lang_Object)))
190 if (!(putmid = class_resolvemethod(ihmclass, utf_put,
191 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))))
195 class_resolvemethod(ihmclass, utf_remove,
196 utf_java_lang_Object__java_lang_Object)))
200 /* direct buffer stuff */
202 if (!(class_java_nio_Buffer =
203 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
204 !link_class(class_java_nio_Buffer))
207 if (!(class_java_nio_DirectByteBufferImpl =
208 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
209 !link_class(class_java_nio_DirectByteBufferImpl))
212 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
213 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
214 !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 if (!(class_gnu_classpath_Pointer64 =
225 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
226 !link_class(class_gnu_classpath_Pointer64))
229 if (!(class_gnu_classpath_Pointer32 =
230 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
231 !link_class(class_gnu_classpath_Pointer32))
239 static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
240 jni_callblock blk[], va_list data,
243 typedesc *paramtypes;
246 paramtypes = descr->paramtypes;
248 /* if method is non-static fill first block and skip `this' pointer */
253 /* the `this' pointer */
254 blk[0].itemtype = TYPE_ADR;
255 blk[0].item = PTR_TO_ITEM(obj);
261 for (; i < descr->paramcount; i++, paramtypes++) {
262 switch (paramtypes->decltype) {
263 /* primitive types */
264 case PRIMITIVETYPE_BYTE:
265 case PRIMITIVETYPE_CHAR:
266 case PRIMITIVETYPE_SHORT:
267 case PRIMITIVETYPE_BOOLEAN:
268 blk[i].itemtype = TYPE_INT;
269 blk[i].item = (s8) va_arg(data, s4);
272 case PRIMITIVETYPE_INT:
273 blk[i].itemtype = TYPE_INT;
274 blk[i].item = (s8) va_arg(data, s4);
277 case PRIMITIVETYPE_LONG:
278 blk[i].itemtype = TYPE_LNG;
279 blk[i].item = (s8) va_arg(data, s8);
282 case PRIMITIVETYPE_FLOAT:
283 blk[i].itemtype = TYPE_FLT;
284 #if defined(__ALPHA__)
285 /* this keeps the assembler function much simpler */
287 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
289 *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
293 case PRIMITIVETYPE_DOUBLE:
294 blk[i].itemtype = TYPE_DBL;
295 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
299 blk[i].itemtype = TYPE_ADR;
300 blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
305 /* The standard doesn't say anything about return value checking, but it */
306 /* appears to be useful. */
308 if (rettype != descr->returntype.decltype)
309 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
313 /* XXX it could be considered if we should do typechecking here in the future */
315 static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
317 java_objectarray *params)
321 typedesc *paramtypes;
326 paramcount = descr->paramcount;
327 paramtypes = descr->paramtypes;
329 /* if method is non-static fill first block and skip `this' pointer */
335 blk[0].itemtype = TYPE_ADR;
336 blk[0].item = PTR_TO_ITEM(obj);
343 for (j = 0; j < paramcount; i++, j++, paramtypes++) {
344 switch (paramtypes->type) {
345 /* primitive types */
350 param = params->data[j];
354 /* internally used data type */
355 blk[i].itemtype = paramtypes->type;
357 /* convert the value according to its declared type */
359 c = param->vftbl->class;
361 switch (paramtypes->decltype) {
362 case PRIMITIVETYPE_BOOLEAN:
363 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
364 blk[i].item = (s8) ((java_lang_Boolean *) param)->value;
369 case PRIMITIVETYPE_BYTE:
370 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
371 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
376 case PRIMITIVETYPE_CHAR:
377 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
378 blk[i].item = (s8) ((java_lang_Character *) param)->value;
383 case PRIMITIVETYPE_SHORT:
384 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
385 blk[i].item = (s8) ((java_lang_Short *) param)->value;
386 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
387 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
392 case PRIMITIVETYPE_INT:
393 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
394 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
395 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
396 blk[i].item = (s8) ((java_lang_Short *) param)->value;
397 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
398 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
403 case PRIMITIVETYPE_LONG:
404 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
405 blk[i].item = (s8) ((java_lang_Long *) param)->value;
406 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
407 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
408 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
409 blk[i].item = (s8) ((java_lang_Short *) param)->value;
410 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
411 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
416 case PRIMITIVETYPE_FLOAT:
417 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
418 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
423 case PRIMITIVETYPE_DOUBLE:
424 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
425 *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Double *) param)->value;
426 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
427 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
434 } /* end declared type switch */
438 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
441 if (params->data[j] != 0) {
442 if (paramtypes->arraydim > 0) {
443 if (!builtin_arrayinstanceof(params->data[j], c))
447 if (!builtin_instanceof(params->data[j], c))
451 blk[i].itemtype = TYPE_ADR;
452 blk[i].item = PTR_TO_ITEM(params->data[j]);
457 } /* end param type switch */
459 } /* end param loop */
462 /* *rettype = descr->returntype.decltype; */
467 exceptions_throw_illegalargumentexception();
472 static jmethodID get_virtual(jobject obj, jmethodID methodID)
474 if (obj->vftbl->class == methodID->class)
477 return class_resolvemethod(obj->vftbl->class, methodID->name,
478 methodID->descriptor);
482 static jmethodID get_nonvirtual(jclass clazz, jmethodID methodID)
484 if (clazz == methodID->class)
487 /* class_resolvemethod -> classfindmethod? (JOWENN) */
488 return class_resolvemethod(clazz, methodID->name, methodID->descriptor);
492 /* _Jv_jni_CallVoidMethod ******************************************************
494 Internal function to call Java void functions.
496 *******************************************************************************/
498 static void _Jv_jni_CallVoidMethod(jobject obj, jmethodID m, va_list ap)
504 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
508 if (!( ((m->flags & ACC_STATIC) && (obj == 0)) ||
509 ((!(m->flags & ACC_STATIC)) && (obj != 0)) )) {
510 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
514 if (obj && !builtin_instanceof(obj, m->class)) {
515 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
519 paramcount = m->parseddesc->paramcount;
521 blk = MNEW(jni_callblock, paramcount);
523 fill_callblock_from_vargs(obj, m->parseddesc, blk, ap, TYPE_VOID);
525 STATISTICS(jnicallXmethodnvokation());
527 ASM_CALLJAVAFUNCTION2(m, paramcount,
528 paramcount * sizeof(jni_callblock),
531 MFREE(blk, jni_callblock, paramcount);
535 static jobject callObjectMethod(jobject obj, jmethodID methodID, va_list args)
542 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
546 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
547 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
548 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
552 if (obj && !builtin_instanceof(obj, methodID->class)) {
553 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
557 argcount = methodID->parseddesc->paramcount;
559 blk = MNEW(jni_callblock, argcount);
561 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_ADR);
563 STATISTICS(jnicallXmethodnvokation());
565 ASM_CALLJAVAFUNCTION2_ADR(ret, methodID, argcount,
566 argcount * sizeof(jni_callblock),
569 MFREE(blk, jni_callblock, argcount);
576 core function for integer class methods (bool, byte, short, integer)
577 This is basically needed for i386
579 static jint callIntegerMethod(jobject obj, jmethodID methodID, int retType, va_list args)
585 STATISTICS(jniinvokation());
588 log_text("JNI-Call: CallObjectMethodV");
589 utf_display(methodID->name);
590 utf_display(methodID->descriptor);
591 printf("\nParmaeter count: %d\n",argcount);
592 utf_display(obj->vftbl->class->name);
596 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
600 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
601 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
602 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
606 if (obj && !builtin_instanceof(obj, methodID->class)) {
607 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
611 argcount = methodID->parseddesc->paramcount;
613 blk = MNEW(jni_callblock, argcount);
615 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
617 STATISTICS(jnicallXmethodnvokation());
619 ASM_CALLJAVAFUNCTION2_INT(ret, methodID, argcount,
620 argcount * sizeof(jni_callblock),
623 MFREE(blk, jni_callblock, argcount);
629 /* callLongMethod **************************************************************
631 Core function for long class functions.
633 *******************************************************************************/
635 static jlong _Jv_jni_CallLongMethod(jobject obj, jmethodID m, va_list ap)
641 STATISTICS(jniinvokation());
644 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
648 if (!( ((m->flags & ACC_STATIC) && (obj == 0)) ||
649 ((!(m->flags & ACC_STATIC)) && (obj != 0)) )) {
650 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
654 if (obj && !builtin_instanceof(obj, m->class)) {
655 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
659 paramcount = m->parseddesc->paramcount;
661 blk = MNEW(jni_callblock, paramcount);
663 fill_callblock_from_vargs(obj, m->parseddesc, blk, ap, TYPE_LNG);
665 STATISTICS(jnicallXmethodnvokation());
667 ASM_CALLJAVAFUNCTION2_LONG(ret, m, paramcount,
668 paramcount * sizeof(jni_callblock),
671 MFREE(blk, jni_callblock, paramcount);
677 /*core function for float class methods (float,double)*/
678 static jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,int retType)
680 int argcount = methodID->parseddesc->paramcount;
684 STATISTICS(jniinvokation());
689 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
690 log_text("Too many arguments. CallObjectMethod does not support that");
694 blk = MNEW(jni_callblock, /*4 */ argcount+2);
696 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
698 STATISTICS(jnicallXmethodnvokation());
700 ASM_CALLJAVAFUNCTION2_DOUBLE(ret, methodID, argcount + 1,
701 (argcount + 1) * sizeof(jni_callblock),
704 MFREE(blk, jni_callblock, argcount + 1);
710 /* _Jv_jni_invokeNative ********************************************************
712 *******************************************************************************/
714 jobject *_Jv_jni_invokeNative(methodinfo *m, jobject obj,
715 java_objectarray *params)
718 java_objectheader *o;
723 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
727 argcount = m->parseddesc->paramcount;
728 paramcount = argcount;
730 /* if method is non-static, remove the `this' pointer */
732 if (!(m->flags & ACC_STATIC))
735 /* the method is an instance method the obj has to be an instance of the
736 class the method belongs to. For static methods the obj parameter
739 if (!(m->flags & ACC_STATIC) && obj &&
740 (!builtin_instanceof((java_objectheader *) obj, m->class))) {
742 new_exception_message(string_java_lang_IllegalArgumentException,
743 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
747 if (((params == NULL) && (paramcount != 0)) ||
748 (params && (params->header.size != paramcount))) {
750 new_exception(string_java_lang_IllegalArgumentException);
755 if (!(m->flags & ACC_STATIC) && !obj) {
757 new_exception_message(string_java_lang_NullPointerException,
758 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
762 if ((m->flags & ACC_STATIC) && (obj))
766 if ((m->flags & ACC_ABSTRACT) ||
767 (m->class->flags & ACC_INTERFACE)) {
768 m = get_virtual(obj, m);
772 blk = MNEW(jni_callblock, argcount);
774 if (!fill_callblock_from_objectarray(obj, m->parseddesc, blk,
778 switch (m->parseddesc->returntype.decltype) {
780 ASM_CALLJAVAFUNCTION2(m, argcount,
781 argcount * sizeof(jni_callblock),
787 case PRIMITIVETYPE_BOOLEAN: {
789 java_lang_Boolean *bo;
791 ASM_CALLJAVAFUNCTION2_INT(i, m, argcount,
792 argcount * sizeof(jni_callblock),
795 o = builtin_new(class_java_lang_Boolean);
797 /* setting the value of the object direct */
799 bo = (java_lang_Boolean *) o;
804 case PRIMITIVETYPE_BYTE: {
808 ASM_CALLJAVAFUNCTION2_INT(i, m, argcount,
809 argcount * sizeof(jni_callblock),
812 o = builtin_new(class_java_lang_Byte);
814 /* setting the value of the object direct */
816 bo = (java_lang_Byte *) o;
821 case PRIMITIVETYPE_CHAR: {
823 java_lang_Character *co;
825 ASM_CALLJAVAFUNCTION2_INT(i, m, argcount,
826 argcount * sizeof(jni_callblock),
829 o = builtin_new(class_java_lang_Character);
831 /* setting the value of the object direct */
833 co = (java_lang_Character *) o;
838 case PRIMITIVETYPE_SHORT: {
842 ASM_CALLJAVAFUNCTION2_INT(i, m, argcount,
843 argcount * sizeof(jni_callblock),
846 o = builtin_new(class_java_lang_Short);
848 /* setting the value of the object direct */
850 so = (java_lang_Short *) o;
855 case PRIMITIVETYPE_INT: {
857 java_lang_Integer *io;
859 ASM_CALLJAVAFUNCTION2_INT(i, m, argcount,
860 argcount * sizeof(jni_callblock),
863 o = builtin_new(class_java_lang_Integer);
865 /* setting the value of the object direct */
867 io = (java_lang_Integer *) o;
872 case PRIMITIVETYPE_LONG: {
876 ASM_CALLJAVAFUNCTION2_LONG(l, m, argcount,
877 argcount * sizeof(jni_callblock),
880 o = builtin_new(class_java_lang_Long);
882 /* setting the value of the object direct */
884 lo = (java_lang_Long *) o;
889 case PRIMITIVETYPE_FLOAT: {
893 ASM_CALLJAVAFUNCTION2_FLOAT(f, m, argcount,
894 argcount * sizeof(jni_callblock),
897 o = builtin_new(class_java_lang_Float);
899 /* setting the value of the object direct */
901 fo = (java_lang_Float *) o;
906 case PRIMITIVETYPE_DOUBLE: {
908 java_lang_Double *_do;
910 ASM_CALLJAVAFUNCTION2_DOUBLE(d, m, argcount,
911 argcount * sizeof(jni_callblock),
914 o = builtin_new(class_java_lang_Double);
916 /* setting the value of the object direct */
918 _do = (java_lang_Double *) o;
924 ASM_CALLJAVAFUNCTION2_ADR(o, m, argcount,
925 argcount * sizeof(jni_callblock),
930 /* if this happens the exception has already been set by
931 fill_callblock_from_objectarray */
933 MFREE(blk, jni_callblock, argcount);
935 return (jobject *) 0;
938 MFREE(blk, jni_callblock, argcount);
941 java_objectheader *cause;
943 cause = *exceptionptr;
945 /* clear exception pointer, we are calling JIT code again */
947 *exceptionptr = NULL;
950 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
951 (java_lang_Throwable *) cause);
954 return (jobject *) o;
958 /* GetVersion ******************************************************************
960 Returns the major version number in the higher 16 bits and the
961 minor version number in the lower 16 bits.
963 *******************************************************************************/
965 jint GetVersion(JNIEnv *env)
967 STATISTICS(jniinvokation());
969 /* we support JNI 1.4 */
971 return JNI_VERSION_1_4;
975 /* Class Operations ***********************************************************/
977 /* DefineClass *****************************************************************
979 Loads a class from a buffer of raw class data. The buffer
980 containing the raw class data is not referenced by the VM after the
981 DefineClass call returns, and it may be discarded if desired.
983 *******************************************************************************/
985 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
986 const jbyte *buf, jsize bufLen)
988 java_lang_ClassLoader *cl;
993 STATISTICS(jniinvokation());
995 cl = (java_lang_ClassLoader *) loader;
996 s = javastring_new_char(name);
997 ba = (java_bytearray *) buf;
999 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
1002 return (jclass) NewLocalRef(env, (jobject) c);
1006 /* FindClass *******************************************************************
1008 This function loads a locally-defined class. It searches the
1009 directories and zip files specified by the CLASSPATH environment
1010 variable for the class with the specified name.
1012 *******************************************************************************/
1014 jclass FindClass(JNIEnv *env, const char *name)
1018 java_objectheader *cl;
1020 STATISTICS(jniinvokation());
1022 u = utf_new_char_classname((char *) name);
1024 /* check stacktrace for classloader, if one found use it, otherwise use */
1025 /* the system classloader */
1027 #if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__)
1028 /* these JITs support stacktraces, and so does the interpreter */
1030 cl = cacao_currentClassLoader();
1032 # if defined(ENABLE_INTRP)
1033 /* the interpreter supports stacktraces, even if the JIT does not */
1036 cl = cacao_currentClassLoader();
1042 if (!(c = load_class_from_classloader(u, cl)))
1048 return (jclass) NewLocalRef(env, (jobject) c);
1052 /* FromReflectedMethod *********************************************************
1054 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1055 object to a method ID.
1057 *******************************************************************************/
1059 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
1065 STATISTICS(jniinvokation());
1070 if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
1071 java_lang_reflect_Method *rm;
1073 rm = (java_lang_reflect_Method *) method;
1074 c = (classinfo *) (rm->declaringClass);
1077 } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
1078 java_lang_reflect_Constructor *rc;
1080 rc = (java_lang_reflect_Constructor *) method;
1081 c = (classinfo *) (rc->clazz);
1087 if ((slot < 0) || (slot >= c->methodscount)) {
1088 /* this usually means a severe internal cacao error or somebody
1089 tempered around with the reflected method */
1090 log_text("error illegal slot for method in class(FromReflectedMethod)");
1094 mi = &(c->methods[slot]);
1100 /* GetSuperclass ***************************************************************
1102 If clazz represents any class other than the class Object, then
1103 this function returns the object that represents the superclass of
1104 the class specified by clazz.
1106 *******************************************************************************/
1108 jclass GetSuperclass(JNIEnv *env, jclass sub)
1112 STATISTICS(jniinvokation());
1114 c = ((classinfo *) sub)->super.cls;
1119 return (jclass) NewLocalRef(env, (jobject) c);
1123 /* IsAssignableFrom ************************************************************
1125 Determines whether an object of sub can be safely cast to sup.
1127 *******************************************************************************/
1129 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1131 STATISTICS(jniinvokation());
1133 return Java_java_lang_VMClass_isAssignableFrom(env,
1135 (java_lang_Class *) sup,
1136 (java_lang_Class *) sub);
1140 /* Throw ***********************************************************************
1142 Causes a java.lang.Throwable object to be thrown.
1144 *******************************************************************************/
1146 jint Throw(JNIEnv *env, jthrowable obj)
1148 STATISTICS(jniinvokation());
1150 *exceptionptr = (java_objectheader *) obj;
1156 /* ThrowNew ********************************************************************
1158 Constructs an exception object from the specified class with the
1159 message specified by message and causes that exception to be
1162 *******************************************************************************/
1164 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1166 java_lang_Throwable *o;
1167 java_lang_String *s;
1169 STATISTICS(jniinvokation());
1171 s = (java_lang_String *) javastring_new_char(msg);
1173 /* instantiate exception object */
1175 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
1181 *exceptionptr = (java_objectheader *) o;
1187 /* ExceptionOccurred ***********************************************************
1189 Determines if an exception is being thrown. The exception stays
1190 being thrown until either the native code calls ExceptionClear(),
1191 or the Java code handles the exception.
1193 *******************************************************************************/
1195 jthrowable ExceptionOccurred(JNIEnv *env)
1197 java_objectheader *e;
1199 STATISTICS(jniinvokation());
1203 return NewLocalRef(env, (jthrowable) e);
1207 /* ExceptionDescribe ***********************************************************
1209 Prints an exception and a backtrace of the stack to a system
1210 error-reporting channel, such as stderr. This is a convenience
1211 routine provided for debugging.
1213 *******************************************************************************/
1215 void ExceptionDescribe(JNIEnv *env)
1217 java_objectheader *e;
1220 STATISTICS(jniinvokation());
1225 /* clear exception, because we are calling jit code again */
1227 *exceptionptr = NULL;
1229 /* get printStackTrace method from exception class */
1231 m = class_resolveclassmethod(e->vftbl->class,
1232 utf_printStackTrace,
1238 /* XXX what should we do? */
1241 /* print the stacktrace */
1243 ASM_CALLJAVAFUNCTION(m, e, NULL, NULL, NULL);
1248 /* ExceptionClear **************************************************************
1250 Clears any exception that is currently being thrown. If no
1251 exception is currently being thrown, this routine has no effect.
1253 *******************************************************************************/
1255 void ExceptionClear(JNIEnv *env)
1257 STATISTICS(jniinvokation());
1259 *exceptionptr = NULL;
1263 /* FatalError ******************************************************************
1265 Raises a fatal error and does not expect the VM to recover. This
1266 function does not return.
1268 *******************************************************************************/
1270 void FatalError(JNIEnv *env, const char *msg)
1272 STATISTICS(jniinvokation());
1274 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
1278 /* PushLocalFrame **************************************************************
1280 Creates a new local reference frame, in which at least a given
1281 number of local references can be created.
1283 *******************************************************************************/
1285 jint PushLocalFrame(JNIEnv* env, jint capacity)
1287 STATISTICS(jniinvokation());
1289 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
1296 /* PopLocalFrame ***************************************************************
1298 Pops off the current local reference frame, frees all the local
1299 references, and returns a local reference in the previous local
1300 reference frame for the given result object.
1302 *******************************************************************************/
1304 jobject PopLocalFrame(JNIEnv* env, jobject result)
1306 STATISTICS(jniinvokation());
1308 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
1312 /* add local reference and return the value */
1314 return NewLocalRef(env, NULL);
1318 /* DeleteLocalRef **************************************************************
1320 Deletes the local reference pointed to by localRef.
1322 *******************************************************************************/
1324 void DeleteLocalRef(JNIEnv *env, jobject localRef)
1326 java_objectheader *o;
1327 localref_table *lrt;
1330 STATISTICS(jniinvokation());
1332 o = (java_objectheader *) localRef;
1334 /* get local reference table (thread specific) */
1336 lrt = LOCALREFTABLE;
1338 /* remove the reference */
1340 for (i = 0; i < lrt->capacity; i++) {
1341 if (lrt->refs[i] == o) {
1342 lrt->refs[i] = NULL;
1349 /* this should not happen */
1351 /* if (opt_checkjni) */
1352 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1353 log_text("JNI-DeleteLocalRef: Bad global or local ref passed to JNI");
1357 /* IsSameObject ****************************************************************
1359 Tests whether two references refer to the same Java object.
1361 *******************************************************************************/
1363 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1365 STATISTICS(jniinvokation());
1374 /* NewLocalRef *****************************************************************
1376 Creates a new local reference that refers to the same object as ref.
1378 *******************************************************************************/
1380 jobject NewLocalRef(JNIEnv *env, jobject ref)
1382 localref_table *lrt;
1385 STATISTICS(jniinvokation());
1390 /* get local reference table (thread specific) */
1392 lrt = LOCALREFTABLE;
1394 /* check if we have space for the requested reference */
1396 if (lrt->used == lrt->capacity)
1397 throw_cacao_exception_exit(string_java_lang_InternalError,
1398 "Too many local references");
1400 /* insert the reference */
1402 for (i = 0; i < lrt->capacity; i++) {
1403 if (lrt->refs[i] == NULL) {
1404 lrt->refs[i] = (java_objectheader *) ref;
1411 /* should not happen, just to be sure */
1415 /* keep compiler happy */
1421 /* EnsureLocalCapacity *********************************************************
1423 Ensures that at least a given number of local references can be
1424 created in the current thread
1426 *******************************************************************************/
1428 jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
1430 localref_table *lrt;
1432 STATISTICS(jniinvokation());
1434 /* get local reference table (thread specific) */
1436 lrt = LOCALREFTABLE;
1438 /* check if capacity elements are available in the local references table */
1440 if ((lrt->used + capacity) > lrt->capacity) {
1441 *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
1449 /* AllocObject *****************************************************************
1451 Allocates a new Java object without invoking any of the
1452 constructors for the object. Returns a reference to the object.
1454 *******************************************************************************/
1456 jobject AllocObject(JNIEnv *env, jclass clazz)
1458 java_objectheader *o;
1460 STATISTICS(jniinvokation());
1462 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1464 new_exception_utfmessage(string_java_lang_InstantiationException,
1469 o = builtin_new(clazz);
1471 return NewLocalRef(env, o);
1475 /* NewObject *******************************************************************
1477 Programmers place all arguments that are to be passed to the
1478 constructor immediately following the methodID
1479 argument. NewObject() accepts these arguments and passes them to
1480 the Java method that the programmer wishes to invoke.
1482 *******************************************************************************/
1484 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1486 java_objectheader *o;
1489 STATISTICS(jniinvokation());
1493 o = builtin_new(clazz);
1498 /* call constructor */
1500 va_start(ap, methodID);
1501 _Jv_jni_CallVoidMethod(o, methodID, ap);
1504 return NewLocalRef(env, o);
1508 /***********************************************************************************
1510 Constructs a new Java object
1511 arguments that are to be passed to the constructor are placed in va_list args
1513 ***********************************************************************************/
1515 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1517 STATISTICS(jniinvokation());
1519 log_text("JNI-Call: NewObjectV: IMPLEMENT ME!");
1521 return NewLocalRef(env, NULL);
1525 /***********************************************************************************
1527 Constructs a new Java object
1528 arguments that are to be passed to the constructor are placed in
1529 args array of jvalues
1531 ***********************************************************************************/
1533 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1535 STATISTICS(jniinvokation());
1537 log_text("JNI-Call: NewObjectA: IMPLEMENT ME!");
1539 return NewLocalRef(env, NULL);
1543 /* GetObjectClass **************************************************************
1545 Returns the class of an object.
1547 *******************************************************************************/
1549 jclass GetObjectClass(JNIEnv *env, jobject obj)
1553 STATISTICS(jniinvokation());
1555 if (!obj || !obj->vftbl)
1558 c = obj->vftbl->class;
1560 return (jclass) NewLocalRef(env, (jobject) c);
1564 /* IsInstanceOf ****************************************************************
1566 Tests whether an object is an instance of a class.
1568 *******************************************************************************/
1570 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1572 STATISTICS(jniinvokation());
1574 return Java_java_lang_VMClass_isInstance(env,
1576 (java_lang_Class *) clazz,
1577 (java_lang_Object *) obj);
1581 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1583 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1585 java_lang_reflect_Field *f;
1587 jfieldID fid; /* the JNI-fieldid of the wrapping object */
1589 STATISTICS(jniinvokation());
1591 /*log_text("JNI-Call: FromReflectedField");*/
1593 f=(java_lang_reflect_Field *)field;
1595 c=(classinfo*)(f->declaringClass);
1596 if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1597 /*this usually means a severe internal cacao error or somebody
1598 tempered around with the reflected method*/
1599 log_text("error illegal slot for field in class(FromReflectedField)");
1602 fid=&(c->fields[f->slot]);
1607 /* ToReflectedMethod ***********************************************************
1609 Converts a method ID derived from cls to an instance of the
1610 java.lang.reflect.Method class or to an instance of the
1611 java.lang.reflect.Constructor class.
1613 *******************************************************************************/
1615 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1617 STATISTICS(jniinvokation());
1619 log_text("JNI-Call: ToReflectedMethod: IMPLEMENT ME!");
1625 /* ToReflectedField ************************************************************
1627 Converts a field ID derived from cls to an instance of the
1628 java.lang.reflect.Field class.
1630 *******************************************************************************/
1632 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1635 STATISTICS(jniinvokation());
1637 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1643 /* Calling Instance Methods ***************************************************/
1645 /* GetMethodID *****************************************************************
1647 Returns the method ID for an instance (nonstatic) method of a class
1648 or interface. The method may be defined in one of the clazz's
1649 superclasses and inherited by clazz. The method is determined by
1650 its name and signature.
1652 GetMethodID() causes an uninitialized class to be initialized.
1654 *******************************************************************************/
1656 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1664 STATISTICS(jniinvokation());
1666 c = (classinfo *) clazz;
1671 if (!(c->state & CLASS_INITIALIZED))
1672 if (!initialize_class(c))
1675 /* try to get the method of the class or one of it's superclasses */
1677 uname = utf_new_char((char *) name);
1678 udesc = utf_new_char((char *) sig);
1680 m = class_resolvemethod(clazz, uname, udesc);
1682 if (!m || (m->flags & ACC_STATIC)) {
1683 *exceptionptr = exceptions_new_nosuchmethoderror(c, uname, udesc);
1692 /******************** JNI-functions for calling instance methods ******************/
1694 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1696 java_objectheader* ret;
1699 STATISTICS(jniinvokation());
1701 va_start(vaargs, methodID);
1702 ret = callObjectMethod(obj, methodID, vaargs);
1705 return NewLocalRef(env, ret);
1709 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1711 java_objectheader* ret;
1713 STATISTICS(jniinvokation());
1715 ret = callObjectMethod(obj, methodID, args);
1717 return NewLocalRef(env, ret);
1721 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1723 STATISTICS(jniinvokation());
1725 log_text("JNI-Call: CallObjectMethodA: IMPLEMENT ME!");
1727 return NewLocalRef(env, NULL);
1733 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1738 STATISTICS(jniinvokation());
1740 /* log_text("JNI-Call: CallBooleanMethod");*/
1742 va_start(vaargs,methodID);
1743 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1749 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1751 STATISTICS(jniinvokation());
1753 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
1757 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1759 STATISTICS(jniinvokation());
1761 log_text("JNI-Call: CallBooleanMethodA");
1766 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1771 STATISTICS(jniinvokation());
1773 /* log_text("JNI-Call: CallVyteMethod");*/
1775 va_start(vaargs,methodID);
1776 ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
1782 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1784 /* log_text("JNI-Call: CallByteMethodV");*/
1786 STATISTICS(jniinvokation());
1788 return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
1792 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1794 STATISTICS(jniinvokation());
1796 log_text("JNI-Call: CallByteMethodA: IMPLEMENT ME!");
1802 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1807 STATISTICS(jniinvokation());
1809 /* log_text("JNI-Call: CallCharMethod");*/
1811 va_start(vaargs,methodID);
1812 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
1819 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1821 STATISTICS(jniinvokation());
1823 /* log_text("JNI-Call: CallCharMethodV");*/
1825 return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
1829 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1831 STATISTICS(jniinvokation());
1833 log_text("JNI-Call: CallCharMethodA: IMPLEMENT ME!");
1839 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1844 STATISTICS(jniinvokation());
1846 /* log_text("JNI-Call: CallShortMethod");*/
1848 va_start(vaargs, methodID);
1849 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
1856 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1858 STATISTICS(jniinvokation());
1860 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
1864 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1866 STATISTICS(jniinvokation());
1868 log_text("JNI-Call: CallShortMethodA: IMPLEMENT ME!");
1875 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1880 STATISTICS(jniinvokation());
1882 va_start(vaargs,methodID);
1883 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
1890 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1892 STATISTICS(jniinvokation());
1894 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
1898 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1900 STATISTICS(jniinvokation());
1902 log_text("JNI-Call: CallIntMethodA: IMPLEMENT ME!");
1909 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1914 STATISTICS(jniinvokation());
1916 va_start(vaargs,methodID);
1917 ret = _Jv_jni_CallLongMethod(obj, get_virtual(obj, methodID), vaargs);
1924 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1926 STATISTICS(jniinvokation());
1928 return _Jv_jni_CallLongMethod(obj, get_virtual(obj, methodID), args);
1932 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1934 STATISTICS(jniinvokation());
1936 log_text("JNI-Call: CallLongMethodA: IMPLEMENT ME!");
1943 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1948 STATISTICS(jniinvokation());
1950 /* log_text("JNI-Call: CallFloatMethod");*/
1952 va_start(vaargs,methodID);
1953 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
1960 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1962 STATISTICS(jniinvokation());
1964 /* log_text("JNI-Call: CallFloatMethodV"); */
1966 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
1970 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1972 STATISTICS(jniinvokation());
1974 log_text("JNI-Call: CallFloatMethodA: IMPLEMENT ME!");
1981 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1986 STATISTICS(jniinvokation());
1988 /* log_text("JNI-Call: CallDoubleMethod");*/
1990 va_start(vaargs,methodID);
1991 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
1998 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2000 STATISTICS(jniinvokation());
2002 /* log_text("JNI-Call: CallDoubleMethodV"); */
2004 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
2008 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2010 STATISTICS(jniinvokation());
2012 log_text("JNI-Call: CallDoubleMethodA: IMPLEMENT ME!");
2019 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2023 STATISTICS(jniinvokation());
2025 va_start(vaargs,methodID);
2026 (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
2031 void CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2033 STATISTICS(jniinvokation());
2035 /* log_text("JNI-Call: CallVoidMethodV"); */
2037 (void) callIntegerMethod(obj, get_virtual(obj, methodID), TYPE_VOID,args);
2041 void CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2043 STATISTICS(jniinvokation());
2045 log_text("JNI-Call: CallVoidMethodA: IMPLEMENT ME!");
2050 jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2052 STATISTICS(jniinvokation());
2054 log_text("JNI-Call: CallNonvirtualObjectMethod: IMPLEMENT ME!");
2056 return NewLocalRef(env, NULL);
2060 jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2062 STATISTICS(jniinvokation());
2064 log_text("JNI-Call: CallNonvirtualObjectMethodV: IMPLEMENT ME!");
2066 return NewLocalRef(env, NULL);
2070 jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2072 STATISTICS(jniinvokation());
2074 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2076 return NewLocalRef(env, NULL);
2081 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2086 STATISTICS(jniinvokation());
2088 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
2090 va_start(vaargs,methodID);
2091 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
2099 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2101 STATISTICS(jniinvokation());
2103 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
2105 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
2109 jboolean CallNonvirtualBooleanMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2111 STATISTICS(jniinvokation());
2113 log_text("JNI-Call: CallNonvirtualBooleanMethodA: IMPLEMENT ME!");
2119 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2124 STATISTICS(jniinvokation());
2126 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
2128 va_start(vaargs,methodID);
2129 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
2136 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2138 STATISTICS(jniinvokation());
2140 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
2142 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
2146 jbyte CallNonvirtualByteMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2148 STATISTICS(jniinvokation());
2150 log_text("JNI-Call: CallNonvirtualByteMethodA: IMPLEMENT ME!");
2157 jchar CallNonvirtualCharMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2162 STATISTICS(jniinvokation());
2164 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
2166 va_start(vaargs,methodID);
2167 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
2174 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2176 STATISTICS(jniinvokation());
2178 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
2180 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
2184 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2186 STATISTICS(jniinvokation());
2188 log_text("JNI-Call: CallNonvirtualCharMethodA: IMPLEMENT ME!");
2195 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2200 STATISTICS(jniinvokation());
2202 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
2204 va_start(vaargs,methodID);
2205 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
2212 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2214 STATISTICS(jniinvokation());
2216 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
2218 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
2222 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2224 STATISTICS(jniinvokation());
2226 log_text("JNI-Call: CallNonvirtualShortMethodA: IMPLEMENT ME!");
2233 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2238 STATISTICS(jniinvokation());
2240 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
2242 va_start(vaargs,methodID);
2243 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
2250 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2252 STATISTICS(jniinvokation());
2254 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
2256 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
2260 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2262 STATISTICS(jniinvokation());
2264 log_text("JNI-Call: CallNonvirtualIntMethodA: IMPLEMENT ME!");
2271 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2273 STATISTICS(jniinvokation());
2275 log_text("JNI-Call: CallNonvirtualLongMethod: IMPLEMENT ME!");
2281 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2283 STATISTICS(jniinvokation());
2285 log_text("JNI-Call: CallNonvirtualLongMethodV: IMPLEMENT ME!");
2291 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2293 STATISTICS(jniinvokation());
2295 log_text("JNI-Call: CallNonvirtualLongMethodA: IMPLEMENT ME!");
2302 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2307 STATISTICS(jniinvokation());
2309 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
2311 va_start(vaargs,methodID);
2312 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
2319 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2321 STATISTICS(jniinvokation());
2323 /* log_text("JNI-Call: CallNonvirtualFloatMethodV"); */
2325 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
2329 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2331 STATISTICS(jniinvokation());
2333 log_text("JNI-Call: CallNonvirtualFloatMethodA: IMPLEMENT ME!");
2340 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2345 STATISTICS(jniinvokation());
2347 /* log_text("JNI-Call: CallNonvirtualDoubleMethod"); */
2349 va_start(vaargs,methodID);
2350 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
2357 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2359 STATISTICS(jniinvokation());
2361 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
2363 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
2367 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2369 STATISTICS(jniinvokation());
2371 log_text("JNI-Call: CallNonvirtualDoubleMethodA: IMPLEMENT ME!");
2378 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2382 STATISTICS(jniinvokation());
2384 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
2386 va_start(vaargs,methodID);
2387 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
2392 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2394 STATISTICS(jniinvokation());
2396 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
2398 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
2402 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
2404 STATISTICS(jniinvokation());
2406 log_text("JNI-Call: CallNonvirtualVoidMethodA: IMPLEMENT ME!");
2410 /* Accessing Fields of Objects ************************************************/
2412 /* GetFieldID ******************************************************************
2414 Returns the field ID for an instance (nonstatic) field of a
2415 class. The field is specified by its name and signature. The
2416 Get<type>Field and Set<type>Field families of accessor functions
2417 use field IDs to retrieve object fields.
2419 *******************************************************************************/
2421 jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2428 STATISTICS(jniinvokation());
2430 uname = utf_new_char((char *) name);
2431 udesc = utf_new_char((char *) sig);
2433 f = class_findfield(clazz, uname, udesc);
2436 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2442 /* Get<type>Field Routines *****************************************************
2444 This family of accessor routines returns the value of an instance
2445 (nonstatic) field of an object. The field to access is specified by
2446 a field ID obtained by calling GetFieldID().
2448 *******************************************************************************/
2450 jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2452 java_objectheader *o;
2454 STATISTICS(jniinvokation());
2456 o = GET_FIELD(obj, java_objectheader*, fieldID);
2458 return NewLocalRef(env, o);
2462 jboolean GetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID)
2466 STATISTICS(jniinvokation());
2468 i = GET_FIELD(obj, s4, fieldID);
2470 return (jboolean) i;
2474 jbyte GetByteField(JNIEnv *env, jobject obj, jfieldID fieldID)
2478 STATISTICS(jniinvokation());
2480 i = GET_FIELD(obj, s4, fieldID);
2486 jchar GetCharField(JNIEnv *env, jobject obj, jfieldID fieldID)
2490 STATISTICS(jniinvokation());
2492 i = GET_FIELD(obj, s4, fieldID);
2498 jshort GetShortField(JNIEnv *env, jobject obj, jfieldID fieldID)
2502 STATISTICS(jniinvokation());
2504 i = GET_FIELD(obj, s4, fieldID);
2510 jint GetIntField(JNIEnv *env, jobject obj, jfieldID fieldID)
2514 STATISTICS(jniinvokation());
2516 i = GET_FIELD(obj, s4, fieldID);
2522 jlong GetLongField(JNIEnv *env, jobject obj, jfieldID fieldID)
2526 STATISTICS(jniinvokation());
2528 l = GET_FIELD(obj, s8, fieldID);
2534 jfloat GetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID)
2538 STATISTICS(jniinvokation());
2540 f = GET_FIELD(obj, float, fieldID);
2546 jdouble GetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID)
2550 STATISTICS(jniinvokation());
2552 d = GET_FIELD(obj, double, fieldID);
2558 /* Set<type>Field Routines *****************************************************
2560 This family of accessor routines sets the value of an instance
2561 (nonstatic) field of an object. The field to access is specified by
2562 a field ID obtained by calling GetFieldID().
2564 *******************************************************************************/
2566 void SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value)
2568 STATISTICS(jniinvokation());
2570 SET_FIELD(obj, java_objectheader*, fieldID, value);
2574 void SetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID, jboolean value)
2576 STATISTICS(jniinvokation());
2578 SET_FIELD(obj, s4, fieldID, value);
2582 void SetByteField(JNIEnv *env, jobject obj, jfieldID fieldID, jbyte value)
2584 STATISTICS(jniinvokation());
2586 SET_FIELD(obj, s4, fieldID, value);
2590 void SetCharField(JNIEnv *env, jobject obj, jfieldID fieldID, jchar value)
2592 STATISTICS(jniinvokation());
2594 SET_FIELD(obj, s4, fieldID, value);
2598 void SetShortField(JNIEnv *env, jobject obj, jfieldID fieldID, jshort value)
2600 STATISTICS(jniinvokation());
2602 SET_FIELD(obj, s4, fieldID, value);
2606 void SetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint value)
2608 STATISTICS(jniinvokation());
2610 SET_FIELD(obj, s4, fieldID, value);
2614 void SetLongField(JNIEnv *env, jobject obj, jfieldID fieldID, jlong value)
2616 STATISTICS(jniinvokation());
2618 SET_FIELD(obj, s8, fieldID, value);
2622 void SetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID, jfloat value)
2624 STATISTICS(jniinvokation());
2626 SET_FIELD(obj, float, fieldID, value);
2630 void SetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID, jdouble value)
2632 STATISTICS(jniinvokation());
2634 SET_FIELD(obj, double, fieldID, value);
2638 /* Calling Static Methods *****************************************************/
2640 /* GetStaticMethodID ***********************************************************
2642 Returns the method ID for a static method of a class. The method is
2643 specified by its name and signature.
2645 GetStaticMethodID() causes an uninitialized class to be
2648 *******************************************************************************/
2650 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2658 STATISTICS(jniinvokation());
2660 c = (classinfo *) clazz;
2665 if (!(c->state & CLASS_INITIALIZED))
2666 if (!initialize_class(c))
2669 /* try to get the static method of the class */
2671 uname = utf_new_char((char *) name);
2672 udesc = utf_new_char((char *) sig);
2674 m = class_resolvemethod(c, uname, udesc);
2676 if (!m || !(m->flags & ACC_STATIC)) {
2677 *exceptionptr = exceptions_new_nosuchmethoderror(c, uname, udesc);
2686 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2688 java_objectheader *ret;
2691 STATISTICS(jniinvokation());
2693 va_start(vaargs, methodID);
2694 ret = callObjectMethod(0, methodID, vaargs);
2697 return NewLocalRef(env, ret);
2701 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2703 java_objectheader *ret;
2705 STATISTICS(jniinvokation());
2707 ret = callObjectMethod(0, methodID, args);
2709 return NewLocalRef(env, ret);
2713 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2715 STATISTICS(jniinvokation());
2717 log_text("JNI-Call: CallStaticObjectMethodA: IMPLEMENT ME!");
2719 return NewLocalRef(env, NULL);
2723 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2728 STATISTICS(jniinvokation());
2730 va_start(vaargs, methodID);
2731 ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
2738 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2740 STATISTICS(jniinvokation());
2742 return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
2746 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2748 STATISTICS(jniinvokation());
2750 log_text("JNI-Call: CallStaticBooleanMethodA: IMPLEMENT ME!");
2756 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2761 STATISTICS(jniinvokation());
2763 va_start(vaargs, methodID);
2764 ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
2771 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2773 STATISTICS(jniinvokation());
2775 return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
2779 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2781 STATISTICS(jniinvokation());
2783 log_text("JNI-Call: CallStaticByteMethodA: IMPLEMENT ME!");
2789 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2794 STATISTICS(jniinvokation());
2796 va_start(vaargs, methodID);
2797 ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
2804 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2806 STATISTICS(jniinvokation());
2808 return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
2812 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2814 STATISTICS(jniinvokation());
2816 log_text("JNI-Call: CallStaticCharMethodA: IMPLEMENT ME!");
2822 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2827 STATISTICS(jniinvokation());
2829 va_start(vaargs, methodID);
2830 ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
2837 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2839 STATISTICS(jniinvokation());
2841 return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
2845 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2847 STATISTICS(jniinvokation());
2849 log_text("JNI-Call: CallStaticShortMethodA: IMPLEMENT ME!");
2855 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2860 STATISTICS(jniinvokation());
2862 va_start(vaargs, methodID);
2863 ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
2870 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2872 STATISTICS(jniinvokation());
2874 return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
2878 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2880 STATISTICS(jniinvokation());
2882 log_text("JNI-Call: CallStaticIntMethodA: IMPLEMENT ME!");
2888 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2893 STATISTICS(jniinvokation());
2895 va_start(vaargs, methodID);
2896 ret = _Jv_jni_CallLongMethod(0, methodID, vaargs);
2903 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
2906 STATISTICS(jniinvokation());
2908 return _Jv_jni_CallLongMethod(0, methodID, args);
2912 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2914 STATISTICS(jniinvokation());
2916 log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!");
2923 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2928 STATISTICS(jniinvokation());
2930 va_start(vaargs, methodID);
2931 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
2938 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2940 STATISTICS(jniinvokation());
2942 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
2947 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2949 STATISTICS(jniinvokation());
2951 log_text("JNI-Call: CallStaticFloatMethodA: IMPLEMENT ME!");
2957 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2962 STATISTICS(jniinvokation());
2964 va_start(vaargs,methodID);
2965 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
2972 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2974 STATISTICS(jniinvokation());
2976 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
2980 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2982 STATISTICS(jniinvokation());
2984 log_text("JNI-Call: CallStaticDoubleMethodA: IMPLEMENT ME!");
2990 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2994 STATISTICS(jniinvokation());
2996 va_start(vaargs, methodID);
2997 (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
3002 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
3004 STATISTICS(jniinvokation());
3006 (void) callIntegerMethod(0, methodID, TYPE_VOID, args);
3010 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
3012 STATISTICS(jniinvokation());
3014 log_text("JNI-Call: CallStaticVoidMethodA: IMPLEMENT ME!");
3018 /* Accessing Static Fields ****************************************************/
3020 /* GetStaticFieldID ************************************************************
3022 Returns the field ID for a static field of a class. The field is
3023 specified by its name and signature. The GetStatic<type>Field and
3024 SetStatic<type>Field families of accessor functions use field IDs
3025 to retrieve static fields.
3027 *******************************************************************************/
3029 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
3033 STATISTICS(jniinvokation());
3035 f = class_findfield(clazz,
3036 utf_new_char((char *) name),
3037 utf_new_char((char *) sig));
3040 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
3046 /* GetStatic<type>Field ********************************************************
3048 This family of accessor routines returns the value of a static
3051 *******************************************************************************/
3053 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3055 STATISTICS(jniinvokation());
3057 if (!(clazz->state & CLASS_INITIALIZED))
3058 if (!initialize_class(clazz))
3061 return NewLocalRef(env, fieldID->value.a);
3065 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3067 STATISTICS(jniinvokation());
3069 if (!(clazz->state & CLASS_INITIALIZED))
3070 if (!initialize_class(clazz))
3073 return fieldID->value.i;
3077 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3079 STATISTICS(jniinvokation());
3081 if (!(clazz->state & CLASS_INITIALIZED))
3082 if (!initialize_class(clazz))
3085 return fieldID->value.i;
3089 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3091 STATISTICS(jniinvokation());
3093 if (!(clazz->state & CLASS_INITIALIZED))
3094 if (!initialize_class(clazz))
3097 return fieldID->value.i;
3101 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3103 STATISTICS(jniinvokation());
3105 if (!(clazz->state & CLASS_INITIALIZED))
3106 if (!initialize_class(clazz))
3109 return fieldID->value.i;
3113 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3115 STATISTICS(jniinvokation());
3117 if (!(clazz->state & CLASS_INITIALIZED))
3118 if (!initialize_class(clazz))
3121 return fieldID->value.i;
3125 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3127 STATISTICS(jniinvokation());
3129 if (!(clazz->state & CLASS_INITIALIZED))
3130 if (!initialize_class(clazz))
3133 return fieldID->value.l;
3137 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3139 STATISTICS(jniinvokation());
3141 if (!(clazz->state & CLASS_INITIALIZED))
3142 if (!initialize_class(clazz))
3145 return fieldID->value.f;
3149 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3151 STATISTICS(jniinvokation());
3153 if (!(clazz->state & CLASS_INITIALIZED))
3154 if (!initialize_class(clazz))
3157 return fieldID->value.d;
3161 /* SetStatic<type>Field *******************************************************
3163 This family of accessor routines sets the value of a static field
3166 *******************************************************************************/
3168 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
3170 STATISTICS(jniinvokation());
3172 if (!(clazz->state & CLASS_INITIALIZED))
3173 if (!initialize_class(clazz))
3176 fieldID->value.a = value;
3180 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
3182 STATISTICS(jniinvokation());
3184 if (!(clazz->state & CLASS_INITIALIZED))
3185 if (!initialize_class(clazz))
3188 fieldID->value.i = value;
3192 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
3194 STATISTICS(jniinvokation());
3196 if (!(clazz->state & CLASS_INITIALIZED))
3197 if (!initialize_class(clazz))
3200 fieldID->value.i = value;
3204 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
3206 STATISTICS(jniinvokation());
3208 if (!(clazz->state & CLASS_INITIALIZED))
3209 if (!initialize_class(clazz))
3212 fieldID->value.i = value;
3216 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
3218 STATISTICS(jniinvokation());
3220 if (!(clazz->state & CLASS_INITIALIZED))
3221 if (!initialize_class(clazz))
3224 fieldID->value.i = value;
3228 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
3230 STATISTICS(jniinvokation());
3232 if (!(clazz->state & CLASS_INITIALIZED))
3233 if (!initialize_class(clazz))
3236 fieldID->value.i = value;
3240 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
3242 STATISTICS(jniinvokation());
3244 if (!(clazz->state & CLASS_INITIALIZED))
3245 if (!initialize_class(clazz))
3248 fieldID->value.l = value;
3252 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
3254 STATISTICS(jniinvokation());
3256 if (!(clazz->state & CLASS_INITIALIZED))
3257 if (!initialize_class(clazz))
3260 fieldID->value.f = value;
3264 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
3266 STATISTICS(jniinvokation());
3268 if (!(clazz->state & CLASS_INITIALIZED))
3269 if (!initialize_class(clazz))
3272 fieldID->value.d = value;
3276 /* String Operations **********************************************************/
3278 /* NewString *******************************************************************
3280 Create new java.lang.String object from an array of Unicode
3283 *******************************************************************************/
3285 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
3287 java_lang_String *s;
3291 STATISTICS(jniinvokation());
3293 s = (java_lang_String *) builtin_new(class_java_lang_String);
3294 a = builtin_newarray_char(len);
3296 /* javastring or characterarray could not be created */
3301 for (i = 0; i < len; i++)
3302 a->data[i] = buf[i];
3308 return (jstring) NewLocalRef(env, (jobject) s);
3312 static jchar emptyStringJ[]={0,0};
3314 /* GetStringLength *************************************************************
3316 Returns the length (the count of Unicode characters) of a Java
3319 *******************************************************************************/
3321 jsize GetStringLength(JNIEnv *env, jstring str)
3323 return ((java_lang_String *) str)->count;
3327 /******************** convertes javastring to u2-array ****************************/
3329 u2 *javastring_tou2(jstring so)
3331 java_lang_String *s;
3336 STATISTICS(jniinvokation());
3338 s = (java_lang_String *) so;
3348 /* allocate memory */
3350 stringbuffer = MNEW(u2, s->count + 1);
3354 for (i = 0; i < s->count; i++)
3355 stringbuffer[i] = a->data[s->offset + i];
3357 /* terminate string */
3359 stringbuffer[i] = '\0';
3361 return stringbuffer;
3365 /* GetStringChars **************************************************************
3367 Returns a pointer to the array of Unicode characters of the
3368 string. This pointer is valid until ReleaseStringchars() is called.
3370 *******************************************************************************/
3372 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
3376 STATISTICS(jniinvokation());
3378 jc = javastring_tou2(str);
3390 return emptyStringJ;
3394 /* ReleaseStringChars **********************************************************
3396 Informs the VM that the native code no longer needs access to
3397 chars. The chars argument is a pointer obtained from string using
3400 *******************************************************************************/
3402 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
3404 STATISTICS(jniinvokation());
3406 if (chars == emptyStringJ)
3409 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
3413 /* NewStringUTF ****************************************************************
3415 Constructs a new java.lang.String object from an array of UTF-8 characters.
3417 *******************************************************************************/
3419 jstring NewStringUTF(JNIEnv *env, const char *bytes)
3421 java_lang_String *s;
3423 STATISTICS(jniinvokation());
3425 s = javastring_new(utf_new_char(bytes));
3427 return (jstring) NewLocalRef(env, (jobject) s);
3431 /****************** returns the utf8 length in bytes of a string *******************/
3433 jsize GetStringUTFLength (JNIEnv *env, jstring string)
3435 java_lang_String *s = (java_lang_String*) string;
3437 STATISTICS(jniinvokation());
3439 return (jsize) u2_utflength(s->value->data, s->count);
3443 /* GetStringUTFChars ***********************************************************
3445 Returns a pointer to an array of UTF-8 characters of the
3446 string. This array is valid until it is released by
3447 ReleaseStringUTFChars().
3449 *******************************************************************************/
3451 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
3455 STATISTICS(jniinvokation());
3463 u = javastring_toutf((java_lang_String *) string, false);
3472 /* ReleaseStringUTFChars *******************************************************
3474 Informs the VM that the native code no longer needs access to
3475 utf. The utf argument is a pointer derived from string using
3476 GetStringUTFChars().
3478 *******************************************************************************/
3480 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
3482 STATISTICS(jniinvokation());
3484 /* XXX we don't release utf chars right now, perhaps that should be done
3485 later. Since there is always one reference the garbage collector will
3490 /* Array Operations ***********************************************************/
3492 /* GetArrayLength **************************************************************
3494 Returns the number of elements in the array.
3496 *******************************************************************************/
3498 jsize GetArrayLength(JNIEnv *env, jarray array)
3500 STATISTICS(jniinvokation());
3506 /* NewObjectArray **************************************************************
3508 Constructs a new array holding objects in class elementClass. All
3509 elements are initially set to initialElement.
3511 *******************************************************************************/
3513 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
3515 java_objectarray *oa;
3518 STATISTICS(jniinvokation());
3521 exceptions_throw_negativearraysizeexception();
3525 oa = builtin_anewarray(length, elementClass);
3530 /* set all elements to initialElement */
3532 for (i = 0; i < length; i++)
3533 oa->data[i] = initialElement;
3535 return (jobjectArray) NewLocalRef(env, (jobject) oa);
3539 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
3543 STATISTICS(jniinvokation());
3545 if (index >= array->header.size) {
3546 exceptions_throw_arrayindexoutofboundsexception();
3550 o = array->data[index];
3552 return NewLocalRef(env, o);
3556 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3558 java_objectarray *oa;
3559 java_objectheader *o;
3561 STATISTICS(jniinvokation());
3563 oa = (java_objectarray *) array;
3564 o = (java_objectheader *) val;
3566 if (index >= array->header.size) {
3567 exceptions_throw_arrayindexoutofboundsexception();
3571 /* check if the class of value is a subclass of the element class
3574 if (!builtin_canstore(oa, o)) {
3575 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3580 array->data[index] = val;
3584 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3586 java_booleanarray *ba;
3588 STATISTICS(jniinvokation());
3591 exceptions_throw_negativearraysizeexception();
3595 ba = builtin_newarray_boolean(len);
3597 return (jbooleanArray) NewLocalRef(env, (jobject) ba);
3601 jbyteArray NewByteArray(JNIEnv *env, jsize len)
3605 STATISTICS(jniinvokation());
3608 exceptions_throw_negativearraysizeexception();
3612 ba = builtin_newarray_byte(len);
3614 return (jbyteArray) NewLocalRef(env, (jobject) ba);
3618 jcharArray NewCharArray(JNIEnv *env, jsize len)
3622 STATISTICS(jniinvokation());
3625 exceptions_throw_negativearraysizeexception();
3629 ca = builtin_newarray_char(len);
3631 return (jcharArray) NewLocalRef(env, (jobject) ca);
3635 jshortArray NewShortArray(JNIEnv *env, jsize len)
3637 java_shortarray *sa;
3639 STATISTICS(jniinvokation());
3642 exceptions_throw_negativearraysizeexception();
3646 sa = builtin_newarray_short(len);
3648 return (jshortArray) NewLocalRef(env, (jobject) sa);
3652 jintArray NewIntArray(JNIEnv *env, jsize len)
3656 STATISTICS(jniinvokation());
3659 exceptions_throw_negativearraysizeexception();
3663 ia = builtin_newarray_int(len);
3665 return (jintArray) NewLocalRef(env, (jobject) ia);
3669 jlongArray NewLongArray(JNIEnv *env, jsize len)
3673 STATISTICS(jniinvokation());
3676 exceptions_throw_negativearraysizeexception();
3680 la = builtin_newarray_long(len);
3682 return (jlongArray) NewLocalRef(env, (jobject) la);
3686 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3688 java_floatarray *fa;
3690 STATISTICS(jniinvokation());
3693 exceptions_throw_negativearraysizeexception();
3697 fa = builtin_newarray_float(len);
3699 return (jfloatArray) NewLocalRef(env, (jobject) fa);
3703 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3705 java_doublearray *da;
3707 STATISTICS(jniinvokation());
3710 exceptions_throw_negativearraysizeexception();
3714 da = builtin_newarray_double(len);
3716 return (jdoubleArray) NewLocalRef(env, (jobject) da);
3720 /* Get<PrimitiveType>ArrayElements *********************************************
3722 A family of functions that returns the body of the primitive array.
3724 *******************************************************************************/
3726 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3729 STATISTICS(jniinvokation());
3732 *isCopy = JNI_FALSE;
3738 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3740 STATISTICS(jniinvokation());
3743 *isCopy = JNI_FALSE;
3749 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3751 STATISTICS(jniinvokation());
3754 *isCopy = JNI_FALSE;
3760 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3762 STATISTICS(jniinvokation());
3765 *isCopy = JNI_FALSE;
3771 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3773 STATISTICS(jniinvokation());
3776 *isCopy = JNI_FALSE;
3782 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3784 STATISTICS(jniinvokation());
3787 *isCopy = JNI_FALSE;
3793 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3795 STATISTICS(jniinvokation());
3798 *isCopy = JNI_FALSE;
3804 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3807 STATISTICS(jniinvokation());
3810 *isCopy = JNI_FALSE;
3816 /* Release<PrimitiveType>ArrayElements *****************************************
3818 A family of functions that informs the VM that the native code no
3819 longer needs access to elems. The elems argument is a pointer
3820 derived from array using the corresponding
3821 Get<PrimitiveType>ArrayElements() function. If necessary, this
3822 function copies back all changes made to elems to the original
3825 *******************************************************************************/
3827 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3828 jboolean *elems, jint mode)
3830 STATISTICS(jniinvokation());
3832 if (elems != array->data) {
3835 MCOPY(array->data, elems, jboolean, array->header.size);
3838 MCOPY(array->data, elems, jboolean, array->header.size);
3839 /* XXX TWISTI how should it be freed? */
3842 /* XXX TWISTI how should it be freed? */
3849 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
3852 STATISTICS(jniinvokation());
3854 if (elems != array->data) {
3857 MCOPY(array->data, elems, jboolean, array->header.size);
3860 MCOPY(array->data, elems, jboolean, array->header.size);
3861 /* XXX TWISTI how should it be freed? */
3864 /* XXX TWISTI how should it be freed? */
3871 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
3874 STATISTICS(jniinvokation());
3876 if (elems != array->data) {
3879 MCOPY(array->data, elems, jboolean, array->header.size);
3882 MCOPY(array->data, elems, jboolean, array->header.size);
3883 /* XXX TWISTI how should it be freed? */
3886 /* XXX TWISTI how should it be freed? */
3893 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
3896 STATISTICS(jniinvokation());
3898 if (elems != array->data) {
3901 MCOPY(array->data, elems, jboolean, array->header.size);
3904 MCOPY(array->data, elems, jboolean, array->header.size);
3905 /* XXX TWISTI how should it be freed? */
3908 /* XXX TWISTI how should it be freed? */
3915 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
3918 STATISTICS(jniinvokation());
3920 if (elems != array->data) {
3923 MCOPY(array->data, elems, jboolean, array->header.size);
3926 MCOPY(array->data, elems, jboolean, array->header.size);
3927 /* XXX TWISTI how should it be freed? */
3930 /* XXX TWISTI how should it be freed? */
3937 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
3940 STATISTICS(jniinvokation());
3942 if (elems != array->data) {
3945 MCOPY(array->data, elems, jboolean, array->header.size);
3948 MCOPY(array->data, elems, jboolean, array->header.size);
3949 /* XXX TWISTI how should it be freed? */
3952 /* XXX TWISTI how should it be freed? */
3959 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
3962 STATISTICS(jniinvokation());
3964 if (elems != array->data) {
3967 MCOPY(array->data, elems, jboolean, array->header.size);
3970 MCOPY(array->data, elems, jboolean, array->header.size);
3971 /* XXX TWISTI how should it be freed? */
3974 /* XXX TWISTI how should it be freed? */
3981 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3982 jdouble *elems, jint mode)
3984 STATISTICS(jniinvokation());
3986 if (elems != array->data) {
3989 MCOPY(array->data, elems, jboolean, array->header.size);
3992 MCOPY(array->data, elems, jboolean, array->header.size);
3993 /* XXX TWISTI how should it be freed? */
3996 /* XXX TWISTI how should it be freed? */
4003 /* Get<PrimitiveType>ArrayRegion **********************************************
4005 A family of functions that copies a region of a primitive array
4008 *******************************************************************************/
4010 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
4011 jsize len, jboolean *buf)
4013 STATISTICS(jniinvokation());
4015 if (start < 0 || len < 0 || start + len > array->header.size)
4016 exceptions_throw_arrayindexoutofboundsexception();
4018 MCOPY(buf, &array->data[start], jboolean, len);
4022 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
4025 STATISTICS(jniinvokation());
4027 if (start < 0 || len < 0 || start + len > array->header.size)
4028 exceptions_throw_arrayindexoutofboundsexception();
4030 MCOPY(buf, &array->data[start], jbyte, len);
4034 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
4037 STATISTICS(jniinvokation());
4039 if (start < 0 || len < 0 || start + len > array->header.size)
4040 exceptions_throw_arrayindexoutofboundsexception();
4042 MCOPY(buf, &array->data[start], jchar, len);
4046 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
4047 jsize len, jshort *buf)
4049 STATISTICS(jniinvokation());
4051 if (start < 0 || len < 0 || start + len > array->header.size)
4052 exceptions_throw_arrayindexoutofboundsexception();
4054 MCOPY(buf, &array->data[start], jshort, len);
4058 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
4061 STATISTICS(jniinvokation());
4063 if (start < 0 || len < 0 || start + len > array->header.size)
4064 exceptions_throw_arrayindexoutofboundsexception();
4066 MCOPY(buf, &array->data[start], jint, len);
4070 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
4073 STATISTICS(jniinvokation());
4075 if (start < 0 || len < 0 || start + len > array->header.size)
4076 exceptions_throw_arrayindexoutofboundsexception();
4078 MCOPY(buf, &array->data[start], jlong, len);
4082 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
4083 jsize len, jfloat *buf)
4085 STATISTICS(jniinvokation());
4087 if (start < 0 || len < 0 || start + len > array->header.size)
4088 exceptions_throw_arrayindexoutofboundsexception();
4090 MCOPY(buf, &array->data[start], jfloat, len);
4094 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
4095 jsize len, jdouble *buf)
4097 STATISTICS(jniinvokation());
4099 if (start < 0 || len < 0 || start+len>array->header.size)
4100 exceptions_throw_arrayindexoutofboundsexception();
4102 MCOPY(buf, &array->data[start], jdouble, len);
4106 /* Set<PrimitiveType>ArrayRegion **********************************************
4108 A family of functions that copies back a region of a primitive
4109 array from a buffer.
4111 *******************************************************************************/
4113 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
4114 jsize len, jboolean *buf)
4116 STATISTICS(jniinvokation());
4118 if (start < 0 || len < 0 || start + len > array->header.size)
4119 exceptions_throw_arrayindexoutofboundsexception();
4121 MCOPY(&array->data[start], buf, jboolean, len);
4125 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
4128 STATISTICS(jniinvokation());
4130 if (start < 0 || len < 0 || start + len > array->header.size)
4131 exceptions_throw_arrayindexoutofboundsexception();
4133 MCOPY(&array->data[start], buf, jbyte, len);
4137 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
4140 STATISTICS(jniinvokation());
4142 if (start < 0 || len < 0 || start + len > array->header.size)
4143 exceptions_throw_arrayindexoutofboundsexception();
4145 MCOPY(&array->data[start], buf, jchar, len);
4149 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
4150 jsize len, jshort *buf)
4152 STATISTICS(jniinvokation());
4154 if (start < 0 || len < 0 || start + len > array->header.size)
4155 exceptions_throw_arrayindexoutofboundsexception();
4157 MCOPY(&array->data[start], buf, jshort, len);
4161 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
4164 STATISTICS(jniinvokation());
4166 if (start < 0 || len < 0 || start + len > array->header.size)
4167 exceptions_throw_arrayindexoutofboundsexception();
4169 MCOPY(&array->data[start], buf, jint, len);
4173 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
4176 STATISTICS(jniinvokation());
4178 if (start < 0 || len < 0 || start + len > array->header.size)
4179 exceptions_throw_arrayindexoutofboundsexception();
4181 MCOPY(&array->data[start], buf, jlong, len);
4185 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
4186 jsize len, jfloat *buf)
4188 STATISTICS(jniinvokation());
4190 if (start < 0 || len < 0 || start + len > array->header.size)
4191 exceptions_throw_arrayindexoutofboundsexception();
4193 MCOPY(&array->data[start], buf, jfloat, len);
4197 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
4198 jsize len, jdouble *buf)
4200 STATISTICS(jniinvokation());
4202 if (start < 0 || len < 0 || start + len > array->header.size)
4203 exceptions_throw_arrayindexoutofboundsexception();
4205 MCOPY(&array->data[start], buf, jdouble, len);
4209 /* Registering Native Methods *************************************************/
4211 /* RegisterNatives *************************************************************
4213 Registers native methods with the class specified by the clazz
4214 argument. The methods parameter specifies an array of
4215 JNINativeMethod structures that contain the names, signatures, and
4216 function pointers of the native methods. The nMethods parameter
4217 specifies the number of native methods in the array.
4219 *******************************************************************************/
4221 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
4224 STATISTICS(jniinvokation());
4226 log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
4232 /* UnregisterNatives ***********************************************************
4234 Unregisters native methods of a class. The class goes back to the
4235 state before it was linked or registered with its native method
4238 This function should not be used in normal native code. Instead, it
4239 provides special programs a way to reload and relink native
4242 *******************************************************************************/
4244 jint UnregisterNatives(JNIEnv *env, jclass clazz)
4246 STATISTICS(jniinvokation());
4248 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
4250 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
4256 /* Monitor Operations *********************************************************/
4258 /* MonitorEnter ****************************************************************
4260 Enters the monitor associated with the underlying Java object
4263 *******************************************************************************/
4265 jint MonitorEnter(JNIEnv *env, jobject obj)
4267 STATISTICS(jniinvokation());
4270 exceptions_throw_nullpointerexception();
4274 #if defined(USE_THREADS)
4275 builtin_monitorenter(obj);
4282 /* MonitorExit *****************************************************************
4284 The current thread must be the owner of the monitor associated with
4285 the underlying Java object referred to by obj. The thread
4286 decrements the counter indicating the number of times it has
4287 entered this monitor. If the value of the counter becomes zero, the
4288 current thread releases the monitor.
4290 *******************************************************************************/
4292 jint MonitorExit(JNIEnv *env, jobject obj)
4294 STATISTICS(jniinvokation());
4297 exceptions_throw_nullpointerexception();
4301 #if defined(USE_THREADS)
4302 builtin_monitorexit(obj);
4309 /* JavaVM Interface ***********************************************************/
4311 /* GetJavaVM *******************************************************************
4313 Returns the Java VM interface (used in the Invocation API)
4314 associated with the current thread. The result is placed at the
4315 location pointed to by the second argument, vm.
4317 *******************************************************************************/
4319 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
4321 STATISTICS(jniinvokation());
4329 void GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
4331 STATISTICS(jniinvokation());
4333 log_text("JNI-Call: GetStringRegion: IMPLEMENT ME!");
4337 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
4339 STATISTICS(jniinvokation());
4341 log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
4345 /* GetPrimitiveArrayCritical ***************************************************
4347 Obtain a direct pointer to array elements.
4349 *******************************************************************************/
4351 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
4356 ba = (java_bytearray *) array;
4358 /* do the same as Kaffe does */
4360 bp = GetByteArrayElements(env, ba, isCopy);
4366 /* ReleasePrimitiveArrayCritical ***********************************************
4368 No specific documentation.
4370 *******************************************************************************/
4372 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
4375 STATISTICS(jniinvokation());
4377 /* do the same as Kaffe does */
4379 ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
4383 /* GetStringCritical ***********************************************************
4385 The semantics of these two functions are similar to the existing
4386 Get/ReleaseStringChars functions.
4388 *******************************************************************************/
4390 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
4392 STATISTICS(jniinvokation());
4394 return GetStringChars(env, string, isCopy);
4398 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
4400 STATISTICS(jniinvokation());
4402 ReleaseStringChars(env, string, cstring);
4406 jweak NewWeakGlobalRef(JNIEnv* env, jobject obj)
4408 STATISTICS(jniinvokation());
4410 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
4416 void DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
4418 STATISTICS(jniinvokation());
4420 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
4424 /* NewGlobalRef ****************************************************************
4426 Creates a new global reference to the object referred to by the obj
4429 *******************************************************************************/
4431 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4433 java_objectheader *o;
4434 java_lang_Integer *refcount;
4435 java_objectheader *newval;
4437 STATISTICS(jniinvokation());
4439 #if defined(USE_THREADS)
4440 builtin_monitorenter(*global_ref_table);
4443 ASM_CALLJAVAFUNCTION_ADR(o, getmid, *global_ref_table, lobj, NULL, NULL);
4445 refcount = (java_lang_Integer *) o;
4447 if (refcount == NULL) {
4448 newval = native_new_and_init_int(class_java_lang_Integer, 1);
4450 if (newval == NULL) {
4451 #if defined(USE_THREADS)
4452 builtin_monitorexit(*global_ref_table);
4457 ASM_CALLJAVAFUNCTION(putmid, *global_ref_table, lobj, newval, NULL);
4460 /* we can access the object itself, as we are in a
4461 synchronized section */
4466 #if defined(USE_THREADS)
4467 builtin_monitorexit(*global_ref_table);
4474 /* DeleteGlobalRef *************************************************************
4476 Deletes the global reference pointed to by globalRef.
4478 *******************************************************************************/
4480 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
4482 java_objectheader *o;
4483 java_lang_Integer *refcount;
4486 STATISTICS(jniinvokation());
4488 #if defined(USE_THREADS)
4489 builtin_monitorenter(*global_ref_table);
4492 ASM_CALLJAVAFUNCTION_ADR(o, getmid, *global_ref_table, globalRef, NULL,
4495 refcount = (java_lang_Integer *) o;
4497 if (refcount == NULL) {
4498 log_text("JNI-DeleteGlobalRef: unable to find global reference");
4502 /* we can access the object itself, as we are in a synchronized
4505 val = refcount->value - 1;
4508 ASM_CALLJAVAFUNCTION(removemid, *global_ref_table, refcount, NULL,
4512 /* we do not create a new object, but set the new value into
4515 refcount->value = val;
4518 #if defined(USE_THREADS)
4519 builtin_monitorexit(*global_ref_table);
4524 /* ExceptionCheck **************************************************************
4526 Returns JNI_TRUE when there is a pending exception; otherwise,
4529 *******************************************************************************/
4531 jboolean ExceptionCheck(JNIEnv *env)
4533 STATISTICS(jniinvokation());
4535 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
4539 /* New JNI 1.4 functions ******************************************************/
4541 /* NewDirectByteBuffer *********************************************************
4543 Allocates and returns a direct java.nio.ByteBuffer referring to the
4544 block of memory starting at the memory address address and
4545 extending capacity bytes.
4547 *******************************************************************************/
4549 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
4551 java_objectheader *nbuf;
4552 #if SIZEOF_VOID_P == 8
4553 gnu_classpath_Pointer64 *paddress;
4555 gnu_classpath_Pointer32 *paddress;
4558 STATISTICS(jniinvokation());
4560 /* alocate a gnu.classpath.Pointer{32,64} object */
4562 #if SIZEOF_VOID_P == 8
4563 if (!(paddress = (gnu_classpath_Pointer64 *)
4564 builtin_new(class_gnu_classpath_Pointer64)))
4566 if (!(paddress = (gnu_classpath_Pointer32 *)
4567 builtin_new(class_gnu_classpath_Pointer32)))
4571 /* fill gnu.classpath.Pointer{32,64} with address */
4573 paddress->data = (ptrint) address;
4575 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
4577 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
4578 dbbirw_init, NULL, paddress,
4579 (jint) capacity, (jint) capacity, (jint) 0);
4581 /* add local reference and return the value */
4583 return NewLocalRef(env, nbuf);
4587 /* GetDirectBufferAddress ******************************************************
4589 Fetches and returns the starting address of the memory region
4590 referenced by the given direct java.nio.Buffer.
4592 *******************************************************************************/
4594 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
4596 java_nio_DirectByteBufferImpl *nbuf;
4597 #if SIZEOF_VOID_P == 8
4598 gnu_classpath_Pointer64 *address;
4600 gnu_classpath_Pointer32 *address;
4603 STATISTICS(jniinvokation());
4605 if (!builtin_instanceof(buf, class_java_nio_Buffer))
4608 nbuf = (java_nio_DirectByteBufferImpl *) buf;
4610 #if SIZEOF_VOID_P == 8
4611 address = (gnu_classpath_Pointer64 *) nbuf->address;
4613 address = (gnu_classpath_Pointer32 *) nbuf->address;
4616 return (void *) address->data;
4620 /* GetDirectBufferCapacity *****************************************************
4622 Fetches and returns the capacity in bytes of the memory region
4623 referenced by the given direct java.nio.Buffer.
4625 *******************************************************************************/
4627 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
4629 java_nio_Buffer *nbuf;
4631 STATISTICS(jniinvokation());
4633 if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
4636 nbuf = (java_nio_Buffer *) buf;
4638 return (jlong) nbuf->cap;
4642 jint DestroyJavaVM(JavaVM *vm)
4644 STATISTICS(jniinvokation());
4646 log_text("JNI-Call: DestroyJavaVM: IMPLEMENT ME!");
4652 /* AttachCurrentThread *********************************************************
4654 Attaches the current thread to a Java VM. Returns a JNI interface
4655 pointer in the JNIEnv argument.
4657 Trying to attach a thread that is already attached is a no-op.
4659 A native thread cannot be attached simultaneously to two Java VMs.
4661 When a thread is attached to the VM, the context class loader is
4662 the bootstrap loader.
4664 *******************************************************************************/
4666 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
4668 STATISTICS(jniinvokation());
4670 log_text("JNI-Call: AttachCurrentThread: IMPLEMENT ME!");
4672 #if !defined(HAVE___THREAD)
4673 /* cacao_thread_attach();*/
4675 #error "No idea how to implement that. Perhaps Stefan knows"
4684 jint DetachCurrentThread(JavaVM *vm)
4686 STATISTICS(jniinvokation());
4688 log_text("JNI-Call: DetachCurrentThread: IMPLEMENT ME!");
4694 /* GetEnv **********************************************************************
4696 If the current thread is not attached to the VM, sets *env to NULL,
4697 and returns JNI_EDETACHED. If the specified version is not
4698 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
4699 sets *env to the appropriate interface, and returns JNI_OK.
4701 *******************************************************************************/
4703 jint GetEnv(JavaVM *vm, void **env, jint version)
4705 STATISTICS(jniinvokation());
4707 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4708 if (thread_getself() == NULL) {
4711 return JNI_EDETACHED;
4715 if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
4716 (version == JNI_VERSION_1_4)) {
4722 #if defined(ENABLE_JVMTI)
4723 if (version == JVMTI_VERSION_1_0) {
4724 *env = (void *) new_jvmtienv();
4733 return JNI_EVERSION;
4738 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4740 STATISTICS(jniinvokation());
4742 log_text("JNI-Call: AttachCurrentThreadAsDaemon: IMPLEMENT ME!");
4748 /* JNI invocation table *******************************************************/
4750 const struct JNIInvokeInterface JNI_JavaVMTable = {
4756 AttachCurrentThread,
4757 DetachCurrentThread,
4759 AttachCurrentThreadAsDaemon
4763 /* JNI function table *********************************************************/
4765 struct JNINativeInterface JNI_JNIEnvTable = {
4774 &FromReflectedMethod,
4775 &FromReflectedField,
4795 &EnsureLocalCapacity,
4811 &CallBooleanMethodV,
4812 &CallBooleanMethodA,
4838 &CallNonvirtualObjectMethod,
4839 &CallNonvirtualObjectMethodV,
4840 &CallNonvirtualObjectMethodA,
4841 &CallNonvirtualBooleanMethod,
4842 &CallNonvirtualBooleanMethodV,
4843 &CallNonvirtualBooleanMethodA,
4844 &CallNonvirtualByteMethod,
4845 &CallNonvirtualByteMethodV,
4846 &CallNonvirtualByteMethodA,
4847 &CallNonvirtualCharMethod,
4848 &CallNonvirtualCharMethodV,
4849 &CallNonvirtualCharMethodA,
4850 &CallNonvirtualShortMethod,
4851 &CallNonvirtualShortMethodV,
4852 &CallNonvirtualShortMethodA,
4853 &CallNonvirtualIntMethod,
4854 &CallNonvirtualIntMethodV,
4855 &CallNonvirtualIntMethodA,
4856 &CallNonvirtualLongMethod,
4857 &CallNonvirtualLongMethodV,
4858 &CallNonvirtualLongMethodA,
4859 &CallNonvirtualFloatMethod,
4860 &CallNonvirtualFloatMethodV,
4861 &CallNonvirtualFloatMethodA,
4862 &CallNonvirtualDoubleMethod,
4863 &CallNonvirtualDoubleMethodV,
4864 &CallNonvirtualDoubleMethodA,
4865 &CallNonvirtualVoidMethod,
4866 &CallNonvirtualVoidMethodV,
4867 &CallNonvirtualVoidMethodA,
4892 &CallStaticObjectMethod,
4893 &CallStaticObjectMethodV,
4894 &CallStaticObjectMethodA,
4895 &CallStaticBooleanMethod,
4896 &CallStaticBooleanMethodV,
4897 &CallStaticBooleanMethodA,
4898 &CallStaticByteMethod,
4899 &CallStaticByteMethodV,
4900 &CallStaticByteMethodA,
4901 &CallStaticCharMethod,
4902 &CallStaticCharMethodV,
4903 &CallStaticCharMethodA,
4904 &CallStaticShortMethod,
4905 &CallStaticShortMethodV,
4906 &CallStaticShortMethodA,
4907 &CallStaticIntMethod,
4908 &CallStaticIntMethodV,
4909 &CallStaticIntMethodA,
4910 &CallStaticLongMethod,
4911 &CallStaticLongMethodV,
4912 &CallStaticLongMethodA,
4913 &CallStaticFloatMethod,
4914 &CallStaticFloatMethodV,
4915 &CallStaticFloatMethodA,
4916 &CallStaticDoubleMethod,
4917 &CallStaticDoubleMethodV,
4918 &CallStaticDoubleMethodA,
4919 &CallStaticVoidMethod,
4920 &CallStaticVoidMethodV,
4921 &CallStaticVoidMethodA,
4925 &GetStaticObjectField,
4926 &GetStaticBooleanField,
4927 &GetStaticByteField,
4928 &GetStaticCharField,
4929 &GetStaticShortField,
4931 &GetStaticLongField,
4932 &GetStaticFloatField,
4933 &GetStaticDoubleField,
4934 &SetStaticObjectField,
4935 &SetStaticBooleanField,
4936 &SetStaticByteField,
4937 &SetStaticCharField,
4938 &SetStaticShortField,
4940 &SetStaticLongField,
4941 &SetStaticFloatField,
4942 &SetStaticDoubleField,
4947 &ReleaseStringChars,
4950 &GetStringUTFLength,
4952 &ReleaseStringUTFChars,
4957 &GetObjectArrayElement,
4958 &SetObjectArrayElement,
4969 &GetBooleanArrayElements,
4970 &GetByteArrayElements,
4971 &GetCharArrayElements,
4972 &GetShortArrayElements,
4973 &GetIntArrayElements,
4974 &GetLongArrayElements,
4975 &GetFloatArrayElements,
4976 &GetDoubleArrayElements,
4978 &ReleaseBooleanArrayElements,
4979 &ReleaseByteArrayElements,
4980 &ReleaseCharArrayElements,
4981 &ReleaseShortArrayElements,
4982 &ReleaseIntArrayElements,
4983 &ReleaseLongArrayElements,
4984 &ReleaseFloatArrayElements,
4985 &ReleaseDoubleArrayElements,
4987 &GetBooleanArrayRegion,
4988 &GetByteArrayRegion,
4989 &GetCharArrayRegion,
4990 &GetShortArrayRegion,
4992 &GetLongArrayRegion,
4993 &GetFloatArrayRegion,
4994 &GetDoubleArrayRegion,
4995 &SetBooleanArrayRegion,
4996 &SetByteArrayRegion,
4997 &SetCharArrayRegion,
4998 &SetShortArrayRegion,
5000 &SetLongArrayRegion,
5001 &SetFloatArrayRegion,
5002 &SetDoubleArrayRegion,
5012 /* new JNI 1.2 functions */
5015 &GetStringUTFRegion,
5017 &GetPrimitiveArrayCritical,
5018 &ReleasePrimitiveArrayCritical,
5021 &ReleaseStringCritical,
5024 &DeleteWeakGlobalRef,
5028 /* new JNI 1.4 functions */
5030 &NewDirectByteBuffer,
5031 &GetDirectBufferAddress,
5032 &GetDirectBufferCapacity
5036 /* Invocation API Functions ***************************************************/
5038 /* JNI_GetDefaultJavaVMInitArgs ************************************************
5040 Returns a default configuration for the Java VM.
5042 *******************************************************************************/
5044 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
5046 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
5048 /* GNU classpath currently supports JNI 1.2 */
5050 _vm_args->version = JNI_VERSION_1_2;
5056 /* JNI_GetCreatedJavaVMs *******************************************************
5058 Returns all Java VMs that have been created. Pointers to VMs are written in
5059 the buffer vmBuf in the order they are created. At most bufLen number of
5060 entries will be written. The total number of created VMs is returned in
5063 *******************************************************************************/
5065 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
5067 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
5073 /* JNI_CreateJavaVM ************************************************************
5075 Loads and initializes a Java VM. The current thread becomes the main thread.
5076 Sets the env argument to the JNI interface pointer of the main thread.
5078 *******************************************************************************/
5080 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
5082 const struct JNIInvokeInterface *vm;
5083 struct JNINativeInterface *env;
5085 vm = &JNI_JavaVMTable;
5086 env = &JNI_JNIEnvTable;
5088 *p_vm = (JavaVM *) vm;
5089 *p_env = (JNIEnv *) env;
5096 * These are local overrides for various environment variables in Emacs.
5097 * Please do not remove this and leave it at the end of the file, where
5098 * Emacs will automagically detect them.
5099 * ---------------------------------------------------------------------
5102 * indent-tabs-mode: t