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 4501 2006-02-13 18:55:55Z 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);
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,
306 but it 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 /* _Jv_jni_CallObjectMethod ****************************************************
474 Internal function to call Java Object methods.
476 *******************************************************************************/
478 static java_objectheader *_Jv_jni_CallObjectMethod(java_objectheader *o,
480 methodinfo *m, va_list ap)
485 java_objectheader *ret;
488 STATISTICS(jniinvokation());
491 exceptions_throw_nullpointerexception();
495 /* Class initialization is done by the JIT compiler. This is ok
496 since a static method always belongs to the declaring class. */
498 if (m->flags & ACC_STATIC) {
499 /* For static methods we reset the object. */
504 /* for convenience */
509 /* For instance methods we make a virtual function table lookup. */
511 resm = method_vftbl_lookup(vftbl, m);
514 /* mark start of dump memory area */
516 dumpsize = dump_size();
518 paramcount = resm->parseddesc->paramcount;
520 blk = DMNEW(jni_callblock, paramcount);
522 fill_callblock_from_vargs(o, resm->parseddesc, blk, ap, TYPE_ADR);
524 STATISTICS(jnicallXmethodnvokation());
526 ASM_CALLJAVAFUNCTION2_ADR(ret, resm, paramcount,
527 paramcount * sizeof(jni_callblock),
530 /* release dump area */
532 dump_release(dumpsize);
538 /* _Jv_jni_CallIntMethod *******************************************************
540 Internal function to call Java integer class methods (boolean,
541 byte, char, short, int).
543 *******************************************************************************/
545 static jint _Jv_jni_CallIntMethod(java_objectheader *o, vftbl_t *vftbl,
546 methodinfo *m, va_list ap, s4 type)
554 STATISTICS(jniinvokation());
557 exceptions_throw_nullpointerexception();
561 /* Class initialization is done by the JIT compiler. This is ok
562 since a static method always belongs to the declaring class. */
564 if (m->flags & ACC_STATIC) {
565 /* For static methods we reset the object. */
570 /* for convenience */
575 /* For instance methods we make a virtual function table lookup. */
577 resm = method_vftbl_lookup(vftbl, m);
580 /* mark start of dump memory area */
582 dumpsize = dump_size();
584 paramcount = resm->parseddesc->paramcount;
586 blk = DMNEW(jni_callblock, paramcount);
588 fill_callblock_from_vargs(o, resm->parseddesc, blk, ap, type);
590 STATISTICS(jnicallXmethodnvokation());
592 ASM_CALLJAVAFUNCTION2_INT(ret, resm, paramcount,
593 paramcount * sizeof(jni_callblock),
596 /* release dump area */
598 dump_release(dumpsize);
604 /* _Jv_jni_CallLongMethod ******************************************************
606 Internal function to call Java long methods.
608 *******************************************************************************/
610 static jlong _Jv_jni_CallLongMethod(java_objectheader *o, vftbl_t *vftbl,
611 methodinfo *m, va_list ap)
619 STATISTICS(jniinvokation());
622 exceptions_throw_nullpointerexception();
626 /* Class initialization is done by the JIT compiler. This is ok
627 since a static method always belongs to the declaring class. */
629 if (m->flags & ACC_STATIC) {
630 /* For static methods we reset the object. */
635 /* for convenience */
640 /* For instance methods we make a virtual function table lookup. */
642 resm = method_vftbl_lookup(vftbl, m);
645 /* mark start of dump memory area */
647 dumpsize = dump_size();
649 paramcount = resm->parseddesc->paramcount;
651 blk = DMNEW(jni_callblock, paramcount);
653 fill_callblock_from_vargs(o, resm->parseddesc, blk, ap, PRIMITIVETYPE_LONG);
655 STATISTICS(jnicallXmethodnvokation());
657 ASM_CALLJAVAFUNCTION2_LONG(ret, resm, paramcount,
658 paramcount * sizeof(jni_callblock),
661 /* release dump area */
663 dump_release(dumpsize);
669 /* _Jv_jni_CallFloatMethod *****************************************************
671 Internal function to call Java float methods.
673 *******************************************************************************/
675 static jfloat _Jv_jni_CallFloatMethod(java_objectheader *o, vftbl_t *vftbl,
676 methodinfo *m, va_list ap)
684 /* Class initialization is done by the JIT compiler. This is ok
685 since a static method always belongs to the declaring class. */
687 if (m->flags & ACC_STATIC) {
688 /* For static methods we reset the object. */
693 /* for convenience */
698 /* For instance methods we make a virtual function table lookup. */
700 resm = method_vftbl_lookup(vftbl, m);
703 /* mark start of dump memory area */
705 dumpsize = dump_size();
707 paramcount = resm->parseddesc->paramcount;
709 blk = DMNEW(jni_callblock, paramcount);
711 fill_callblock_from_vargs(o, resm->parseddesc, blk, ap,
712 PRIMITIVETYPE_FLOAT);
714 STATISTICS(jnicallXmethodnvokation());
716 ASM_CALLJAVAFUNCTION2_FLOAT(ret, resm, paramcount,
717 paramcount * sizeof(jni_callblock),
720 /* release dump area */
722 dump_release(dumpsize);
728 /* _Jv_jni_CallDoubleMethod ****************************************************
730 Internal function to call Java double methods.
732 *******************************************************************************/
734 static jdouble _Jv_jni_CallDoubleMethod(java_objectheader *o, vftbl_t *vftbl,
735 methodinfo *m, va_list ap)
743 /* Class initialization is done by the JIT compiler. This is ok
744 since a static method always belongs to the declaring class. */
746 if (m->flags & ACC_STATIC) {
747 /* For static methods we reset the object. */
752 /* for convenience */
757 /* For instance methods we make a virtual function table lookup. */
759 resm = method_vftbl_lookup(vftbl, m);
762 /* mark start of dump memory area */
764 dumpsize = dump_size();
766 paramcount = resm->parseddesc->paramcount;
768 blk = DMNEW(jni_callblock, paramcount);
770 fill_callblock_from_vargs(o, resm->parseddesc, blk, ap,
771 PRIMITIVETYPE_DOUBLE);
773 STATISTICS(jnicallXmethodnvokation());
775 ASM_CALLJAVAFUNCTION2_DOUBLE(ret, resm, paramcount,
776 paramcount * sizeof(jni_callblock),
779 /* release dump area */
781 dump_release(dumpsize);
787 /* _Jv_jni_CallVoidMethod ******************************************************
789 Internal function to call Java void methods.
791 *******************************************************************************/
793 static void _Jv_jni_CallVoidMethod(java_objectheader *o, vftbl_t *vftbl,
794 methodinfo *m, va_list ap)
802 exceptions_throw_nullpointerexception();
806 /* Class initialization is done by the JIT compiler. This is ok
807 since a static method always belongs to the declaring class. */
809 if (m->flags & ACC_STATIC) {
810 /* For static methods we reset the object. */
815 /* for convenience */
820 /* For instance methods we make a virtual function table lookup. */
822 resm = method_vftbl_lookup(vftbl, m);
825 /* mark start of dump memory area */
827 dumpsize = dump_size();
829 paramcount = resm->parseddesc->paramcount;
831 blk = DMNEW(jni_callblock, paramcount);
833 fill_callblock_from_vargs(o, resm->parseddesc, blk, ap, TYPE_VOID);
835 STATISTICS(jnicallXmethodnvokation());
837 ASM_CALLJAVAFUNCTION2(resm, paramcount,
838 paramcount * sizeof(jni_callblock),
841 /* release dump area */
843 dump_release(dumpsize);
847 /* _Jv_jni_invokeNative ********************************************************
851 *******************************************************************************/
853 jobject *_Jv_jni_invokeNative(methodinfo *m, jobject obj,
854 java_objectarray *params)
858 java_objectheader *o;
863 exceptions_throw_nullpointerexception();
867 argcount = m->parseddesc->paramcount;
868 paramcount = argcount;
870 /* if method is non-static, remove the `this' pointer */
872 if (!(m->flags & ACC_STATIC))
875 /* the method is an instance method the obj has to be an instance of the
876 class the method belongs to. For static methods the obj parameter
879 if (!(m->flags & ACC_STATIC) && obj &&
880 (!builtin_instanceof((java_objectheader *) obj, m->class))) {
882 new_exception_message(string_java_lang_IllegalArgumentException,
883 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
887 if (((params == NULL) && (paramcount != 0)) ||
888 (params && (params->header.size != paramcount))) {
890 new_exception(string_java_lang_IllegalArgumentException);
894 if (!(m->flags & ACC_STATIC) && (obj == NULL)) {
896 new_exception_message(string_java_lang_NullPointerException,
897 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
901 if ((m->flags & ACC_STATIC) && (obj != NULL))
904 /* For virtual calls with abstract method of interface classes we
905 have to do a virtual function table lookup (XXX TWISTI: not
906 sure if this is correct, took it from the old
910 ((m->flags & ACC_ABSTRACT) || (m->class->flags & ACC_INTERFACE))) {
911 resm = method_vftbl_lookup(obj->vftbl, m);
914 /* just for convenience */
919 blk = MNEW(jni_callblock, argcount);
921 if (!fill_callblock_from_objectarray(obj, resm->parseddesc, blk,
925 switch (resm->parseddesc->returntype.decltype) {
927 ASM_CALLJAVAFUNCTION2(resm, argcount,
928 argcount * sizeof(jni_callblock),
934 case PRIMITIVETYPE_BOOLEAN: {
936 java_lang_Boolean *bo;
938 ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
939 argcount * sizeof(jni_callblock),
942 o = builtin_new(class_java_lang_Boolean);
944 /* setting the value of the object direct */
946 bo = (java_lang_Boolean *) o;
951 case PRIMITIVETYPE_BYTE: {
955 ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
956 argcount * sizeof(jni_callblock),
959 o = builtin_new(class_java_lang_Byte);
961 /* setting the value of the object direct */
963 bo = (java_lang_Byte *) o;
968 case PRIMITIVETYPE_CHAR: {
970 java_lang_Character *co;
972 ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
973 argcount * sizeof(jni_callblock),
976 o = builtin_new(class_java_lang_Character);
978 /* setting the value of the object direct */
980 co = (java_lang_Character *) o;
985 case PRIMITIVETYPE_SHORT: {
989 ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
990 argcount * sizeof(jni_callblock),
993 o = builtin_new(class_java_lang_Short);
995 /* setting the value of the object direct */
997 so = (java_lang_Short *) o;
1002 case PRIMITIVETYPE_INT: {
1004 java_lang_Integer *io;
1006 ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
1007 argcount * sizeof(jni_callblock),
1010 o = builtin_new(class_java_lang_Integer);
1012 /* setting the value of the object direct */
1014 io = (java_lang_Integer *) o;
1019 case PRIMITIVETYPE_LONG: {
1023 ASM_CALLJAVAFUNCTION2_LONG(l, resm, argcount,
1024 argcount * sizeof(jni_callblock),
1027 o = builtin_new(class_java_lang_Long);
1029 /* setting the value of the object direct */
1031 lo = (java_lang_Long *) o;
1036 case PRIMITIVETYPE_FLOAT: {
1038 java_lang_Float *fo;
1040 ASM_CALLJAVAFUNCTION2_FLOAT(f, resm, argcount,
1041 argcount * sizeof(jni_callblock),
1044 o = builtin_new(class_java_lang_Float);
1046 /* setting the value of the object direct */
1048 fo = (java_lang_Float *) o;
1053 case PRIMITIVETYPE_DOUBLE: {
1055 java_lang_Double *_do;
1057 ASM_CALLJAVAFUNCTION2_DOUBLE(d, resm, argcount,
1058 argcount * sizeof(jni_callblock),
1061 o = builtin_new(class_java_lang_Double);
1063 /* setting the value of the object direct */
1065 _do = (java_lang_Double *) o;
1071 ASM_CALLJAVAFUNCTION2_ADR(o, resm, argcount,
1072 argcount * sizeof(jni_callblock),
1077 /* if this happens the exception has already been set by
1078 fill_callblock_from_objectarray */
1080 MFREE(blk, jni_callblock, argcount);
1082 return (jobject *) 0;
1085 MFREE(blk, jni_callblock, argcount);
1087 if (*exceptionptr) {
1088 java_objectheader *cause;
1090 cause = *exceptionptr;
1092 /* clear exception pointer, we are calling JIT code again */
1094 *exceptionptr = NULL;
1097 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
1098 (java_lang_Throwable *) cause);
1101 return (jobject *) o;
1105 /* GetVersion ******************************************************************
1107 Returns the major version number in the higher 16 bits and the
1108 minor version number in the lower 16 bits.
1110 *******************************************************************************/
1112 jint GetVersion(JNIEnv *env)
1114 STATISTICS(jniinvokation());
1116 /* we support JNI 1.4 */
1118 return JNI_VERSION_1_4;
1122 /* Class Operations ***********************************************************/
1124 /* DefineClass *****************************************************************
1126 Loads a class from a buffer of raw class data. The buffer
1127 containing the raw class data is not referenced by the VM after the
1128 DefineClass call returns, and it may be discarded if desired.
1130 *******************************************************************************/
1132 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
1133 const jbyte *buf, jsize bufLen)
1135 java_lang_ClassLoader *cl;
1136 java_lang_String *s;
1140 STATISTICS(jniinvokation());
1142 cl = (java_lang_ClassLoader *) loader;
1143 s = javastring_new_char(name);
1144 ba = (java_bytearray *) buf;
1146 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
1149 return (jclass) NewLocalRef(env, (jobject) c);
1153 /* FindClass *******************************************************************
1155 This function loads a locally-defined class. It searches the
1156 directories and zip files specified by the CLASSPATH environment
1157 variable for the class with the specified name.
1159 *******************************************************************************/
1161 jclass FindClass(JNIEnv *env, const char *name)
1165 java_objectheader *cl;
1167 STATISTICS(jniinvokation());
1169 u = utf_new_char_classname((char *) name);
1171 /* Check stacktrace for classloader, if one found use it,
1172 otherwise use the system classloader. */
1174 #if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__)
1175 /* these JITs support stacktraces, and so does the interpreter */
1177 cl = stacktrace_getCurrentClassLoader();
1179 # if defined(ENABLE_INTRP)
1180 /* the interpreter supports stacktraces, even if the JIT does not */
1183 cl = stacktrace_getCurrentClassLoader();
1189 if (!(c = load_class_from_classloader(u, cl)))
1195 return (jclass) NewLocalRef(env, (jobject) c);
1199 /* FromReflectedMethod *********************************************************
1201 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1202 object to a method ID.
1204 *******************************************************************************/
1206 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
1212 STATISTICS(jniinvokation());
1217 if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
1218 java_lang_reflect_Method *rm;
1220 rm = (java_lang_reflect_Method *) method;
1221 c = (classinfo *) (rm->declaringClass);
1224 } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
1225 java_lang_reflect_Constructor *rc;
1227 rc = (java_lang_reflect_Constructor *) method;
1228 c = (classinfo *) (rc->clazz);
1234 if ((slot < 0) || (slot >= c->methodscount)) {
1235 /* this usually means a severe internal cacao error or somebody
1236 tempered around with the reflected method */
1237 log_text("error illegal slot for method in class(FromReflectedMethod)");
1241 mi = &(c->methods[slot]);
1247 /* GetSuperclass ***************************************************************
1249 If clazz represents any class other than the class Object, then
1250 this function returns the object that represents the superclass of
1251 the class specified by clazz.
1253 *******************************************************************************/
1255 jclass GetSuperclass(JNIEnv *env, jclass sub)
1259 STATISTICS(jniinvokation());
1261 c = ((classinfo *) sub)->super.cls;
1266 return (jclass) NewLocalRef(env, (jobject) c);
1270 /* IsAssignableFrom ************************************************************
1272 Determines whether an object of sub can be safely cast to sup.
1274 *******************************************************************************/
1276 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1278 STATISTICS(jniinvokation());
1280 return Java_java_lang_VMClass_isAssignableFrom(env,
1282 (java_lang_Class *) sup,
1283 (java_lang_Class *) sub);
1287 /* Throw ***********************************************************************
1289 Causes a java.lang.Throwable object to be thrown.
1291 *******************************************************************************/
1293 jint Throw(JNIEnv *env, jthrowable obj)
1295 STATISTICS(jniinvokation());
1297 *exceptionptr = (java_objectheader *) obj;
1303 /* ThrowNew ********************************************************************
1305 Constructs an exception object from the specified class with the
1306 message specified by message and causes that exception to be
1309 *******************************************************************************/
1311 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1313 java_lang_Throwable *o;
1314 java_lang_String *s;
1316 STATISTICS(jniinvokation());
1318 s = (java_lang_String *) javastring_new_char(msg);
1320 /* instantiate exception object */
1322 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
1328 *exceptionptr = (java_objectheader *) o;
1334 /* ExceptionOccurred ***********************************************************
1336 Determines if an exception is being thrown. The exception stays
1337 being thrown until either the native code calls ExceptionClear(),
1338 or the Java code handles the exception.
1340 *******************************************************************************/
1342 jthrowable ExceptionOccurred(JNIEnv *env)
1344 java_objectheader *e;
1346 STATISTICS(jniinvokation());
1350 return NewLocalRef(env, (jthrowable) e);
1354 /* ExceptionDescribe ***********************************************************
1356 Prints an exception and a backtrace of the stack to a system
1357 error-reporting channel, such as stderr. This is a convenience
1358 routine provided for debugging.
1360 *******************************************************************************/
1362 void ExceptionDescribe(JNIEnv *env)
1364 java_objectheader *e;
1367 STATISTICS(jniinvokation());
1372 /* clear exception, because we are calling jit code again */
1374 *exceptionptr = NULL;
1376 /* get printStackTrace method from exception class */
1378 m = class_resolveclassmethod(e->vftbl->class,
1379 utf_printStackTrace,
1385 /* XXX what should we do? */
1388 /* print the stacktrace */
1390 ASM_CALLJAVAFUNCTION(m, e, NULL, NULL, NULL);
1395 /* ExceptionClear **************************************************************
1397 Clears any exception that is currently being thrown. If no
1398 exception is currently being thrown, this routine has no effect.
1400 *******************************************************************************/
1402 void ExceptionClear(JNIEnv *env)
1404 STATISTICS(jniinvokation());
1406 *exceptionptr = NULL;
1410 /* FatalError ******************************************************************
1412 Raises a fatal error and does not expect the VM to recover. This
1413 function does not return.
1415 *******************************************************************************/
1417 void FatalError(JNIEnv *env, const char *msg)
1419 STATISTICS(jniinvokation());
1421 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
1425 /* PushLocalFrame **************************************************************
1427 Creates a new local reference frame, in which at least a given
1428 number of local references can be created.
1430 *******************************************************************************/
1432 jint PushLocalFrame(JNIEnv* env, jint capacity)
1434 STATISTICS(jniinvokation());
1436 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
1443 /* PopLocalFrame ***************************************************************
1445 Pops off the current local reference frame, frees all the local
1446 references, and returns a local reference in the previous local
1447 reference frame for the given result object.
1449 *******************************************************************************/
1451 jobject PopLocalFrame(JNIEnv* env, jobject result)
1453 STATISTICS(jniinvokation());
1455 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
1459 /* add local reference and return the value */
1461 return NewLocalRef(env, NULL);
1465 /* DeleteLocalRef **************************************************************
1467 Deletes the local reference pointed to by localRef.
1469 *******************************************************************************/
1471 void DeleteLocalRef(JNIEnv *env, jobject localRef)
1473 java_objectheader *o;
1474 localref_table *lrt;
1477 STATISTICS(jniinvokation());
1479 o = (java_objectheader *) localRef;
1481 /* get local reference table (thread specific) */
1483 lrt = LOCALREFTABLE;
1485 /* remove the reference */
1487 for (i = 0; i < lrt->capacity; i++) {
1488 if (lrt->refs[i] == o) {
1489 lrt->refs[i] = NULL;
1496 /* this should not happen */
1498 /* if (opt_checkjni) */
1499 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1500 log_text("JNI-DeleteLocalRef: Bad global or local ref passed to JNI");
1504 /* IsSameObject ****************************************************************
1506 Tests whether two references refer to the same Java object.
1508 *******************************************************************************/
1510 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1512 STATISTICS(jniinvokation());
1521 /* NewLocalRef *****************************************************************
1523 Creates a new local reference that refers to the same object as ref.
1525 *******************************************************************************/
1527 jobject NewLocalRef(JNIEnv *env, jobject ref)
1529 localref_table *lrt;
1532 STATISTICS(jniinvokation());
1537 /* get local reference table (thread specific) */
1539 lrt = LOCALREFTABLE;
1541 /* check if we have space for the requested reference */
1543 if (lrt->used == lrt->capacity) {
1544 /* throw_cacao_exception_exit(string_java_lang_InternalError, */
1545 /* "Too many local references"); */
1546 fprintf(stderr, "Too many local references");
1550 /* insert the reference */
1552 for (i = 0; i < lrt->capacity; i++) {
1553 if (lrt->refs[i] == NULL) {
1554 lrt->refs[i] = (java_objectheader *) ref;
1561 /* should not happen, just to be sure */
1565 /* keep compiler happy */
1571 /* EnsureLocalCapacity *********************************************************
1573 Ensures that at least a given number of local references can be
1574 created in the current thread
1576 *******************************************************************************/
1578 jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
1580 localref_table *lrt;
1582 STATISTICS(jniinvokation());
1584 /* get local reference table (thread specific) */
1586 lrt = LOCALREFTABLE;
1588 /* check if capacity elements are available in the local references table */
1590 if ((lrt->used + capacity) > lrt->capacity) {
1591 *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
1599 /* AllocObject *****************************************************************
1601 Allocates a new Java object without invoking any of the
1602 constructors for the object. Returns a reference to the object.
1604 *******************************************************************************/
1606 jobject AllocObject(JNIEnv *env, jclass clazz)
1608 java_objectheader *o;
1610 STATISTICS(jniinvokation());
1612 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1614 new_exception_utfmessage(string_java_lang_InstantiationException,
1619 o = builtin_new(clazz);
1621 return NewLocalRef(env, o);
1625 /* NewObject *******************************************************************
1627 Programmers place all arguments that are to be passed to the
1628 constructor immediately following the methodID
1629 argument. NewObject() accepts these arguments and passes them to
1630 the Java method that the programmer wishes to invoke.
1632 *******************************************************************************/
1634 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1636 java_objectheader *o;
1639 STATISTICS(jniinvokation());
1643 o = builtin_new(clazz);
1648 /* call constructor */
1650 va_start(ap, methodID);
1651 _Jv_jni_CallVoidMethod(o, o->vftbl, methodID, ap);
1654 return NewLocalRef(env, o);
1658 /* NewObjectV ******************************************************************
1660 Programmers place all arguments that are to be passed to the
1661 constructor in an args argument of type va_list that immediately
1662 follows the methodID argument. NewObjectV() accepts these
1663 arguments, and, in turn, passes them to the Java method that the
1664 programmer wishes to invoke.
1666 *******************************************************************************/
1668 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1670 java_objectheader *o;
1672 STATISTICS(jniinvokation());
1676 o = builtin_new(clazz);
1681 /* call constructor */
1683 _Jv_jni_CallVoidMethod(o, o->vftbl, methodID, args);
1685 return NewLocalRef(env, o);
1689 /***********************************************************************************
1691 Constructs a new Java object
1692 arguments that are to be passed to the constructor are placed in
1693 args array of jvalues
1695 ***********************************************************************************/
1697 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1699 STATISTICS(jniinvokation());
1701 log_text("JNI-Call: NewObjectA: IMPLEMENT ME!");
1703 return NewLocalRef(env, NULL);
1707 /* GetObjectClass **************************************************************
1709 Returns the class of an object.
1711 *******************************************************************************/
1713 jclass GetObjectClass(JNIEnv *env, jobject obj)
1717 STATISTICS(jniinvokation());
1719 if (!obj || !obj->vftbl)
1722 c = obj->vftbl->class;
1724 return (jclass) NewLocalRef(env, (jobject) c);
1728 /* IsInstanceOf ****************************************************************
1730 Tests whether an object is an instance of a class.
1732 *******************************************************************************/
1734 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1736 STATISTICS(jniinvokation());
1738 return Java_java_lang_VMClass_isInstance(env,
1740 (java_lang_Class *) clazz,
1741 (java_lang_Object *) obj);
1745 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1747 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1749 java_lang_reflect_Field *f;
1751 jfieldID fid; /* the JNI-fieldid of the wrapping object */
1753 STATISTICS(jniinvokation());
1755 /*log_text("JNI-Call: FromReflectedField");*/
1757 f=(java_lang_reflect_Field *)field;
1759 c=(classinfo*)(f->declaringClass);
1760 if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1761 /*this usually means a severe internal cacao error or somebody
1762 tempered around with the reflected method*/
1763 log_text("error illegal slot for field in class(FromReflectedField)");
1766 fid=&(c->fields[f->slot]);
1771 /* ToReflectedMethod ***********************************************************
1773 Converts a method ID derived from cls to an instance of the
1774 java.lang.reflect.Method class or to an instance of the
1775 java.lang.reflect.Constructor class.
1777 *******************************************************************************/
1779 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1781 STATISTICS(jniinvokation());
1783 log_text("JNI-Call: ToReflectedMethod: IMPLEMENT ME!");
1789 /* ToReflectedField ************************************************************
1791 Converts a field ID derived from cls to an instance of the
1792 java.lang.reflect.Field class.
1794 *******************************************************************************/
1796 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1799 STATISTICS(jniinvokation());
1801 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1807 /* Calling Instance Methods ***************************************************/
1809 /* GetMethodID *****************************************************************
1811 Returns the method ID for an instance (nonstatic) method of a class
1812 or interface. The method may be defined in one of the clazz's
1813 superclasses and inherited by clazz. The method is determined by
1814 its name and signature.
1816 GetMethodID() causes an uninitialized class to be initialized.
1818 *******************************************************************************/
1820 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1828 STATISTICS(jniinvokation());
1830 c = (classinfo *) clazz;
1835 if (!(c->state & CLASS_INITIALIZED))
1836 if (!initialize_class(c))
1839 /* try to get the method of the class or one of it's superclasses */
1841 uname = utf_new_char((char *) name);
1842 udesc = utf_new_char((char *) sig);
1844 m = class_resolvemethod(clazz, uname, udesc);
1846 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1847 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1856 /* JNI-functions for calling instance methods *********************************/
1858 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1860 java_objectheader* ret;
1863 va_start(ap, methodID);
1864 ret = _Jv_jni_CallObjectMethod(obj, obj->vftbl, methodID, ap);
1867 return NewLocalRef(env, ret);
1871 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1873 java_objectheader* ret;
1875 ret = _Jv_jni_CallObjectMethod(obj, obj->vftbl, methodID, args);
1877 return NewLocalRef(env, ret);
1881 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1883 log_text("JNI-Call: CallObjectMethodA: IMPLEMENT ME!");
1885 return NewLocalRef(env, NULL);
1889 jboolean CallBooleanMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1894 va_start(ap, methodID);
1895 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, ap,
1896 PRIMITIVETYPE_BOOLEAN);
1903 jboolean CallBooleanMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1907 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, args,
1908 PRIMITIVETYPE_BOOLEAN);
1914 jboolean CallBooleanMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1916 log_text("JNI-Call: CallBooleanMethodA");
1922 jbyte CallByteMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1927 va_start(ap, methodID);
1928 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, ap,
1929 PRIMITIVETYPE_BYTE);
1936 jbyte CallByteMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1940 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, args,
1941 PRIMITIVETYPE_BYTE);
1947 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1949 log_text("JNI-Call: CallByteMethodA: IMPLEMENT ME!");
1955 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1960 va_start(ap, methodID);
1961 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, ap,
1962 PRIMITIVETYPE_CHAR);
1969 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1973 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, args,
1974 PRIMITIVETYPE_CHAR);
1980 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1982 log_text("JNI-Call: CallCharMethodA: IMPLEMENT ME!");
1988 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1993 va_start(ap, methodID);
1994 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, ap,
1995 PRIMITIVETYPE_SHORT);
2002 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2006 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, args,
2007 PRIMITIVETYPE_SHORT);
2013 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2015 log_text("JNI-Call: CallShortMethodA: IMPLEMENT ME!");
2022 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2027 va_start(ap, methodID);
2028 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, ap,
2036 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2040 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, args,
2047 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2049 log_text("JNI-Call: CallIntMethodA: IMPLEMENT ME!");
2056 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2061 va_start(ap, methodID);
2062 ret = _Jv_jni_CallLongMethod(obj, obj->vftbl, methodID, ap);
2069 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2073 ret = _Jv_jni_CallLongMethod(obj, obj->vftbl, methodID, args);
2079 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2081 log_text("JNI-Call: CallLongMethodA: IMPLEMENT ME!");
2088 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2093 va_start(ap, methodID);
2094 ret = _Jv_jni_CallFloatMethod(obj, obj->vftbl, methodID, ap);
2101 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2105 ret = _Jv_jni_CallFloatMethod(obj, obj->vftbl, methodID, args);
2111 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2113 log_text("JNI-Call: CallFloatMethodA: IMPLEMENT ME!");
2120 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2125 va_start(ap, methodID);
2126 ret = _Jv_jni_CallDoubleMethod(obj, obj->vftbl, methodID, ap);
2133 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2137 ret = _Jv_jni_CallDoubleMethod(obj, obj->vftbl, methodID, args);
2143 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2145 log_text("JNI-Call: CallDoubleMethodA: IMPLEMENT ME!");
2152 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2156 va_start(ap, methodID);
2157 _Jv_jni_CallVoidMethod(obj, obj->vftbl, methodID, ap);
2162 void CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2164 _Jv_jni_CallVoidMethod(obj, obj->vftbl, methodID, args);
2168 void CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2170 log_text("JNI-Call: CallVoidMethodA: IMPLEMENT ME!");
2175 jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2177 java_objectheader *ret;
2180 va_start(ap, methodID);
2181 ret = _Jv_jni_CallObjectMethod(obj, clazz->vftbl, methodID, ap);
2184 return NewLocalRef(env, ret);
2188 jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2190 java_objectheader* ret;
2192 ret = _Jv_jni_CallObjectMethod(obj, clazz->vftbl, methodID, args);
2194 return NewLocalRef(env, ret);
2198 jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2200 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2202 return NewLocalRef(env, NULL);
2207 jboolean CallNonvirtualBooleanMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2212 va_start(ap, methodID);
2213 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, ap,
2214 PRIMITIVETYPE_BOOLEAN);
2222 jboolean CallNonvirtualBooleanMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2226 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, args,
2227 PRIMITIVETYPE_BOOLEAN);
2233 jboolean CallNonvirtualBooleanMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2235 log_text("JNI-Call: CallNonvirtualBooleanMethodA: IMPLEMENT ME!");
2241 jbyte CallNonvirtualByteMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2246 va_start(ap, methodID);
2247 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, ap,
2248 PRIMITIVETYPE_BYTE);
2255 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2259 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, args,
2260 PRIMITIVETYPE_BYTE);
2266 jbyte CallNonvirtualByteMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2268 log_text("JNI-Call: CallNonvirtualByteMethodA: IMPLEMENT ME!");
2275 jchar CallNonvirtualCharMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2280 va_start(ap, methodID);
2281 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, ap,
2282 PRIMITIVETYPE_CHAR);
2289 jchar CallNonvirtualCharMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2293 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, args,
2294 PRIMITIVETYPE_CHAR);
2300 jchar CallNonvirtualCharMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2302 log_text("JNI-Call: CallNonvirtualCharMethodA: IMPLEMENT ME!");
2309 jshort CallNonvirtualShortMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2314 va_start(ap, methodID);
2315 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, ap,
2316 PRIMITIVETYPE_SHORT);
2323 jshort CallNonvirtualShortMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2327 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, args,
2328 PRIMITIVETYPE_SHORT);
2334 jshort CallNonvirtualShortMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2336 log_text("JNI-Call: CallNonvirtualShortMethodA: IMPLEMENT ME!");
2343 jint CallNonvirtualIntMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2348 va_start(ap, methodID);
2349 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, ap,
2357 jint CallNonvirtualIntMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2361 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, args,
2368 jint CallNonvirtualIntMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2370 log_text("JNI-Call: CallNonvirtualIntMethodA: IMPLEMENT ME!");
2377 jlong CallNonvirtualLongMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2382 va_start(ap, methodID);
2383 ret = _Jv_jni_CallLongMethod(obj, clazz->vftbl, methodID, ap);
2390 jlong CallNonvirtualLongMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2394 ret = _Jv_jni_CallLongMethod(obj, clazz->vftbl, methodID, args);
2400 jlong CallNonvirtualLongMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2402 log_text("JNI-Call: CallNonvirtualLongMethodA: IMPLEMENT ME!");
2409 jfloat CallNonvirtualFloatMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2414 va_start(ap, methodID);
2415 ret = _Jv_jni_CallFloatMethod(obj, clazz->vftbl, methodID, ap);
2422 jfloat CallNonvirtualFloatMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2426 ret = _Jv_jni_CallFloatMethod(obj, clazz->vftbl, methodID, args);
2432 jfloat CallNonvirtualFloatMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2434 STATISTICS(jniinvokation());
2436 log_text("JNI-Call: CallNonvirtualFloatMethodA: IMPLEMENT ME!");
2443 jdouble CallNonvirtualDoubleMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2448 va_start(ap, methodID);
2449 ret = _Jv_jni_CallDoubleMethod(obj, clazz->vftbl, methodID, ap);
2456 jdouble CallNonvirtualDoubleMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2460 ret = _Jv_jni_CallDoubleMethod(obj, clazz->vftbl, methodID, args);
2466 jdouble CallNonvirtualDoubleMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2468 log_text("JNI-Call: CallNonvirtualDoubleMethodA: IMPLEMENT ME!");
2475 void CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2479 va_start(ap, methodID);
2480 _Jv_jni_CallVoidMethod(obj, clazz->vftbl, methodID, ap);
2485 void CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2487 _Jv_jni_CallVoidMethod(obj, clazz->vftbl, methodID, args);
2491 void CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
2493 log_text("JNI-Call: CallNonvirtualVoidMethodA: IMPLEMENT ME!");
2497 /* Accessing Fields of Objects ************************************************/
2499 /* GetFieldID ******************************************************************
2501 Returns the field ID for an instance (nonstatic) field of a
2502 class. The field is specified by its name and signature. The
2503 Get<type>Field and Set<type>Field families of accessor functions
2504 use field IDs to retrieve object fields.
2506 *******************************************************************************/
2508 jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2515 STATISTICS(jniinvokation());
2517 uname = utf_new_char((char *) name);
2518 udesc = utf_new_char((char *) sig);
2520 f = class_findfield(clazz, uname, udesc);
2523 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2529 /* Get<type>Field Routines *****************************************************
2531 This family of accessor routines returns the value of an instance
2532 (nonstatic) field of an object. The field to access is specified by
2533 a field ID obtained by calling GetFieldID().
2535 *******************************************************************************/
2537 jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2539 java_objectheader *o;
2541 STATISTICS(jniinvokation());
2543 o = GET_FIELD(obj, java_objectheader*, fieldID);
2545 return NewLocalRef(env, o);
2549 jboolean GetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID)
2553 STATISTICS(jniinvokation());
2555 i = GET_FIELD(obj, s4, fieldID);
2557 return (jboolean) i;
2561 jbyte GetByteField(JNIEnv *env, jobject obj, jfieldID fieldID)
2565 STATISTICS(jniinvokation());
2567 i = GET_FIELD(obj, s4, fieldID);
2573 jchar GetCharField(JNIEnv *env, jobject obj, jfieldID fieldID)
2577 STATISTICS(jniinvokation());
2579 i = GET_FIELD(obj, s4, fieldID);
2585 jshort GetShortField(JNIEnv *env, jobject obj, jfieldID fieldID)
2589 STATISTICS(jniinvokation());
2591 i = GET_FIELD(obj, s4, fieldID);
2597 jint GetIntField(JNIEnv *env, jobject obj, jfieldID fieldID)
2601 STATISTICS(jniinvokation());
2603 i = GET_FIELD(obj, s4, fieldID);
2609 jlong GetLongField(JNIEnv *env, jobject obj, jfieldID fieldID)
2613 STATISTICS(jniinvokation());
2615 l = GET_FIELD(obj, s8, fieldID);
2621 jfloat GetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID)
2625 STATISTICS(jniinvokation());
2627 f = GET_FIELD(obj, float, fieldID);
2633 jdouble GetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID)
2637 STATISTICS(jniinvokation());
2639 d = GET_FIELD(obj, double, fieldID);
2645 /* Set<type>Field Routines *****************************************************
2647 This family of accessor routines sets the value of an instance
2648 (nonstatic) field of an object. The field to access is specified by
2649 a field ID obtained by calling GetFieldID().
2651 *******************************************************************************/
2653 void SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value)
2655 STATISTICS(jniinvokation());
2657 SET_FIELD(obj, java_objectheader*, fieldID, value);
2661 void SetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID, jboolean value)
2663 STATISTICS(jniinvokation());
2665 SET_FIELD(obj, s4, fieldID, value);
2669 void SetByteField(JNIEnv *env, jobject obj, jfieldID fieldID, jbyte value)
2671 STATISTICS(jniinvokation());
2673 SET_FIELD(obj, s4, fieldID, value);
2677 void SetCharField(JNIEnv *env, jobject obj, jfieldID fieldID, jchar value)
2679 STATISTICS(jniinvokation());
2681 SET_FIELD(obj, s4, fieldID, value);
2685 void SetShortField(JNIEnv *env, jobject obj, jfieldID fieldID, jshort value)
2687 STATISTICS(jniinvokation());
2689 SET_FIELD(obj, s4, fieldID, value);
2693 void SetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint value)
2695 STATISTICS(jniinvokation());
2697 SET_FIELD(obj, s4, fieldID, value);
2701 void SetLongField(JNIEnv *env, jobject obj, jfieldID fieldID, jlong value)
2703 STATISTICS(jniinvokation());
2705 SET_FIELD(obj, s8, fieldID, value);
2709 void SetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID, jfloat value)
2711 STATISTICS(jniinvokation());
2713 SET_FIELD(obj, float, fieldID, value);
2717 void SetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID, jdouble value)
2719 STATISTICS(jniinvokation());
2721 SET_FIELD(obj, double, fieldID, value);
2725 /* Calling Static Methods *****************************************************/
2727 /* GetStaticMethodID ***********************************************************
2729 Returns the method ID for a static method of a class. The method is
2730 specified by its name and signature.
2732 GetStaticMethodID() causes an uninitialized class to be
2735 *******************************************************************************/
2737 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2745 STATISTICS(jniinvokation());
2747 c = (classinfo *) clazz;
2752 if (!(c->state & CLASS_INITIALIZED))
2753 if (!initialize_class(c))
2756 /* try to get the static method of the class */
2758 uname = utf_new_char((char *) name);
2759 udesc = utf_new_char((char *) sig);
2761 m = class_resolvemethod(c, uname, udesc);
2763 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2764 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2773 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2775 java_objectheader *ret;
2778 va_start(ap, methodID);
2779 ret = _Jv_jni_CallObjectMethod(NULL, NULL, methodID, ap);
2782 return NewLocalRef(env, ret);
2786 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2788 java_objectheader *ret;
2790 ret = _Jv_jni_CallObjectMethod(NULL, NULL, methodID, args);
2792 return NewLocalRef(env, ret);
2796 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2798 log_text("JNI-Call: CallStaticObjectMethodA: IMPLEMENT ME!");
2800 return NewLocalRef(env, NULL);
2804 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2809 va_start(ap, methodID);
2810 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, ap,
2811 PRIMITIVETYPE_BOOLEAN);
2818 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2822 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, args,
2823 PRIMITIVETYPE_BOOLEAN);
2829 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2831 log_text("JNI-Call: CallStaticBooleanMethodA: IMPLEMENT ME!");
2837 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2842 va_start(ap, methodID);
2843 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, ap, PRIMITIVETYPE_BYTE);
2850 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2854 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, args, PRIMITIVETYPE_BYTE);
2860 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2862 log_text("JNI-Call: CallStaticByteMethodA: IMPLEMENT ME!");
2868 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2873 va_start(ap, methodID);
2874 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, ap, PRIMITIVETYPE_CHAR);
2881 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2885 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, args, PRIMITIVETYPE_CHAR);
2891 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2893 log_text("JNI-Call: CallStaticCharMethodA: IMPLEMENT ME!");
2899 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2904 va_start(ap, methodID);
2905 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, ap, PRIMITIVETYPE_SHORT);
2912 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2916 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, args,
2917 PRIMITIVETYPE_SHORT);
2923 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2925 log_text("JNI-Call: CallStaticShortMethodA: IMPLEMENT ME!");
2931 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2936 va_start(ap, methodID);
2937 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, ap, PRIMITIVETYPE_INT);
2944 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2948 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, args, PRIMITIVETYPE_INT);
2954 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2956 log_text("JNI-Call: CallStaticIntMethodA: IMPLEMENT ME!");
2962 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2967 va_start(ap, methodID);
2968 ret = _Jv_jni_CallLongMethod(NULL, NULL, methodID, ap);
2975 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
2980 ret = _Jv_jni_CallLongMethod(NULL, NULL, methodID, args);
2986 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2988 log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!");
2995 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3000 va_start(ap, methodID);
3001 ret = _Jv_jni_CallFloatMethod(NULL, NULL, methodID, ap);
3008 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3012 ret = _Jv_jni_CallFloatMethod(NULL, NULL, methodID, args);
3018 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3020 log_text("JNI-Call: CallStaticFloatMethodA: IMPLEMENT ME!");
3026 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3031 va_start(ap, methodID);
3032 ret = _Jv_jni_CallDoubleMethod(NULL, NULL, methodID, ap);
3039 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3043 ret = _Jv_jni_CallDoubleMethod(NULL, NULL, methodID, args);
3049 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3051 log_text("JNI-Call: CallStaticDoubleMethodA: IMPLEMENT ME!");
3057 void CallStaticVoidMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3061 va_start(ap, methodID);
3062 _Jv_jni_CallVoidMethod(NULL, NULL, methodID, ap);
3067 void CallStaticVoidMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3069 _Jv_jni_CallVoidMethod(NULL, NULL, methodID, args);
3073 void CallStaticVoidMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue * args)
3075 log_text("JNI-Call: CallStaticVoidMethodA: IMPLEMENT ME!");
3079 /* Accessing Static Fields ****************************************************/
3081 /* GetStaticFieldID ************************************************************
3083 Returns the field ID for a static field of a class. The field is
3084 specified by its name and signature. The GetStatic<type>Field and
3085 SetStatic<type>Field families of accessor functions use field IDs
3086 to retrieve static fields.
3088 *******************************************************************************/
3090 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
3094 STATISTICS(jniinvokation());
3096 f = class_findfield(clazz,
3097 utf_new_char((char *) name),
3098 utf_new_char((char *) sig));
3101 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
3107 /* GetStatic<type>Field ********************************************************
3109 This family of accessor routines returns the value of a static
3112 *******************************************************************************/
3114 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3116 STATISTICS(jniinvokation());
3118 if (!(clazz->state & CLASS_INITIALIZED))
3119 if (!initialize_class(clazz))
3122 return NewLocalRef(env, fieldID->value.a);
3126 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3128 STATISTICS(jniinvokation());
3130 if (!(clazz->state & CLASS_INITIALIZED))
3131 if (!initialize_class(clazz))
3134 return fieldID->value.i;
3138 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3140 STATISTICS(jniinvokation());
3142 if (!(clazz->state & CLASS_INITIALIZED))
3143 if (!initialize_class(clazz))
3146 return fieldID->value.i;
3150 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3152 STATISTICS(jniinvokation());
3154 if (!(clazz->state & CLASS_INITIALIZED))
3155 if (!initialize_class(clazz))
3158 return fieldID->value.i;
3162 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3164 STATISTICS(jniinvokation());
3166 if (!(clazz->state & CLASS_INITIALIZED))
3167 if (!initialize_class(clazz))
3170 return fieldID->value.i;
3174 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3176 STATISTICS(jniinvokation());
3178 if (!(clazz->state & CLASS_INITIALIZED))
3179 if (!initialize_class(clazz))
3182 return fieldID->value.i;
3186 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3188 STATISTICS(jniinvokation());
3190 if (!(clazz->state & CLASS_INITIALIZED))
3191 if (!initialize_class(clazz))
3194 return fieldID->value.l;
3198 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3200 STATISTICS(jniinvokation());
3202 if (!(clazz->state & CLASS_INITIALIZED))
3203 if (!initialize_class(clazz))
3206 return fieldID->value.f;
3210 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3212 STATISTICS(jniinvokation());
3214 if (!(clazz->state & CLASS_INITIALIZED))
3215 if (!initialize_class(clazz))
3218 return fieldID->value.d;
3222 /* SetStatic<type>Field *******************************************************
3224 This family of accessor routines sets the value of a static field
3227 *******************************************************************************/
3229 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
3231 STATISTICS(jniinvokation());
3233 if (!(clazz->state & CLASS_INITIALIZED))
3234 if (!initialize_class(clazz))
3237 fieldID->value.a = value;
3241 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
3243 STATISTICS(jniinvokation());
3245 if (!(clazz->state & CLASS_INITIALIZED))
3246 if (!initialize_class(clazz))
3249 fieldID->value.i = value;
3253 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
3255 STATISTICS(jniinvokation());
3257 if (!(clazz->state & CLASS_INITIALIZED))
3258 if (!initialize_class(clazz))
3261 fieldID->value.i = value;
3265 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
3267 STATISTICS(jniinvokation());
3269 if (!(clazz->state & CLASS_INITIALIZED))
3270 if (!initialize_class(clazz))
3273 fieldID->value.i = value;
3277 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
3279 STATISTICS(jniinvokation());
3281 if (!(clazz->state & CLASS_INITIALIZED))
3282 if (!initialize_class(clazz))
3285 fieldID->value.i = value;
3289 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
3291 STATISTICS(jniinvokation());
3293 if (!(clazz->state & CLASS_INITIALIZED))
3294 if (!initialize_class(clazz))
3297 fieldID->value.i = value;
3301 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
3303 STATISTICS(jniinvokation());
3305 if (!(clazz->state & CLASS_INITIALIZED))
3306 if (!initialize_class(clazz))
3309 fieldID->value.l = value;
3313 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
3315 STATISTICS(jniinvokation());
3317 if (!(clazz->state & CLASS_INITIALIZED))
3318 if (!initialize_class(clazz))
3321 fieldID->value.f = value;
3325 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
3327 STATISTICS(jniinvokation());
3329 if (!(clazz->state & CLASS_INITIALIZED))
3330 if (!initialize_class(clazz))
3333 fieldID->value.d = value;
3337 /* String Operations **********************************************************/
3339 /* NewString *******************************************************************
3341 Create new java.lang.String object from an array of Unicode
3344 *******************************************************************************/
3346 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
3348 java_lang_String *s;
3352 STATISTICS(jniinvokation());
3354 s = (java_lang_String *) builtin_new(class_java_lang_String);
3355 a = builtin_newarray_char(len);
3357 /* javastring or characterarray could not be created */
3362 for (i = 0; i < len; i++)
3363 a->data[i] = buf[i];
3369 return (jstring) NewLocalRef(env, (jobject) s);
3373 static jchar emptyStringJ[]={0,0};
3375 /* GetStringLength *************************************************************
3377 Returns the length (the count of Unicode characters) of a Java
3380 *******************************************************************************/
3382 jsize GetStringLength(JNIEnv *env, jstring str)
3384 return ((java_lang_String *) str)->count;
3388 /******************** convertes javastring to u2-array ****************************/
3390 u2 *javastring_tou2(jstring so)
3392 java_lang_String *s;
3397 STATISTICS(jniinvokation());
3399 s = (java_lang_String *) so;
3409 /* allocate memory */
3411 stringbuffer = MNEW(u2, s->count + 1);
3415 for (i = 0; i < s->count; i++)
3416 stringbuffer[i] = a->data[s->offset + i];
3418 /* terminate string */
3420 stringbuffer[i] = '\0';
3422 return stringbuffer;
3426 /* GetStringChars **************************************************************
3428 Returns a pointer to the array of Unicode characters of the
3429 string. This pointer is valid until ReleaseStringchars() is called.
3431 *******************************************************************************/
3433 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
3437 STATISTICS(jniinvokation());
3439 jc = javastring_tou2(str);
3451 return emptyStringJ;
3455 /* ReleaseStringChars **********************************************************
3457 Informs the VM that the native code no longer needs access to
3458 chars. The chars argument is a pointer obtained from string using
3461 *******************************************************************************/
3463 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
3465 STATISTICS(jniinvokation());
3467 if (chars == emptyStringJ)
3470 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
3474 /* NewStringUTF ****************************************************************
3476 Constructs a new java.lang.String object from an array of UTF-8 characters.
3478 *******************************************************************************/
3480 jstring NewStringUTF(JNIEnv *env, const char *bytes)
3482 java_lang_String *s;
3484 STATISTICS(jniinvokation());
3486 s = javastring_new(utf_new_char(bytes));
3488 return (jstring) NewLocalRef(env, (jobject) s);
3492 /****************** returns the utf8 length in bytes of a string *******************/
3494 jsize GetStringUTFLength (JNIEnv *env, jstring string)
3496 java_lang_String *s = (java_lang_String*) string;
3498 STATISTICS(jniinvokation());
3500 return (jsize) u2_utflength(s->value->data, s->count);
3504 /* GetStringUTFChars ***********************************************************
3506 Returns a pointer to an array of UTF-8 characters of the
3507 string. This array is valid until it is released by
3508 ReleaseStringUTFChars().
3510 *******************************************************************************/
3512 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
3516 STATISTICS(jniinvokation());
3524 u = javastring_toutf((java_lang_String *) string, false);
3533 /* ReleaseStringUTFChars *******************************************************
3535 Informs the VM that the native code no longer needs access to
3536 utf. The utf argument is a pointer derived from string using
3537 GetStringUTFChars().
3539 *******************************************************************************/
3541 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
3543 STATISTICS(jniinvokation());
3545 /* XXX we don't release utf chars right now, perhaps that should be done
3546 later. Since there is always one reference the garbage collector will
3551 /* Array Operations ***********************************************************/
3553 /* GetArrayLength **************************************************************
3555 Returns the number of elements in the array.
3557 *******************************************************************************/
3559 jsize GetArrayLength(JNIEnv *env, jarray array)
3561 STATISTICS(jniinvokation());
3567 /* NewObjectArray **************************************************************
3569 Constructs a new array holding objects in class elementClass. All
3570 elements are initially set to initialElement.
3572 *******************************************************************************/
3574 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
3576 java_objectarray *oa;
3579 STATISTICS(jniinvokation());
3582 exceptions_throw_negativearraysizeexception();
3586 oa = builtin_anewarray(length, elementClass);
3591 /* set all elements to initialElement */
3593 for (i = 0; i < length; i++)
3594 oa->data[i] = initialElement;
3596 return (jobjectArray) NewLocalRef(env, (jobject) oa);
3600 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
3604 STATISTICS(jniinvokation());
3606 if (index >= array->header.size) {
3607 exceptions_throw_arrayindexoutofboundsexception();
3611 o = array->data[index];
3613 return NewLocalRef(env, o);
3617 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3619 java_objectarray *oa;
3620 java_objectheader *o;
3622 STATISTICS(jniinvokation());
3624 oa = (java_objectarray *) array;
3625 o = (java_objectheader *) val;
3627 if (index >= array->header.size) {
3628 exceptions_throw_arrayindexoutofboundsexception();
3632 /* check if the class of value is a subclass of the element class
3635 if (!builtin_canstore(oa, o)) {
3636 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3641 array->data[index] = val;
3645 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3647 java_booleanarray *ba;
3649 STATISTICS(jniinvokation());
3652 exceptions_throw_negativearraysizeexception();
3656 ba = builtin_newarray_boolean(len);
3658 return (jbooleanArray) NewLocalRef(env, (jobject) ba);
3662 jbyteArray NewByteArray(JNIEnv *env, jsize len)
3666 STATISTICS(jniinvokation());
3669 exceptions_throw_negativearraysizeexception();
3673 ba = builtin_newarray_byte(len);
3675 return (jbyteArray) NewLocalRef(env, (jobject) ba);
3679 jcharArray NewCharArray(JNIEnv *env, jsize len)
3683 STATISTICS(jniinvokation());
3686 exceptions_throw_negativearraysizeexception();
3690 ca = builtin_newarray_char(len);
3692 return (jcharArray) NewLocalRef(env, (jobject) ca);
3696 jshortArray NewShortArray(JNIEnv *env, jsize len)
3698 java_shortarray *sa;
3700 STATISTICS(jniinvokation());
3703 exceptions_throw_negativearraysizeexception();
3707 sa = builtin_newarray_short(len);
3709 return (jshortArray) NewLocalRef(env, (jobject) sa);
3713 jintArray NewIntArray(JNIEnv *env, jsize len)
3717 STATISTICS(jniinvokation());
3720 exceptions_throw_negativearraysizeexception();
3724 ia = builtin_newarray_int(len);
3726 return (jintArray) NewLocalRef(env, (jobject) ia);
3730 jlongArray NewLongArray(JNIEnv *env, jsize len)
3734 STATISTICS(jniinvokation());
3737 exceptions_throw_negativearraysizeexception();
3741 la = builtin_newarray_long(len);
3743 return (jlongArray) NewLocalRef(env, (jobject) la);
3747 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3749 java_floatarray *fa;
3751 STATISTICS(jniinvokation());
3754 exceptions_throw_negativearraysizeexception();
3758 fa = builtin_newarray_float(len);
3760 return (jfloatArray) NewLocalRef(env, (jobject) fa);
3764 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3766 java_doublearray *da;
3768 STATISTICS(jniinvokation());
3771 exceptions_throw_negativearraysizeexception();
3775 da = builtin_newarray_double(len);
3777 return (jdoubleArray) NewLocalRef(env, (jobject) da);
3781 /* Get<PrimitiveType>ArrayElements *********************************************
3783 A family of functions that returns the body of the primitive array.
3785 *******************************************************************************/
3787 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3790 STATISTICS(jniinvokation());
3793 *isCopy = JNI_FALSE;
3799 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3801 STATISTICS(jniinvokation());
3804 *isCopy = JNI_FALSE;
3810 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3812 STATISTICS(jniinvokation());
3815 *isCopy = JNI_FALSE;
3821 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3823 STATISTICS(jniinvokation());
3826 *isCopy = JNI_FALSE;
3832 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3834 STATISTICS(jniinvokation());
3837 *isCopy = JNI_FALSE;
3843 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3845 STATISTICS(jniinvokation());
3848 *isCopy = JNI_FALSE;
3854 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3856 STATISTICS(jniinvokation());
3859 *isCopy = JNI_FALSE;
3865 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3868 STATISTICS(jniinvokation());
3871 *isCopy = JNI_FALSE;
3877 /* Release<PrimitiveType>ArrayElements *****************************************
3879 A family of functions that informs the VM that the native code no
3880 longer needs access to elems. The elems argument is a pointer
3881 derived from array using the corresponding
3882 Get<PrimitiveType>ArrayElements() function. If necessary, this
3883 function copies back all changes made to elems to the original
3886 *******************************************************************************/
3888 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3889 jboolean *elems, jint mode)
3891 STATISTICS(jniinvokation());
3893 if (elems != array->data) {
3896 MCOPY(array->data, elems, jboolean, array->header.size);
3899 MCOPY(array->data, elems, jboolean, array->header.size);
3900 /* XXX TWISTI how should it be freed? */
3903 /* XXX TWISTI how should it be freed? */
3910 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
3913 STATISTICS(jniinvokation());
3915 if (elems != array->data) {
3918 MCOPY(array->data, elems, jboolean, array->header.size);
3921 MCOPY(array->data, elems, jboolean, array->header.size);
3922 /* XXX TWISTI how should it be freed? */
3925 /* XXX TWISTI how should it be freed? */
3932 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
3935 STATISTICS(jniinvokation());
3937 if (elems != array->data) {
3940 MCOPY(array->data, elems, jboolean, array->header.size);
3943 MCOPY(array->data, elems, jboolean, array->header.size);
3944 /* XXX TWISTI how should it be freed? */
3947 /* XXX TWISTI how should it be freed? */
3954 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
3957 STATISTICS(jniinvokation());
3959 if (elems != array->data) {
3962 MCOPY(array->data, elems, jboolean, array->header.size);
3965 MCOPY(array->data, elems, jboolean, array->header.size);
3966 /* XXX TWISTI how should it be freed? */
3969 /* XXX TWISTI how should it be freed? */
3976 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
3979 STATISTICS(jniinvokation());
3981 if (elems != array->data) {
3984 MCOPY(array->data, elems, jboolean, array->header.size);
3987 MCOPY(array->data, elems, jboolean, array->header.size);
3988 /* XXX TWISTI how should it be freed? */
3991 /* XXX TWISTI how should it be freed? */
3998 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
4001 STATISTICS(jniinvokation());
4003 if (elems != array->data) {
4006 MCOPY(array->data, elems, jboolean, array->header.size);
4009 MCOPY(array->data, elems, jboolean, array->header.size);
4010 /* XXX TWISTI how should it be freed? */
4013 /* XXX TWISTI how should it be freed? */
4020 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
4023 STATISTICS(jniinvokation());
4025 if (elems != array->data) {
4028 MCOPY(array->data, elems, jboolean, array->header.size);
4031 MCOPY(array->data, elems, jboolean, array->header.size);
4032 /* XXX TWISTI how should it be freed? */
4035 /* XXX TWISTI how should it be freed? */
4042 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
4043 jdouble *elems, jint mode)
4045 STATISTICS(jniinvokation());
4047 if (elems != array->data) {
4050 MCOPY(array->data, elems, jboolean, array->header.size);
4053 MCOPY(array->data, elems, jboolean, array->header.size);
4054 /* XXX TWISTI how should it be freed? */
4057 /* XXX TWISTI how should it be freed? */
4064 /* Get<PrimitiveType>ArrayRegion **********************************************
4066 A family of functions that copies a region of a primitive array
4069 *******************************************************************************/
4071 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
4072 jsize len, jboolean *buf)
4074 STATISTICS(jniinvokation());
4076 if (start < 0 || len < 0 || start + len > array->header.size)
4077 exceptions_throw_arrayindexoutofboundsexception();
4079 MCOPY(buf, &array->data[start], jboolean, len);
4083 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
4086 STATISTICS(jniinvokation());
4088 if (start < 0 || len < 0 || start + len > array->header.size)
4089 exceptions_throw_arrayindexoutofboundsexception();
4091 MCOPY(buf, &array->data[start], jbyte, len);
4095 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
4098 STATISTICS(jniinvokation());
4100 if (start < 0 || len < 0 || start + len > array->header.size)
4101 exceptions_throw_arrayindexoutofboundsexception();
4103 MCOPY(buf, &array->data[start], jchar, len);
4107 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
4108 jsize len, jshort *buf)
4110 STATISTICS(jniinvokation());
4112 if (start < 0 || len < 0 || start + len > array->header.size)
4113 exceptions_throw_arrayindexoutofboundsexception();
4115 MCOPY(buf, &array->data[start], jshort, len);
4119 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
4122 STATISTICS(jniinvokation());
4124 if (start < 0 || len < 0 || start + len > array->header.size)
4125 exceptions_throw_arrayindexoutofboundsexception();
4127 MCOPY(buf, &array->data[start], jint, len);
4131 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
4134 STATISTICS(jniinvokation());
4136 if (start < 0 || len < 0 || start + len > array->header.size)
4137 exceptions_throw_arrayindexoutofboundsexception();
4139 MCOPY(buf, &array->data[start], jlong, len);
4143 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
4144 jsize len, jfloat *buf)
4146 STATISTICS(jniinvokation());
4148 if (start < 0 || len < 0 || start + len > array->header.size)
4149 exceptions_throw_arrayindexoutofboundsexception();
4151 MCOPY(buf, &array->data[start], jfloat, len);
4155 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
4156 jsize len, jdouble *buf)
4158 STATISTICS(jniinvokation());
4160 if (start < 0 || len < 0 || start+len>array->header.size)
4161 exceptions_throw_arrayindexoutofboundsexception();
4163 MCOPY(buf, &array->data[start], jdouble, len);
4167 /* Set<PrimitiveType>ArrayRegion **********************************************
4169 A family of functions that copies back a region of a primitive
4170 array from a buffer.
4172 *******************************************************************************/
4174 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
4175 jsize len, jboolean *buf)
4177 STATISTICS(jniinvokation());
4179 if (start < 0 || len < 0 || start + len > array->header.size)
4180 exceptions_throw_arrayindexoutofboundsexception();
4182 MCOPY(&array->data[start], buf, jboolean, len);
4186 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
4189 STATISTICS(jniinvokation());
4191 if (start < 0 || len < 0 || start + len > array->header.size)
4192 exceptions_throw_arrayindexoutofboundsexception();
4194 MCOPY(&array->data[start], buf, jbyte, len);
4198 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
4201 STATISTICS(jniinvokation());
4203 if (start < 0 || len < 0 || start + len > array->header.size)
4204 exceptions_throw_arrayindexoutofboundsexception();
4206 MCOPY(&array->data[start], buf, jchar, len);
4210 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
4211 jsize len, jshort *buf)
4213 STATISTICS(jniinvokation());
4215 if (start < 0 || len < 0 || start + len > array->header.size)
4216 exceptions_throw_arrayindexoutofboundsexception();
4218 MCOPY(&array->data[start], buf, jshort, len);
4222 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
4225 STATISTICS(jniinvokation());
4227 if (start < 0 || len < 0 || start + len > array->header.size)
4228 exceptions_throw_arrayindexoutofboundsexception();
4230 MCOPY(&array->data[start], buf, jint, len);
4234 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
4237 STATISTICS(jniinvokation());
4239 if (start < 0 || len < 0 || start + len > array->header.size)
4240 exceptions_throw_arrayindexoutofboundsexception();
4242 MCOPY(&array->data[start], buf, jlong, len);
4246 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
4247 jsize len, jfloat *buf)
4249 STATISTICS(jniinvokation());
4251 if (start < 0 || len < 0 || start + len > array->header.size)
4252 exceptions_throw_arrayindexoutofboundsexception();
4254 MCOPY(&array->data[start], buf, jfloat, len);
4258 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
4259 jsize len, jdouble *buf)
4261 STATISTICS(jniinvokation());
4263 if (start < 0 || len < 0 || start + len > array->header.size)
4264 exceptions_throw_arrayindexoutofboundsexception();
4266 MCOPY(&array->data[start], buf, jdouble, len);
4270 /* Registering Native Methods *************************************************/
4272 /* RegisterNatives *************************************************************
4274 Registers native methods with the class specified by the clazz
4275 argument. The methods parameter specifies an array of
4276 JNINativeMethod structures that contain the names, signatures, and
4277 function pointers of the native methods. The nMethods parameter
4278 specifies the number of native methods in the array.
4280 *******************************************************************************/
4282 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
4285 STATISTICS(jniinvokation());
4287 log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
4293 /* UnregisterNatives ***********************************************************
4295 Unregisters native methods of a class. The class goes back to the
4296 state before it was linked or registered with its native method
4299 This function should not be used in normal native code. Instead, it
4300 provides special programs a way to reload and relink native
4303 *******************************************************************************/
4305 jint UnregisterNatives(JNIEnv *env, jclass clazz)
4307 STATISTICS(jniinvokation());
4309 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
4311 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
4317 /* Monitor Operations *********************************************************/
4319 /* MonitorEnter ****************************************************************
4321 Enters the monitor associated with the underlying Java object
4324 *******************************************************************************/
4326 jint MonitorEnter(JNIEnv *env, jobject obj)
4328 STATISTICS(jniinvokation());
4331 exceptions_throw_nullpointerexception();
4335 #if defined(USE_THREADS)
4336 builtin_monitorenter(obj);
4343 /* MonitorExit *****************************************************************
4345 The current thread must be the owner of the monitor associated with
4346 the underlying Java object referred to by obj. The thread
4347 decrements the counter indicating the number of times it has
4348 entered this monitor. If the value of the counter becomes zero, the
4349 current thread releases the monitor.
4351 *******************************************************************************/
4353 jint MonitorExit(JNIEnv *env, jobject obj)
4355 STATISTICS(jniinvokation());
4358 exceptions_throw_nullpointerexception();
4362 #if defined(USE_THREADS)
4363 builtin_monitorexit(obj);
4370 /* JavaVM Interface ***********************************************************/
4372 /* GetJavaVM *******************************************************************
4374 Returns the Java VM interface (used in the Invocation API)
4375 associated with the current thread. The result is placed at the
4376 location pointed to by the second argument, vm.
4378 *******************************************************************************/
4380 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
4382 STATISTICS(jniinvokation());
4390 void GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
4392 STATISTICS(jniinvokation());
4394 log_text("JNI-Call: GetStringRegion: IMPLEMENT ME!");
4398 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
4400 STATISTICS(jniinvokation());
4402 log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
4406 /* GetPrimitiveArrayCritical ***************************************************
4408 Obtain a direct pointer to array elements.
4410 *******************************************************************************/
4412 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
4417 ba = (java_bytearray *) array;
4419 /* do the same as Kaffe does */
4421 bp = GetByteArrayElements(env, ba, isCopy);
4427 /* ReleasePrimitiveArrayCritical ***********************************************
4429 No specific documentation.
4431 *******************************************************************************/
4433 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
4436 STATISTICS(jniinvokation());
4438 /* do the same as Kaffe does */
4440 ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
4444 /* GetStringCritical ***********************************************************
4446 The semantics of these two functions are similar to the existing
4447 Get/ReleaseStringChars functions.
4449 *******************************************************************************/
4451 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
4453 STATISTICS(jniinvokation());
4455 return GetStringChars(env, string, isCopy);
4459 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
4461 STATISTICS(jniinvokation());
4463 ReleaseStringChars(env, string, cstring);
4467 jweak NewWeakGlobalRef(JNIEnv* env, jobject obj)
4469 STATISTICS(jniinvokation());
4471 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
4477 void DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
4479 STATISTICS(jniinvokation());
4481 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
4485 /* NewGlobalRef ****************************************************************
4487 Creates a new global reference to the object referred to by the obj
4490 *******************************************************************************/
4492 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4494 java_objectheader *o;
4495 java_lang_Integer *refcount;
4496 java_objectheader *newval;
4498 STATISTICS(jniinvokation());
4500 #if defined(USE_THREADS)
4501 builtin_monitorenter(*global_ref_table);
4504 ASM_CALLJAVAFUNCTION_ADR(o, getmid, *global_ref_table, lobj, NULL, NULL);
4506 refcount = (java_lang_Integer *) o;
4508 if (refcount == NULL) {
4509 newval = native_new_and_init_int(class_java_lang_Integer, 1);
4511 if (newval == NULL) {
4512 #if defined(USE_THREADS)
4513 builtin_monitorexit(*global_ref_table);
4518 ASM_CALLJAVAFUNCTION(putmid, *global_ref_table, lobj, newval, NULL);
4521 /* we can access the object itself, as we are in a
4522 synchronized section */
4527 #if defined(USE_THREADS)
4528 builtin_monitorexit(*global_ref_table);
4535 /* DeleteGlobalRef *************************************************************
4537 Deletes the global reference pointed to by globalRef.
4539 *******************************************************************************/
4541 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
4543 java_objectheader *o;
4544 java_lang_Integer *refcount;
4547 STATISTICS(jniinvokation());
4549 #if defined(USE_THREADS)
4550 builtin_monitorenter(*global_ref_table);
4553 ASM_CALLJAVAFUNCTION_ADR(o, getmid, *global_ref_table, globalRef, NULL,
4556 refcount = (java_lang_Integer *) o;
4558 if (refcount == NULL) {
4559 log_text("JNI-DeleteGlobalRef: unable to find global reference");
4563 /* we can access the object itself, as we are in a synchronized
4566 val = refcount->value - 1;
4569 ASM_CALLJAVAFUNCTION(removemid, *global_ref_table, refcount, NULL,
4573 /* we do not create a new object, but set the new value into
4576 refcount->value = val;
4579 #if defined(USE_THREADS)
4580 builtin_monitorexit(*global_ref_table);
4585 /* ExceptionCheck **************************************************************
4587 Returns JNI_TRUE when there is a pending exception; otherwise,
4590 *******************************************************************************/
4592 jboolean ExceptionCheck(JNIEnv *env)
4594 STATISTICS(jniinvokation());
4596 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
4600 /* New JNI 1.4 functions ******************************************************/
4602 /* NewDirectByteBuffer *********************************************************
4604 Allocates and returns a direct java.nio.ByteBuffer referring to the
4605 block of memory starting at the memory address address and
4606 extending capacity bytes.
4608 *******************************************************************************/
4610 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
4612 java_objectheader *nbuf;
4613 #if SIZEOF_VOID_P == 8
4614 gnu_classpath_Pointer64 *paddress;
4616 gnu_classpath_Pointer32 *paddress;
4619 STATISTICS(jniinvokation());
4621 /* alocate a gnu.classpath.Pointer{32,64} object */
4623 #if SIZEOF_VOID_P == 8
4624 if (!(paddress = (gnu_classpath_Pointer64 *)
4625 builtin_new(class_gnu_classpath_Pointer64)))
4627 if (!(paddress = (gnu_classpath_Pointer32 *)
4628 builtin_new(class_gnu_classpath_Pointer32)))
4632 /* fill gnu.classpath.Pointer{32,64} with address */
4634 paddress->data = (ptrint) address;
4636 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
4638 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
4639 dbbirw_init, NULL, paddress,
4640 (jint) capacity, (jint) capacity, (jint) 0);
4642 /* add local reference and return the value */
4644 return NewLocalRef(env, nbuf);
4648 /* GetDirectBufferAddress ******************************************************
4650 Fetches and returns the starting address of the memory region
4651 referenced by the given direct java.nio.Buffer.
4653 *******************************************************************************/
4655 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
4657 java_nio_DirectByteBufferImpl *nbuf;
4658 #if SIZEOF_VOID_P == 8
4659 gnu_classpath_Pointer64 *address;
4661 gnu_classpath_Pointer32 *address;
4664 STATISTICS(jniinvokation());
4666 if (!builtin_instanceof(buf, class_java_nio_Buffer))
4669 nbuf = (java_nio_DirectByteBufferImpl *) buf;
4671 #if SIZEOF_VOID_P == 8
4672 address = (gnu_classpath_Pointer64 *) nbuf->address;
4674 address = (gnu_classpath_Pointer32 *) nbuf->address;
4677 return (void *) address->data;
4681 /* GetDirectBufferCapacity *****************************************************
4683 Fetches and returns the capacity in bytes of the memory region
4684 referenced by the given direct java.nio.Buffer.
4686 *******************************************************************************/
4688 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
4690 java_nio_Buffer *nbuf;
4692 STATISTICS(jniinvokation());
4694 if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
4697 nbuf = (java_nio_Buffer *) buf;
4699 return (jlong) nbuf->cap;
4703 jint DestroyJavaVM(JavaVM *vm)
4705 STATISTICS(jniinvokation());
4707 log_text("JNI-Call: DestroyJavaVM: IMPLEMENT ME!");
4713 /* AttachCurrentThread *********************************************************
4715 Attaches the current thread to a Java VM. Returns a JNI interface
4716 pointer in the JNIEnv argument.
4718 Trying to attach a thread that is already attached is a no-op.
4720 A native thread cannot be attached simultaneously to two Java VMs.
4722 When a thread is attached to the VM, the context class loader is
4723 the bootstrap loader.
4725 *******************************************************************************/
4727 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
4729 STATISTICS(jniinvokation());
4731 log_text("JNI-Call: AttachCurrentThread: IMPLEMENT ME!");
4733 #if !defined(HAVE___THREAD)
4734 /* cacao_thread_attach();*/
4736 #error "No idea how to implement that. Perhaps Stefan knows"
4745 jint DetachCurrentThread(JavaVM *vm)
4747 STATISTICS(jniinvokation());
4749 log_text("JNI-Call: DetachCurrentThread: IMPLEMENT ME!");
4755 /* GetEnv **********************************************************************
4757 If the current thread is not attached to the VM, sets *env to NULL,
4758 and returns JNI_EDETACHED. If the specified version is not
4759 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
4760 sets *env to the appropriate interface, and returns JNI_OK.
4762 *******************************************************************************/
4764 jint GetEnv(JavaVM *vm, void **env, jint version)
4766 STATISTICS(jniinvokation());
4768 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4769 if (thread_getself() == NULL) {
4772 return JNI_EDETACHED;
4776 if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
4777 (version == JNI_VERSION_1_4)) {
4783 #if defined(ENABLE_JVMTI)
4784 if (version == JVMTI_VERSION_1_0) {
4785 *env = (void *) new_jvmtienv();
4794 return JNI_EVERSION;
4799 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4801 STATISTICS(jniinvokation());
4803 log_text("JNI-Call: AttachCurrentThreadAsDaemon: IMPLEMENT ME!");
4809 /* JNI invocation table *******************************************************/
4811 const struct JNIInvokeInterface JNI_JavaVMTable = {
4817 AttachCurrentThread,
4818 DetachCurrentThread,
4820 AttachCurrentThreadAsDaemon
4824 /* JNI function table *********************************************************/
4826 struct JNINativeInterface JNI_JNIEnvTable = {
4835 &FromReflectedMethod,
4836 &FromReflectedField,
4856 &EnsureLocalCapacity,
4872 &CallBooleanMethodV,
4873 &CallBooleanMethodA,
4899 &CallNonvirtualObjectMethod,
4900 &CallNonvirtualObjectMethodV,
4901 &CallNonvirtualObjectMethodA,
4902 &CallNonvirtualBooleanMethod,
4903 &CallNonvirtualBooleanMethodV,
4904 &CallNonvirtualBooleanMethodA,
4905 &CallNonvirtualByteMethod,
4906 &CallNonvirtualByteMethodV,
4907 &CallNonvirtualByteMethodA,
4908 &CallNonvirtualCharMethod,
4909 &CallNonvirtualCharMethodV,
4910 &CallNonvirtualCharMethodA,
4911 &CallNonvirtualShortMethod,
4912 &CallNonvirtualShortMethodV,
4913 &CallNonvirtualShortMethodA,
4914 &CallNonvirtualIntMethod,
4915 &CallNonvirtualIntMethodV,
4916 &CallNonvirtualIntMethodA,
4917 &CallNonvirtualLongMethod,
4918 &CallNonvirtualLongMethodV,
4919 &CallNonvirtualLongMethodA,
4920 &CallNonvirtualFloatMethod,
4921 &CallNonvirtualFloatMethodV,
4922 &CallNonvirtualFloatMethodA,
4923 &CallNonvirtualDoubleMethod,
4924 &CallNonvirtualDoubleMethodV,
4925 &CallNonvirtualDoubleMethodA,
4926 &CallNonvirtualVoidMethod,
4927 &CallNonvirtualVoidMethodV,
4928 &CallNonvirtualVoidMethodA,
4953 &CallStaticObjectMethod,
4954 &CallStaticObjectMethodV,
4955 &CallStaticObjectMethodA,
4956 &CallStaticBooleanMethod,
4957 &CallStaticBooleanMethodV,
4958 &CallStaticBooleanMethodA,
4959 &CallStaticByteMethod,
4960 &CallStaticByteMethodV,
4961 &CallStaticByteMethodA,
4962 &CallStaticCharMethod,
4963 &CallStaticCharMethodV,
4964 &CallStaticCharMethodA,
4965 &CallStaticShortMethod,
4966 &CallStaticShortMethodV,
4967 &CallStaticShortMethodA,
4968 &CallStaticIntMethod,
4969 &CallStaticIntMethodV,
4970 &CallStaticIntMethodA,
4971 &CallStaticLongMethod,
4972 &CallStaticLongMethodV,
4973 &CallStaticLongMethodA,
4974 &CallStaticFloatMethod,
4975 &CallStaticFloatMethodV,
4976 &CallStaticFloatMethodA,
4977 &CallStaticDoubleMethod,
4978 &CallStaticDoubleMethodV,
4979 &CallStaticDoubleMethodA,
4980 &CallStaticVoidMethod,
4981 &CallStaticVoidMethodV,
4982 &CallStaticVoidMethodA,
4986 &GetStaticObjectField,
4987 &GetStaticBooleanField,
4988 &GetStaticByteField,
4989 &GetStaticCharField,
4990 &GetStaticShortField,
4992 &GetStaticLongField,
4993 &GetStaticFloatField,
4994 &GetStaticDoubleField,
4995 &SetStaticObjectField,
4996 &SetStaticBooleanField,
4997 &SetStaticByteField,
4998 &SetStaticCharField,
4999 &SetStaticShortField,
5001 &SetStaticLongField,
5002 &SetStaticFloatField,
5003 &SetStaticDoubleField,
5008 &ReleaseStringChars,
5011 &GetStringUTFLength,
5013 &ReleaseStringUTFChars,
5018 &GetObjectArrayElement,
5019 &SetObjectArrayElement,
5030 &GetBooleanArrayElements,
5031 &GetByteArrayElements,
5032 &GetCharArrayElements,
5033 &GetShortArrayElements,
5034 &GetIntArrayElements,
5035 &GetLongArrayElements,
5036 &GetFloatArrayElements,
5037 &GetDoubleArrayElements,
5039 &ReleaseBooleanArrayElements,
5040 &ReleaseByteArrayElements,
5041 &ReleaseCharArrayElements,
5042 &ReleaseShortArrayElements,
5043 &ReleaseIntArrayElements,
5044 &ReleaseLongArrayElements,
5045 &ReleaseFloatArrayElements,
5046 &ReleaseDoubleArrayElements,
5048 &GetBooleanArrayRegion,
5049 &GetByteArrayRegion,
5050 &GetCharArrayRegion,
5051 &GetShortArrayRegion,
5053 &GetLongArrayRegion,
5054 &GetFloatArrayRegion,
5055 &GetDoubleArrayRegion,
5056 &SetBooleanArrayRegion,
5057 &SetByteArrayRegion,
5058 &SetCharArrayRegion,
5059 &SetShortArrayRegion,
5061 &SetLongArrayRegion,
5062 &SetFloatArrayRegion,
5063 &SetDoubleArrayRegion,
5073 /* new JNI 1.2 functions */
5076 &GetStringUTFRegion,
5078 &GetPrimitiveArrayCritical,
5079 &ReleasePrimitiveArrayCritical,
5082 &ReleaseStringCritical,
5085 &DeleteWeakGlobalRef,
5089 /* new JNI 1.4 functions */
5091 &NewDirectByteBuffer,
5092 &GetDirectBufferAddress,
5093 &GetDirectBufferCapacity
5097 /* Invocation API Functions ***************************************************/
5099 /* JNI_GetDefaultJavaVMInitArgs ************************************************
5101 Returns a default configuration for the Java VM.
5103 *******************************************************************************/
5105 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
5107 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
5109 /* GNU classpath currently supports JNI 1.2 */
5111 _vm_args->version = JNI_VERSION_1_2;
5117 /* JNI_GetCreatedJavaVMs *******************************************************
5119 Returns all Java VMs that have been created. Pointers to VMs are written in
5120 the buffer vmBuf in the order they are created. At most bufLen number of
5121 entries will be written. The total number of created VMs is returned in
5124 *******************************************************************************/
5126 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
5128 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
5134 /* JNI_CreateJavaVM ************************************************************
5136 Loads and initializes a Java VM. The current thread becomes the main thread.
5137 Sets the env argument to the JNI interface pointer of the main thread.
5139 *******************************************************************************/
5141 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
5143 const struct JNIInvokeInterface *vm;
5144 struct JNINativeInterface *env;
5146 vm = &JNI_JavaVMTable;
5147 env = &JNI_JNIEnvTable;
5149 *p_vm = (JavaVM *) vm;
5150 *p_env = (JNIEnv *) env;
5157 * These are local overrides for various environment variables in Emacs.
5158 * Please do not remove this and leave it at the end of the file, where
5159 * Emacs will automagically detect them.
5160 * ---------------------------------------------------------------------
5163 * indent-tabs-mode: t