1 /* src/native/jni.c - implementation of the Java Native Interface functions
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Rainhard Grafl
30 Changes: Joseph Wenninger
35 $Id: jni.c 4522 2006-02-14 20:27:06Z edwin $
48 #include "mm/memory.h"
49 #include "native/jni.h"
50 #include "native/native.h"
52 #include "native/include/gnu_classpath_Pointer.h"
54 #if SIZEOF_VOID_P == 8
55 # include "native/include/gnu_classpath_Pointer64.h"
57 # include "native/include/gnu_classpath_Pointer32.h"
60 #include "native/include/java_lang_Object.h"
61 #include "native/include/java_lang_Byte.h"
62 #include "native/include/java_lang_Character.h"
63 #include "native/include/java_lang_Short.h"
64 #include "native/include/java_lang_Integer.h"
65 #include "native/include/java_lang_Boolean.h"
66 #include "native/include/java_lang_Long.h"
67 #include "native/include/java_lang_Float.h"
68 #include "native/include/java_lang_Double.h"
69 #include "native/include/java_lang_Throwable.h"
70 #include "native/include/java_lang_reflect_Method.h"
71 #include "native/include/java_lang_reflect_Constructor.h"
72 #include "native/include/java_lang_reflect_Field.h"
74 #include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
75 #include "native/include/java_lang_VMClass.h"
76 #include "native/include/java_lang_VMClassLoader.h"
77 #include "native/include/java_nio_Buffer.h"
78 #include "native/include/java_nio_DirectByteBufferImpl.h"
80 #if defined(ENABLE_JVMTI)
81 # include "native/jvmti/jvmti.h"
84 #if defined(USE_THREADS)
85 # if defined(NATIVE_THREADS)
86 # include "threads/native/threads.h"
88 # include "threads/green/threads.h"
92 #include "toolbox/logging.h"
93 #include "vm/builtin.h"
94 #include "vm/exceptions.h"
95 #include "vm/global.h"
96 #include "vm/initialize.h"
97 #include "vm/loader.h"
98 #include "vm/options.h"
99 #include "vm/resolve.h"
100 #include "vm/statistics.h"
101 #include "vm/stringlocal.h"
102 #include "vm/jit/asmpart.h"
103 #include "vm/jit/jit.h"
104 #include "vm/statistics.h"
107 /* XXX TWISTI hack: define it extern so they can be found in this file */
109 extern const struct JNIInvokeInterface JNI_JavaVMTable;
110 extern struct JNINativeInterface JNI_JNIEnvTable;
112 /* pointers to VM and the environment needed by GetJavaVM and GetEnv */
114 static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
115 void *ptr_env = (void*) &JNI_JNIEnvTable;
118 #define PTR_TO_ITEM(ptr) ((u8)(size_t)(ptr))
120 /* global variables ***********************************************************/
122 /* global reference table *****************************************************/
124 static java_objectheader **global_ref_table;
126 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
127 static classinfo *ihmclass = NULL;
128 static methodinfo *putmid = NULL;
129 static methodinfo *getmid = NULL;
130 static methodinfo *removemid = NULL;
133 /* direct buffer stuff ********************************************************/
135 static classinfo *class_java_nio_Buffer;
136 static classinfo *class_java_nio_DirectByteBufferImpl;
137 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
138 #if SIZEOF_VOID_P == 8
139 static classinfo *class_gnu_classpath_Pointer64;
141 static classinfo *class_gnu_classpath_Pointer32;
144 static methodinfo *dbbirw_init;
147 /* local reference table ******************************************************/
149 #if !defined(USE_THREADS)
150 localref_table *_no_threads_localref_table;
154 /* accessing instance fields macros *******************************************/
156 #define SET_FIELD(obj,type,var,value) \
157 *((type *) ((ptrint) (obj) + (ptrint) (var)->offset)) = (type) (value)
159 #define GET_FIELD(obj,type,var) \
160 *((type *) ((ptrint) (obj) + (ptrint) (var)->offset))
163 /* some forward declarations **************************************************/
165 jobject NewLocalRef(JNIEnv *env, jobject ref);
168 /* jni_init ********************************************************************
170 Initialize the JNI subsystem.
172 *******************************************************************************/
176 /* initalize global reference table */
179 load_class_bootstrap(utf_new_char("java/util/IdentityHashMap"))))
182 global_ref_table = GCNEW(jobject);
184 if (!(*global_ref_table = native_new_and_init(ihmclass)))
187 if (!(getmid = class_resolvemethod(ihmclass, utf_get,
188 utf_java_lang_Object__java_lang_Object)))
191 if (!(putmid = class_resolvemethod(ihmclass, utf_put,
192 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))))
196 class_resolvemethod(ihmclass, utf_remove,
197 utf_java_lang_Object__java_lang_Object)))
201 /* direct buffer stuff */
203 if (!(class_java_nio_Buffer =
204 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
205 !link_class(class_java_nio_Buffer))
208 if (!(class_java_nio_DirectByteBufferImpl =
209 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
210 !link_class(class_java_nio_DirectByteBufferImpl))
213 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
214 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
215 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
219 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
221 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
224 #if SIZEOF_VOID_P == 8
225 if (!(class_gnu_classpath_Pointer64 =
226 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
227 !link_class(class_gnu_classpath_Pointer64))
230 if (!(class_gnu_classpath_Pointer32 =
231 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
232 !link_class(class_gnu_classpath_Pointer32))
240 static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
241 jni_callblock blk[], va_list data,
244 typedesc *paramtypes;
247 paramtypes = descr->paramtypes;
249 /* if method is non-static fill first block and skip `this' pointer */
254 /* the `this' pointer */
255 blk[0].itemtype = TYPE_ADR;
256 blk[0].item = PTR_TO_ITEM(obj);
262 for (; i < descr->paramcount; i++, paramtypes++) {
263 switch (paramtypes->decltype) {
264 /* primitive types */
265 case PRIMITIVETYPE_BYTE:
266 case PRIMITIVETYPE_CHAR:
267 case PRIMITIVETYPE_SHORT:
268 case PRIMITIVETYPE_BOOLEAN:
269 blk[i].itemtype = TYPE_INT;
270 blk[i].item = (s8) va_arg(data, s4);
273 case PRIMITIVETYPE_INT:
274 blk[i].itemtype = TYPE_INT;
275 blk[i].item = (s8) va_arg(data, s4);
278 case PRIMITIVETYPE_LONG:
279 blk[i].itemtype = TYPE_LNG;
280 blk[i].item = (s8) va_arg(data, s8);
283 case PRIMITIVETYPE_FLOAT:
284 blk[i].itemtype = TYPE_FLT;
285 #if defined(__ALPHA__)
286 /* this keeps the assembler function much simpler */
288 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
290 *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
294 case PRIMITIVETYPE_DOUBLE:
295 blk[i].itemtype = TYPE_DBL;
296 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
300 blk[i].itemtype = TYPE_ADR;
301 blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
306 /* The standard doesn't say anything about return value checking,
307 but it appears to be useful. */
309 if (rettype != descr->returntype.decltype)
310 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
314 /* XXX it could be considered if we should do typechecking here in the future */
316 static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
318 java_objectarray *params)
322 typedesc *paramtypes;
327 paramcount = descr->paramcount;
328 paramtypes = descr->paramtypes;
330 /* if method is non-static fill first block and skip `this' pointer */
336 blk[0].itemtype = TYPE_ADR;
337 blk[0].item = PTR_TO_ITEM(obj);
344 for (j = 0; j < paramcount; i++, j++, paramtypes++) {
345 switch (paramtypes->type) {
346 /* primitive types */
351 param = params->data[j];
355 /* internally used data type */
356 blk[i].itemtype = paramtypes->type;
358 /* convert the value according to its declared type */
360 c = param->vftbl->class;
362 switch (paramtypes->decltype) {
363 case PRIMITIVETYPE_BOOLEAN:
364 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
365 blk[i].item = (s8) ((java_lang_Boolean *) param)->value;
370 case PRIMITIVETYPE_BYTE:
371 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
372 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
377 case PRIMITIVETYPE_CHAR:
378 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
379 blk[i].item = (s8) ((java_lang_Character *) param)->value;
384 case PRIMITIVETYPE_SHORT:
385 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
386 blk[i].item = (s8) ((java_lang_Short *) param)->value;
387 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
388 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
393 case PRIMITIVETYPE_INT:
394 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
395 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
396 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
397 blk[i].item = (s8) ((java_lang_Short *) param)->value;
398 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
399 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
404 case PRIMITIVETYPE_LONG:
405 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
406 blk[i].item = (s8) ((java_lang_Long *) param)->value;
407 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
408 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
409 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
410 blk[i].item = (s8) ((java_lang_Short *) param)->value;
411 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
412 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
417 case PRIMITIVETYPE_FLOAT:
418 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
419 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
424 case PRIMITIVETYPE_DOUBLE:
425 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
426 *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Double *) param)->value;
427 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
428 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
435 } /* end declared type switch */
439 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
442 if (params->data[j] != 0) {
443 if (paramtypes->arraydim > 0) {
444 if (!builtin_arrayinstanceof(params->data[j], c))
448 if (!builtin_instanceof(params->data[j], c))
452 blk[i].itemtype = TYPE_ADR;
453 blk[i].item = PTR_TO_ITEM(params->data[j]);
458 } /* end param type switch */
460 } /* end param loop */
463 /* *rettype = descr->returntype.decltype; */
468 exceptions_throw_illegalargumentexception();
473 /* _Jv_jni_CallObjectMethod ****************************************************
475 Internal function to call Java Object methods.
477 *******************************************************************************/
479 static java_objectheader *_Jv_jni_CallObjectMethod(java_objectheader *o,
481 methodinfo *m, va_list ap)
486 java_objectheader *ret;
489 STATISTICS(jniinvokation());
492 exceptions_throw_nullpointerexception();
496 /* Class initialization is done by the JIT compiler. This is ok
497 since a static method always belongs to the declaring class. */
499 if (m->flags & ACC_STATIC) {
500 /* For static methods we reset the object. */
505 /* for convenience */
510 /* For instance methods we make a virtual function table lookup. */
512 resm = method_vftbl_lookup(vftbl, m);
515 /* mark start of dump memory area */
517 dumpsize = dump_size();
519 paramcount = resm->parseddesc->paramcount;
521 blk = DMNEW(jni_callblock, paramcount);
523 fill_callblock_from_vargs(o, resm->parseddesc, blk, ap, TYPE_ADR);
525 STATISTICS(jnicallXmethodnvokation());
527 ASM_CALLJAVAFUNCTION2_ADR(ret, resm, paramcount,
528 paramcount * sizeof(jni_callblock),
531 /* release dump area */
533 dump_release(dumpsize);
539 /* _Jv_jni_CallIntMethod *******************************************************
541 Internal function to call Java integer class methods (boolean,
542 byte, char, short, int).
544 *******************************************************************************/
546 static jint _Jv_jni_CallIntMethod(java_objectheader *o, vftbl_t *vftbl,
547 methodinfo *m, va_list ap, s4 type)
555 STATISTICS(jniinvokation());
558 exceptions_throw_nullpointerexception();
562 /* Class initialization is done by the JIT compiler. This is ok
563 since a static method always belongs to the declaring class. */
565 if (m->flags & ACC_STATIC) {
566 /* For static methods we reset the object. */
571 /* for convenience */
576 /* For instance methods we make a virtual function table lookup. */
578 resm = method_vftbl_lookup(vftbl, m);
581 /* mark start of dump memory area */
583 dumpsize = dump_size();
585 paramcount = resm->parseddesc->paramcount;
587 blk = DMNEW(jni_callblock, paramcount);
589 fill_callblock_from_vargs(o, resm->parseddesc, blk, ap, type);
591 STATISTICS(jnicallXmethodnvokation());
593 ASM_CALLJAVAFUNCTION2_INT(ret, resm, paramcount,
594 paramcount * sizeof(jni_callblock),
597 /* release dump area */
599 dump_release(dumpsize);
605 /* _Jv_jni_CallLongMethod ******************************************************
607 Internal function to call Java long methods.
609 *******************************************************************************/
611 static jlong _Jv_jni_CallLongMethod(java_objectheader *o, vftbl_t *vftbl,
612 methodinfo *m, va_list ap)
620 STATISTICS(jniinvokation());
623 exceptions_throw_nullpointerexception();
627 /* Class initialization is done by the JIT compiler. This is ok
628 since a static method always belongs to the declaring class. */
630 if (m->flags & ACC_STATIC) {
631 /* For static methods we reset the object. */
636 /* for convenience */
641 /* For instance methods we make a virtual function table lookup. */
643 resm = method_vftbl_lookup(vftbl, m);
646 /* mark start of dump memory area */
648 dumpsize = dump_size();
650 paramcount = resm->parseddesc->paramcount;
652 blk = DMNEW(jni_callblock, paramcount);
654 fill_callblock_from_vargs(o, resm->parseddesc, blk, ap, PRIMITIVETYPE_LONG);
656 STATISTICS(jnicallXmethodnvokation());
658 ASM_CALLJAVAFUNCTION2_LONG(ret, resm, paramcount,
659 paramcount * sizeof(jni_callblock),
662 /* release dump area */
664 dump_release(dumpsize);
670 /* _Jv_jni_CallFloatMethod *****************************************************
672 Internal function to call Java float methods.
674 *******************************************************************************/
676 static jfloat _Jv_jni_CallFloatMethod(java_objectheader *o, vftbl_t *vftbl,
677 methodinfo *m, va_list ap)
685 /* Class initialization is done by the JIT compiler. This is ok
686 since a static method always belongs to the declaring class. */
688 if (m->flags & ACC_STATIC) {
689 /* For static methods we reset the object. */
694 /* for convenience */
699 /* For instance methods we make a virtual function table lookup. */
701 resm = method_vftbl_lookup(vftbl, m);
704 /* mark start of dump memory area */
706 dumpsize = dump_size();
708 paramcount = resm->parseddesc->paramcount;
710 blk = DMNEW(jni_callblock, paramcount);
712 fill_callblock_from_vargs(o, resm->parseddesc, blk, ap,
713 PRIMITIVETYPE_FLOAT);
715 STATISTICS(jnicallXmethodnvokation());
717 ASM_CALLJAVAFUNCTION2_FLOAT(ret, resm, paramcount,
718 paramcount * sizeof(jni_callblock),
721 /* release dump area */
723 dump_release(dumpsize);
729 /* _Jv_jni_CallDoubleMethod ****************************************************
731 Internal function to call Java double methods.
733 *******************************************************************************/
735 static jdouble _Jv_jni_CallDoubleMethod(java_objectheader *o, vftbl_t *vftbl,
736 methodinfo *m, va_list ap)
744 /* Class initialization is done by the JIT compiler. This is ok
745 since a static method always belongs to the declaring class. */
747 if (m->flags & ACC_STATIC) {
748 /* For static methods we reset the object. */
753 /* for convenience */
758 /* For instance methods we make a virtual function table lookup. */
760 resm = method_vftbl_lookup(vftbl, m);
763 /* mark start of dump memory area */
765 dumpsize = dump_size();
767 paramcount = resm->parseddesc->paramcount;
769 blk = DMNEW(jni_callblock, paramcount);
771 fill_callblock_from_vargs(o, resm->parseddesc, blk, ap,
772 PRIMITIVETYPE_DOUBLE);
774 STATISTICS(jnicallXmethodnvokation());
776 ASM_CALLJAVAFUNCTION2_DOUBLE(ret, resm, paramcount,
777 paramcount * sizeof(jni_callblock),
780 /* release dump area */
782 dump_release(dumpsize);
788 /* _Jv_jni_CallVoidMethod ******************************************************
790 Internal function to call Java void methods.
792 *******************************************************************************/
794 static void _Jv_jni_CallVoidMethod(java_objectheader *o, vftbl_t *vftbl,
795 methodinfo *m, va_list ap)
803 exceptions_throw_nullpointerexception();
807 /* Class initialization is done by the JIT compiler. This is ok
808 since a static method always belongs to the declaring class. */
810 if (m->flags & ACC_STATIC) {
811 /* For static methods we reset the object. */
816 /* for convenience */
821 /* For instance methods we make a virtual function table lookup. */
823 resm = method_vftbl_lookup(vftbl, m);
826 /* mark start of dump memory area */
828 dumpsize = dump_size();
830 paramcount = resm->parseddesc->paramcount;
832 blk = DMNEW(jni_callblock, paramcount);
834 fill_callblock_from_vargs(o, resm->parseddesc, blk, ap, TYPE_VOID);
836 STATISTICS(jnicallXmethodnvokation());
838 ASM_CALLJAVAFUNCTION2(resm, paramcount,
839 paramcount * sizeof(jni_callblock),
842 /* release dump area */
844 dump_release(dumpsize);
848 /* _Jv_jni_invokeNative ********************************************************
850 Invoke a method on the given object with the given arguments.
852 For instance methods OBJ must be != NULL and the method is looked up
853 in the vftbl of the object.
855 For static methods, OBJ is ignored.
857 *******************************************************************************/
859 jobject *_Jv_jni_invokeNative(methodinfo *m, jobject obj,
860 java_objectarray *params)
864 java_objectheader *o;
869 exceptions_throw_nullpointerexception();
873 argcount = m->parseddesc->paramcount;
874 paramcount = argcount;
876 /* if method is non-static, remove the `this' pointer */
878 if (!(m->flags & ACC_STATIC))
881 /* For instance methods the object has to be an instance of the */
882 /* class the method belongs to. For static methods the obj parameter */
885 if (!(m->flags & ACC_STATIC) && obj &&
886 (!builtin_instanceof((java_objectheader *) obj, m->class)))
889 new_exception_message(string_java_lang_IllegalArgumentException,
890 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
894 /* check if we got the right number of arguments */
896 if (((params == NULL) && (paramcount != 0)) ||
897 (params && (params->header.size != paramcount)))
900 new_exception(string_java_lang_IllegalArgumentException);
904 /* for instance methods we need an object */
906 if (!(m->flags & ACC_STATIC) && !obj)
909 new_exception_message(string_java_lang_NullPointerException,
910 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
914 /* for static methods, zero obj to make subsequent code simpler */
915 if (m->flags & ACC_STATIC)
919 /* for instance methods we must do a vftbl lookup */
920 resm = method_vftbl_lookup(obj->vftbl, m);
923 /* for static methods, just for convenience */
927 blk = MNEW(jni_callblock, argcount);
929 if (!fill_callblock_from_objectarray(obj, resm->parseddesc, blk,
933 switch (resm->parseddesc->returntype.decltype) {
935 ASM_CALLJAVAFUNCTION2(resm, argcount,
936 argcount * sizeof(jni_callblock),
942 case PRIMITIVETYPE_BOOLEAN: {
944 java_lang_Boolean *bo;
946 ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
947 argcount * sizeof(jni_callblock),
950 o = builtin_new(class_java_lang_Boolean);
952 /* setting the value of the object direct */
954 bo = (java_lang_Boolean *) o;
959 case PRIMITIVETYPE_BYTE: {
963 ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
964 argcount * sizeof(jni_callblock),
967 o = builtin_new(class_java_lang_Byte);
969 /* setting the value of the object direct */
971 bo = (java_lang_Byte *) o;
976 case PRIMITIVETYPE_CHAR: {
978 java_lang_Character *co;
980 ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
981 argcount * sizeof(jni_callblock),
984 o = builtin_new(class_java_lang_Character);
986 /* setting the value of the object direct */
988 co = (java_lang_Character *) o;
993 case PRIMITIVETYPE_SHORT: {
997 ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
998 argcount * sizeof(jni_callblock),
1001 o = builtin_new(class_java_lang_Short);
1003 /* setting the value of the object direct */
1005 so = (java_lang_Short *) o;
1010 case PRIMITIVETYPE_INT: {
1012 java_lang_Integer *io;
1014 ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
1015 argcount * sizeof(jni_callblock),
1018 o = builtin_new(class_java_lang_Integer);
1020 /* setting the value of the object direct */
1022 io = (java_lang_Integer *) o;
1027 case PRIMITIVETYPE_LONG: {
1031 ASM_CALLJAVAFUNCTION2_LONG(l, resm, argcount,
1032 argcount * sizeof(jni_callblock),
1035 o = builtin_new(class_java_lang_Long);
1037 /* setting the value of the object direct */
1039 lo = (java_lang_Long *) o;
1044 case PRIMITIVETYPE_FLOAT: {
1046 java_lang_Float *fo;
1048 ASM_CALLJAVAFUNCTION2_FLOAT(f, resm, argcount,
1049 argcount * sizeof(jni_callblock),
1052 o = builtin_new(class_java_lang_Float);
1054 /* setting the value of the object direct */
1056 fo = (java_lang_Float *) o;
1061 case PRIMITIVETYPE_DOUBLE: {
1063 java_lang_Double *_do;
1065 ASM_CALLJAVAFUNCTION2_DOUBLE(d, resm, argcount,
1066 argcount * sizeof(jni_callblock),
1069 o = builtin_new(class_java_lang_Double);
1071 /* setting the value of the object direct */
1073 _do = (java_lang_Double *) o;
1079 ASM_CALLJAVAFUNCTION2_ADR(o, resm, argcount,
1080 argcount * sizeof(jni_callblock),
1085 /* if this happens the exception has already been set by
1086 fill_callblock_from_objectarray */
1088 MFREE(blk, jni_callblock, argcount);
1090 return (jobject *) 0;
1093 MFREE(blk, jni_callblock, argcount);
1095 if (*exceptionptr) {
1096 java_objectheader *cause;
1098 cause = *exceptionptr;
1100 /* clear exception pointer, we are calling JIT code again */
1102 *exceptionptr = NULL;
1105 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
1106 (java_lang_Throwable *) cause);
1109 return (jobject *) o;
1113 /* GetVersion ******************************************************************
1115 Returns the major version number in the higher 16 bits and the
1116 minor version number in the lower 16 bits.
1118 *******************************************************************************/
1120 jint GetVersion(JNIEnv *env)
1122 STATISTICS(jniinvokation());
1124 /* we support JNI 1.4 */
1126 return JNI_VERSION_1_4;
1130 /* Class Operations ***********************************************************/
1132 /* DefineClass *****************************************************************
1134 Loads a class from a buffer of raw class data. The buffer
1135 containing the raw class data is not referenced by the VM after the
1136 DefineClass call returns, and it may be discarded if desired.
1138 *******************************************************************************/
1140 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
1141 const jbyte *buf, jsize bufLen)
1143 java_lang_ClassLoader *cl;
1144 java_lang_String *s;
1148 STATISTICS(jniinvokation());
1150 cl = (java_lang_ClassLoader *) loader;
1151 s = javastring_new_char(name);
1152 ba = (java_bytearray *) buf;
1154 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
1157 return (jclass) NewLocalRef(env, (jobject) c);
1161 /* FindClass *******************************************************************
1163 This function loads a locally-defined class. It searches the
1164 directories and zip files specified by the CLASSPATH environment
1165 variable for the class with the specified name.
1167 *******************************************************************************/
1169 jclass FindClass(JNIEnv *env, const char *name)
1173 java_objectheader *cl;
1175 STATISTICS(jniinvokation());
1177 u = utf_new_char_classname((char *) name);
1179 /* Check stacktrace for classloader, if one found use it,
1180 otherwise use the system classloader. */
1182 #if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__)
1183 /* these JITs support stacktraces, and so does the interpreter */
1185 cl = stacktrace_getCurrentClassLoader();
1187 # if defined(ENABLE_INTRP)
1188 /* the interpreter supports stacktraces, even if the JIT does not */
1191 cl = stacktrace_getCurrentClassLoader();
1197 if (!(c = load_class_from_classloader(u, cl)))
1203 return (jclass) NewLocalRef(env, (jobject) c);
1207 /* FromReflectedMethod *********************************************************
1209 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1210 object to a method ID.
1212 *******************************************************************************/
1214 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
1220 STATISTICS(jniinvokation());
1225 if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
1226 java_lang_reflect_Method *rm;
1228 rm = (java_lang_reflect_Method *) method;
1229 c = (classinfo *) (rm->declaringClass);
1232 } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
1233 java_lang_reflect_Constructor *rc;
1235 rc = (java_lang_reflect_Constructor *) method;
1236 c = (classinfo *) (rc->clazz);
1242 if ((slot < 0) || (slot >= c->methodscount)) {
1243 /* this usually means a severe internal cacao error or somebody
1244 tempered around with the reflected method */
1245 log_text("error illegal slot for method in class(FromReflectedMethod)");
1249 mi = &(c->methods[slot]);
1255 /* GetSuperclass ***************************************************************
1257 If clazz represents any class other than the class Object, then
1258 this function returns the object that represents the superclass of
1259 the class specified by clazz.
1261 *******************************************************************************/
1263 jclass GetSuperclass(JNIEnv *env, jclass sub)
1267 STATISTICS(jniinvokation());
1269 c = ((classinfo *) sub)->super.cls;
1274 return (jclass) NewLocalRef(env, (jobject) c);
1278 /* IsAssignableFrom ************************************************************
1280 Determines whether an object of sub can be safely cast to sup.
1282 *******************************************************************************/
1284 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1286 STATISTICS(jniinvokation());
1288 return Java_java_lang_VMClass_isAssignableFrom(env,
1290 (java_lang_Class *) sup,
1291 (java_lang_Class *) sub);
1295 /* Throw ***********************************************************************
1297 Causes a java.lang.Throwable object to be thrown.
1299 *******************************************************************************/
1301 jint Throw(JNIEnv *env, jthrowable obj)
1303 STATISTICS(jniinvokation());
1305 *exceptionptr = (java_objectheader *) obj;
1311 /* ThrowNew ********************************************************************
1313 Constructs an exception object from the specified class with the
1314 message specified by message and causes that exception to be
1317 *******************************************************************************/
1319 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1321 java_lang_Throwable *o;
1322 java_lang_String *s;
1324 STATISTICS(jniinvokation());
1326 s = (java_lang_String *) javastring_new_char(msg);
1328 /* instantiate exception object */
1330 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
1336 *exceptionptr = (java_objectheader *) o;
1342 /* ExceptionOccurred ***********************************************************
1344 Determines if an exception is being thrown. The exception stays
1345 being thrown until either the native code calls ExceptionClear(),
1346 or the Java code handles the exception.
1348 *******************************************************************************/
1350 jthrowable ExceptionOccurred(JNIEnv *env)
1352 java_objectheader *e;
1354 STATISTICS(jniinvokation());
1358 return NewLocalRef(env, (jthrowable) e);
1362 /* ExceptionDescribe ***********************************************************
1364 Prints an exception and a backtrace of the stack to a system
1365 error-reporting channel, such as stderr. This is a convenience
1366 routine provided for debugging.
1368 *******************************************************************************/
1370 void ExceptionDescribe(JNIEnv *env)
1372 java_objectheader *e;
1375 STATISTICS(jniinvokation());
1380 /* clear exception, because we are calling jit code again */
1382 *exceptionptr = NULL;
1384 /* get printStackTrace method from exception class */
1386 m = class_resolveclassmethod(e->vftbl->class,
1387 utf_printStackTrace,
1393 /* XXX what should we do? */
1396 /* print the stacktrace */
1398 ASM_CALLJAVAFUNCTION(m, e, NULL, NULL, NULL);
1403 /* ExceptionClear **************************************************************
1405 Clears any exception that is currently being thrown. If no
1406 exception is currently being thrown, this routine has no effect.
1408 *******************************************************************************/
1410 void ExceptionClear(JNIEnv *env)
1412 STATISTICS(jniinvokation());
1414 *exceptionptr = NULL;
1418 /* FatalError ******************************************************************
1420 Raises a fatal error and does not expect the VM to recover. This
1421 function does not return.
1423 *******************************************************************************/
1425 void FatalError(JNIEnv *env, const char *msg)
1427 STATISTICS(jniinvokation());
1429 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
1433 /* PushLocalFrame **************************************************************
1435 Creates a new local reference frame, in which at least a given
1436 number of local references can be created.
1438 *******************************************************************************/
1440 jint PushLocalFrame(JNIEnv* env, jint capacity)
1442 STATISTICS(jniinvokation());
1444 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
1451 /* PopLocalFrame ***************************************************************
1453 Pops off the current local reference frame, frees all the local
1454 references, and returns a local reference in the previous local
1455 reference frame for the given result object.
1457 *******************************************************************************/
1459 jobject PopLocalFrame(JNIEnv* env, jobject result)
1461 STATISTICS(jniinvokation());
1463 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
1467 /* add local reference and return the value */
1469 return NewLocalRef(env, NULL);
1473 /* DeleteLocalRef **************************************************************
1475 Deletes the local reference pointed to by localRef.
1477 *******************************************************************************/
1479 void DeleteLocalRef(JNIEnv *env, jobject localRef)
1481 java_objectheader *o;
1482 localref_table *lrt;
1485 STATISTICS(jniinvokation());
1487 o = (java_objectheader *) localRef;
1489 /* get local reference table (thread specific) */
1491 lrt = LOCALREFTABLE;
1493 /* remove the reference */
1495 for (i = 0; i < lrt->capacity; i++) {
1496 if (lrt->refs[i] == o) {
1497 lrt->refs[i] = NULL;
1504 /* this should not happen */
1506 /* if (opt_checkjni) */
1507 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1508 log_text("JNI-DeleteLocalRef: Bad global or local ref passed to JNI");
1512 /* IsSameObject ****************************************************************
1514 Tests whether two references refer to the same Java object.
1516 *******************************************************************************/
1518 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1520 STATISTICS(jniinvokation());
1529 /* NewLocalRef *****************************************************************
1531 Creates a new local reference that refers to the same object as ref.
1533 *******************************************************************************/
1535 jobject NewLocalRef(JNIEnv *env, jobject ref)
1537 localref_table *lrt;
1540 STATISTICS(jniinvokation());
1545 /* get local reference table (thread specific) */
1547 lrt = LOCALREFTABLE;
1549 /* check if we have space for the requested reference */
1551 if (lrt->used == lrt->capacity) {
1552 /* throw_cacao_exception_exit(string_java_lang_InternalError, */
1553 /* "Too many local references"); */
1554 fprintf(stderr, "Too many local references");
1558 /* insert the reference */
1560 for (i = 0; i < lrt->capacity; i++) {
1561 if (lrt->refs[i] == NULL) {
1562 lrt->refs[i] = (java_objectheader *) ref;
1569 /* should not happen, just to be sure */
1573 /* keep compiler happy */
1579 /* EnsureLocalCapacity *********************************************************
1581 Ensures that at least a given number of local references can be
1582 created in the current thread
1584 *******************************************************************************/
1586 jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
1588 localref_table *lrt;
1590 STATISTICS(jniinvokation());
1592 /* get local reference table (thread specific) */
1594 lrt = LOCALREFTABLE;
1596 /* check if capacity elements are available in the local references table */
1598 if ((lrt->used + capacity) > lrt->capacity) {
1599 *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
1607 /* AllocObject *****************************************************************
1609 Allocates a new Java object without invoking any of the
1610 constructors for the object. Returns a reference to the object.
1612 *******************************************************************************/
1614 jobject AllocObject(JNIEnv *env, jclass clazz)
1616 java_objectheader *o;
1618 STATISTICS(jniinvokation());
1620 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1622 new_exception_utfmessage(string_java_lang_InstantiationException,
1627 o = builtin_new(clazz);
1629 return NewLocalRef(env, o);
1633 /* NewObject *******************************************************************
1635 Programmers place all arguments that are to be passed to the
1636 constructor immediately following the methodID
1637 argument. NewObject() accepts these arguments and passes them to
1638 the Java method that the programmer wishes to invoke.
1640 *******************************************************************************/
1642 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1644 java_objectheader *o;
1647 STATISTICS(jniinvokation());
1651 o = builtin_new(clazz);
1656 /* call constructor */
1658 va_start(ap, methodID);
1659 _Jv_jni_CallVoidMethod(o, o->vftbl, methodID, ap);
1662 return NewLocalRef(env, o);
1666 /* NewObjectV ******************************************************************
1668 Programmers place all arguments that are to be passed to the
1669 constructor in an args argument of type va_list that immediately
1670 follows the methodID argument. NewObjectV() accepts these
1671 arguments, and, in turn, passes them to the Java method that the
1672 programmer wishes to invoke.
1674 *******************************************************************************/
1676 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1678 java_objectheader *o;
1680 STATISTICS(jniinvokation());
1684 o = builtin_new(clazz);
1689 /* call constructor */
1691 _Jv_jni_CallVoidMethod(o, o->vftbl, methodID, args);
1693 return NewLocalRef(env, o);
1697 /***********************************************************************************
1699 Constructs a new Java object
1700 arguments that are to be passed to the constructor are placed in
1701 args array of jvalues
1703 ***********************************************************************************/
1705 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1707 STATISTICS(jniinvokation());
1709 log_text("JNI-Call: NewObjectA: IMPLEMENT ME!");
1711 return NewLocalRef(env, NULL);
1715 /* GetObjectClass **************************************************************
1717 Returns the class of an object.
1719 *******************************************************************************/
1721 jclass GetObjectClass(JNIEnv *env, jobject obj)
1725 STATISTICS(jniinvokation());
1727 if (!obj || !obj->vftbl)
1730 c = obj->vftbl->class;
1732 return (jclass) NewLocalRef(env, (jobject) c);
1736 /* IsInstanceOf ****************************************************************
1738 Tests whether an object is an instance of a class.
1740 *******************************************************************************/
1742 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1744 STATISTICS(jniinvokation());
1746 return Java_java_lang_VMClass_isInstance(env,
1748 (java_lang_Class *) clazz,
1749 (java_lang_Object *) obj);
1753 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1755 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1757 java_lang_reflect_Field *f;
1759 jfieldID fid; /* the JNI-fieldid of the wrapping object */
1761 STATISTICS(jniinvokation());
1763 /*log_text("JNI-Call: FromReflectedField");*/
1765 f=(java_lang_reflect_Field *)field;
1767 c=(classinfo*)(f->declaringClass);
1768 if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1769 /*this usually means a severe internal cacao error or somebody
1770 tempered around with the reflected method*/
1771 log_text("error illegal slot for field in class(FromReflectedField)");
1774 fid=&(c->fields[f->slot]);
1779 /* ToReflectedMethod ***********************************************************
1781 Converts a method ID derived from cls to an instance of the
1782 java.lang.reflect.Method class or to an instance of the
1783 java.lang.reflect.Constructor class.
1785 *******************************************************************************/
1787 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1789 STATISTICS(jniinvokation());
1791 log_text("JNI-Call: ToReflectedMethod: IMPLEMENT ME!");
1797 /* ToReflectedField ************************************************************
1799 Converts a field ID derived from cls to an instance of the
1800 java.lang.reflect.Field class.
1802 *******************************************************************************/
1804 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1807 STATISTICS(jniinvokation());
1809 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1815 /* Calling Instance Methods ***************************************************/
1817 /* GetMethodID *****************************************************************
1819 Returns the method ID for an instance (nonstatic) method of a class
1820 or interface. The method may be defined in one of the clazz's
1821 superclasses and inherited by clazz. The method is determined by
1822 its name and signature.
1824 GetMethodID() causes an uninitialized class to be initialized.
1826 *******************************************************************************/
1828 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1836 STATISTICS(jniinvokation());
1838 c = (classinfo *) clazz;
1843 if (!(c->state & CLASS_INITIALIZED))
1844 if (!initialize_class(c))
1847 /* try to get the method of the class or one of it's superclasses */
1849 uname = utf_new_char((char *) name);
1850 udesc = utf_new_char((char *) sig);
1852 m = class_resolvemethod(clazz, uname, udesc);
1854 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1855 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1864 /* JNI-functions for calling instance methods *********************************/
1866 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1868 java_objectheader* ret;
1871 va_start(ap, methodID);
1872 ret = _Jv_jni_CallObjectMethod(obj, obj->vftbl, methodID, ap);
1875 return NewLocalRef(env, ret);
1879 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1881 java_objectheader* ret;
1883 ret = _Jv_jni_CallObjectMethod(obj, obj->vftbl, methodID, args);
1885 return NewLocalRef(env, ret);
1889 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1891 log_text("JNI-Call: CallObjectMethodA: IMPLEMENT ME!");
1893 return NewLocalRef(env, NULL);
1897 jboolean CallBooleanMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1902 va_start(ap, methodID);
1903 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, ap,
1904 PRIMITIVETYPE_BOOLEAN);
1911 jboolean CallBooleanMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1915 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, args,
1916 PRIMITIVETYPE_BOOLEAN);
1922 jboolean CallBooleanMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1924 log_text("JNI-Call: CallBooleanMethodA");
1930 jbyte CallByteMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1935 va_start(ap, methodID);
1936 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, ap,
1937 PRIMITIVETYPE_BYTE);
1944 jbyte CallByteMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1948 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, args,
1949 PRIMITIVETYPE_BYTE);
1955 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1957 log_text("JNI-Call: CallByteMethodA: IMPLEMENT ME!");
1963 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1968 va_start(ap, methodID);
1969 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, ap,
1970 PRIMITIVETYPE_CHAR);
1977 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1981 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, args,
1982 PRIMITIVETYPE_CHAR);
1988 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1990 log_text("JNI-Call: CallCharMethodA: IMPLEMENT ME!");
1996 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2001 va_start(ap, methodID);
2002 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, ap,
2003 PRIMITIVETYPE_SHORT);
2010 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2014 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, args,
2015 PRIMITIVETYPE_SHORT);
2021 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2023 log_text("JNI-Call: CallShortMethodA: IMPLEMENT ME!");
2030 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2035 va_start(ap, methodID);
2036 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, ap,
2044 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2048 ret = _Jv_jni_CallIntMethod(obj, obj->vftbl, methodID, args,
2055 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2057 log_text("JNI-Call: CallIntMethodA: IMPLEMENT ME!");
2064 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2069 va_start(ap, methodID);
2070 ret = _Jv_jni_CallLongMethod(obj, obj->vftbl, methodID, ap);
2077 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2081 ret = _Jv_jni_CallLongMethod(obj, obj->vftbl, methodID, args);
2087 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2089 log_text("JNI-Call: CallLongMethodA: IMPLEMENT ME!");
2096 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2101 va_start(ap, methodID);
2102 ret = _Jv_jni_CallFloatMethod(obj, obj->vftbl, methodID, ap);
2109 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2113 ret = _Jv_jni_CallFloatMethod(obj, obj->vftbl, methodID, args);
2119 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2121 log_text("JNI-Call: CallFloatMethodA: IMPLEMENT ME!");
2128 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2133 va_start(ap, methodID);
2134 ret = _Jv_jni_CallDoubleMethod(obj, obj->vftbl, methodID, ap);
2141 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2145 ret = _Jv_jni_CallDoubleMethod(obj, obj->vftbl, methodID, args);
2151 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2153 log_text("JNI-Call: CallDoubleMethodA: IMPLEMENT ME!");
2160 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2164 va_start(ap, methodID);
2165 _Jv_jni_CallVoidMethod(obj, obj->vftbl, methodID, ap);
2170 void CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2172 _Jv_jni_CallVoidMethod(obj, obj->vftbl, methodID, args);
2176 void CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2178 log_text("JNI-Call: CallVoidMethodA: IMPLEMENT ME!");
2183 jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2185 java_objectheader *ret;
2188 va_start(ap, methodID);
2189 ret = _Jv_jni_CallObjectMethod(obj, clazz->vftbl, methodID, ap);
2192 return NewLocalRef(env, ret);
2196 jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2198 java_objectheader* ret;
2200 ret = _Jv_jni_CallObjectMethod(obj, clazz->vftbl, methodID, args);
2202 return NewLocalRef(env, ret);
2206 jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2208 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2210 return NewLocalRef(env, NULL);
2215 jboolean CallNonvirtualBooleanMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2220 va_start(ap, methodID);
2221 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, ap,
2222 PRIMITIVETYPE_BOOLEAN);
2230 jboolean CallNonvirtualBooleanMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2234 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, args,
2235 PRIMITIVETYPE_BOOLEAN);
2241 jboolean CallNonvirtualBooleanMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2243 log_text("JNI-Call: CallNonvirtualBooleanMethodA: IMPLEMENT ME!");
2249 jbyte CallNonvirtualByteMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2254 va_start(ap, methodID);
2255 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, ap,
2256 PRIMITIVETYPE_BYTE);
2263 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2267 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, args,
2268 PRIMITIVETYPE_BYTE);
2274 jbyte CallNonvirtualByteMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2276 log_text("JNI-Call: CallNonvirtualByteMethodA: IMPLEMENT ME!");
2283 jchar CallNonvirtualCharMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2288 va_start(ap, methodID);
2289 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, ap,
2290 PRIMITIVETYPE_CHAR);
2297 jchar CallNonvirtualCharMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2301 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, args,
2302 PRIMITIVETYPE_CHAR);
2308 jchar CallNonvirtualCharMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2310 log_text("JNI-Call: CallNonvirtualCharMethodA: IMPLEMENT ME!");
2317 jshort CallNonvirtualShortMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2322 va_start(ap, methodID);
2323 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, ap,
2324 PRIMITIVETYPE_SHORT);
2331 jshort CallNonvirtualShortMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2335 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, args,
2336 PRIMITIVETYPE_SHORT);
2342 jshort CallNonvirtualShortMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2344 log_text("JNI-Call: CallNonvirtualShortMethodA: IMPLEMENT ME!");
2351 jint CallNonvirtualIntMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2356 va_start(ap, methodID);
2357 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, ap,
2365 jint CallNonvirtualIntMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2369 ret = _Jv_jni_CallIntMethod(obj, clazz->vftbl, methodID, args,
2376 jint CallNonvirtualIntMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2378 log_text("JNI-Call: CallNonvirtualIntMethodA: IMPLEMENT ME!");
2385 jlong CallNonvirtualLongMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2390 va_start(ap, methodID);
2391 ret = _Jv_jni_CallLongMethod(obj, clazz->vftbl, methodID, ap);
2398 jlong CallNonvirtualLongMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2402 ret = _Jv_jni_CallLongMethod(obj, clazz->vftbl, methodID, args);
2408 jlong CallNonvirtualLongMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2410 log_text("JNI-Call: CallNonvirtualLongMethodA: IMPLEMENT ME!");
2417 jfloat CallNonvirtualFloatMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2422 va_start(ap, methodID);
2423 ret = _Jv_jni_CallFloatMethod(obj, clazz->vftbl, methodID, ap);
2430 jfloat CallNonvirtualFloatMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2434 ret = _Jv_jni_CallFloatMethod(obj, clazz->vftbl, methodID, args);
2440 jfloat CallNonvirtualFloatMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2442 STATISTICS(jniinvokation());
2444 log_text("JNI-Call: CallNonvirtualFloatMethodA: IMPLEMENT ME!");
2451 jdouble CallNonvirtualDoubleMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2456 va_start(ap, methodID);
2457 ret = _Jv_jni_CallDoubleMethod(obj, clazz->vftbl, methodID, ap);
2464 jdouble CallNonvirtualDoubleMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2468 ret = _Jv_jni_CallDoubleMethod(obj, clazz->vftbl, methodID, args);
2474 jdouble CallNonvirtualDoubleMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2476 log_text("JNI-Call: CallNonvirtualDoubleMethodA: IMPLEMENT ME!");
2483 void CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2487 va_start(ap, methodID);
2488 _Jv_jni_CallVoidMethod(obj, clazz->vftbl, methodID, ap);
2493 void CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2495 _Jv_jni_CallVoidMethod(obj, clazz->vftbl, methodID, args);
2499 void CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
2501 log_text("JNI-Call: CallNonvirtualVoidMethodA: IMPLEMENT ME!");
2505 /* Accessing Fields of Objects ************************************************/
2507 /* GetFieldID ******************************************************************
2509 Returns the field ID for an instance (nonstatic) field of a
2510 class. The field is specified by its name and signature. The
2511 Get<type>Field and Set<type>Field families of accessor functions
2512 use field IDs to retrieve object fields.
2514 *******************************************************************************/
2516 jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2523 STATISTICS(jniinvokation());
2525 uname = utf_new_char((char *) name);
2526 udesc = utf_new_char((char *) sig);
2528 f = class_findfield(clazz, uname, udesc);
2531 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2537 /* Get<type>Field Routines *****************************************************
2539 This family of accessor routines returns the value of an instance
2540 (nonstatic) field of an object. The field to access is specified by
2541 a field ID obtained by calling GetFieldID().
2543 *******************************************************************************/
2545 jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2547 java_objectheader *o;
2549 STATISTICS(jniinvokation());
2551 o = GET_FIELD(obj, java_objectheader*, fieldID);
2553 return NewLocalRef(env, o);
2557 jboolean GetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID)
2561 STATISTICS(jniinvokation());
2563 i = GET_FIELD(obj, s4, fieldID);
2565 return (jboolean) i;
2569 jbyte GetByteField(JNIEnv *env, jobject obj, jfieldID fieldID)
2573 STATISTICS(jniinvokation());
2575 i = GET_FIELD(obj, s4, fieldID);
2581 jchar GetCharField(JNIEnv *env, jobject obj, jfieldID fieldID)
2585 STATISTICS(jniinvokation());
2587 i = GET_FIELD(obj, s4, fieldID);
2593 jshort GetShortField(JNIEnv *env, jobject obj, jfieldID fieldID)
2597 STATISTICS(jniinvokation());
2599 i = GET_FIELD(obj, s4, fieldID);
2605 jint GetIntField(JNIEnv *env, jobject obj, jfieldID fieldID)
2609 STATISTICS(jniinvokation());
2611 i = GET_FIELD(obj, s4, fieldID);
2617 jlong GetLongField(JNIEnv *env, jobject obj, jfieldID fieldID)
2621 STATISTICS(jniinvokation());
2623 l = GET_FIELD(obj, s8, fieldID);
2629 jfloat GetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID)
2633 STATISTICS(jniinvokation());
2635 f = GET_FIELD(obj, float, fieldID);
2641 jdouble GetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID)
2645 STATISTICS(jniinvokation());
2647 d = GET_FIELD(obj, double, fieldID);
2653 /* Set<type>Field Routines *****************************************************
2655 This family of accessor routines sets the value of an instance
2656 (nonstatic) field of an object. The field to access is specified by
2657 a field ID obtained by calling GetFieldID().
2659 *******************************************************************************/
2661 void SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value)
2663 STATISTICS(jniinvokation());
2665 SET_FIELD(obj, java_objectheader*, fieldID, value);
2669 void SetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID, jboolean value)
2671 STATISTICS(jniinvokation());
2673 SET_FIELD(obj, s4, fieldID, value);
2677 void SetByteField(JNIEnv *env, jobject obj, jfieldID fieldID, jbyte value)
2679 STATISTICS(jniinvokation());
2681 SET_FIELD(obj, s4, fieldID, value);
2685 void SetCharField(JNIEnv *env, jobject obj, jfieldID fieldID, jchar value)
2687 STATISTICS(jniinvokation());
2689 SET_FIELD(obj, s4, fieldID, value);
2693 void SetShortField(JNIEnv *env, jobject obj, jfieldID fieldID, jshort value)
2695 STATISTICS(jniinvokation());
2697 SET_FIELD(obj, s4, fieldID, value);
2701 void SetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint value)
2703 STATISTICS(jniinvokation());
2705 SET_FIELD(obj, s4, fieldID, value);
2709 void SetLongField(JNIEnv *env, jobject obj, jfieldID fieldID, jlong value)
2711 STATISTICS(jniinvokation());
2713 SET_FIELD(obj, s8, fieldID, value);
2717 void SetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID, jfloat value)
2719 STATISTICS(jniinvokation());
2721 SET_FIELD(obj, float, fieldID, value);
2725 void SetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID, jdouble value)
2727 STATISTICS(jniinvokation());
2729 SET_FIELD(obj, double, fieldID, value);
2733 /* Calling Static Methods *****************************************************/
2735 /* GetStaticMethodID ***********************************************************
2737 Returns the method ID for a static method of a class. The method is
2738 specified by its name and signature.
2740 GetStaticMethodID() causes an uninitialized class to be
2743 *******************************************************************************/
2745 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2753 STATISTICS(jniinvokation());
2755 c = (classinfo *) clazz;
2760 if (!(c->state & CLASS_INITIALIZED))
2761 if (!initialize_class(c))
2764 /* try to get the static method of the class */
2766 uname = utf_new_char((char *) name);
2767 udesc = utf_new_char((char *) sig);
2769 m = class_resolvemethod(c, uname, udesc);
2771 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2772 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2781 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2783 java_objectheader *ret;
2786 va_start(ap, methodID);
2787 ret = _Jv_jni_CallObjectMethod(NULL, NULL, methodID, ap);
2790 return NewLocalRef(env, ret);
2794 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2796 java_objectheader *ret;
2798 ret = _Jv_jni_CallObjectMethod(NULL, NULL, methodID, args);
2800 return NewLocalRef(env, ret);
2804 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2806 log_text("JNI-Call: CallStaticObjectMethodA: IMPLEMENT ME!");
2808 return NewLocalRef(env, NULL);
2812 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2817 va_start(ap, methodID);
2818 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, ap,
2819 PRIMITIVETYPE_BOOLEAN);
2826 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2830 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, args,
2831 PRIMITIVETYPE_BOOLEAN);
2837 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2839 log_text("JNI-Call: CallStaticBooleanMethodA: IMPLEMENT ME!");
2845 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2850 va_start(ap, methodID);
2851 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, ap, PRIMITIVETYPE_BYTE);
2858 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2862 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, args, PRIMITIVETYPE_BYTE);
2868 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2870 log_text("JNI-Call: CallStaticByteMethodA: IMPLEMENT ME!");
2876 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2881 va_start(ap, methodID);
2882 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, ap, PRIMITIVETYPE_CHAR);
2889 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2893 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, args, PRIMITIVETYPE_CHAR);
2899 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2901 log_text("JNI-Call: CallStaticCharMethodA: IMPLEMENT ME!");
2907 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2912 va_start(ap, methodID);
2913 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, ap, PRIMITIVETYPE_SHORT);
2920 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2924 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, args,
2925 PRIMITIVETYPE_SHORT);
2931 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2933 log_text("JNI-Call: CallStaticShortMethodA: IMPLEMENT ME!");
2939 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2944 va_start(ap, methodID);
2945 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, ap, PRIMITIVETYPE_INT);
2952 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2956 ret = _Jv_jni_CallIntMethod(NULL, NULL, methodID, args, PRIMITIVETYPE_INT);
2962 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2964 log_text("JNI-Call: CallStaticIntMethodA: IMPLEMENT ME!");
2970 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2975 va_start(ap, methodID);
2976 ret = _Jv_jni_CallLongMethod(NULL, NULL, methodID, ap);
2983 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
2988 ret = _Jv_jni_CallLongMethod(NULL, NULL, methodID, args);
2994 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2996 log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!");
3003 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3008 va_start(ap, methodID);
3009 ret = _Jv_jni_CallFloatMethod(NULL, NULL, methodID, ap);
3016 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3020 ret = _Jv_jni_CallFloatMethod(NULL, NULL, methodID, args);
3026 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3028 log_text("JNI-Call: CallStaticFloatMethodA: IMPLEMENT ME!");
3034 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3039 va_start(ap, methodID);
3040 ret = _Jv_jni_CallDoubleMethod(NULL, NULL, methodID, ap);
3047 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3051 ret = _Jv_jni_CallDoubleMethod(NULL, NULL, methodID, args);
3057 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3059 log_text("JNI-Call: CallStaticDoubleMethodA: IMPLEMENT ME!");
3065 void CallStaticVoidMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3069 va_start(ap, methodID);
3070 _Jv_jni_CallVoidMethod(NULL, NULL, methodID, ap);
3075 void CallStaticVoidMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3077 _Jv_jni_CallVoidMethod(NULL, NULL, methodID, args);
3081 void CallStaticVoidMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue * args)
3083 log_text("JNI-Call: CallStaticVoidMethodA: IMPLEMENT ME!");
3087 /* Accessing Static Fields ****************************************************/
3089 /* GetStaticFieldID ************************************************************
3091 Returns the field ID for a static field of a class. The field is
3092 specified by its name and signature. The GetStatic<type>Field and
3093 SetStatic<type>Field families of accessor functions use field IDs
3094 to retrieve static fields.
3096 *******************************************************************************/
3098 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
3102 STATISTICS(jniinvokation());
3104 f = class_findfield(clazz,
3105 utf_new_char((char *) name),
3106 utf_new_char((char *) sig));
3109 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
3115 /* GetStatic<type>Field ********************************************************
3117 This family of accessor routines returns the value of a static
3120 *******************************************************************************/
3122 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3124 STATISTICS(jniinvokation());
3126 if (!(clazz->state & CLASS_INITIALIZED))
3127 if (!initialize_class(clazz))
3130 return NewLocalRef(env, fieldID->value.a);
3134 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3136 STATISTICS(jniinvokation());
3138 if (!(clazz->state & CLASS_INITIALIZED))
3139 if (!initialize_class(clazz))
3142 return fieldID->value.i;
3146 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3148 STATISTICS(jniinvokation());
3150 if (!(clazz->state & CLASS_INITIALIZED))
3151 if (!initialize_class(clazz))
3154 return fieldID->value.i;
3158 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3160 STATISTICS(jniinvokation());
3162 if (!(clazz->state & CLASS_INITIALIZED))
3163 if (!initialize_class(clazz))
3166 return fieldID->value.i;
3170 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3172 STATISTICS(jniinvokation());
3174 if (!(clazz->state & CLASS_INITIALIZED))
3175 if (!initialize_class(clazz))
3178 return fieldID->value.i;
3182 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3184 STATISTICS(jniinvokation());
3186 if (!(clazz->state & CLASS_INITIALIZED))
3187 if (!initialize_class(clazz))
3190 return fieldID->value.i;
3194 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3196 STATISTICS(jniinvokation());
3198 if (!(clazz->state & CLASS_INITIALIZED))
3199 if (!initialize_class(clazz))
3202 return fieldID->value.l;
3206 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3208 STATISTICS(jniinvokation());
3210 if (!(clazz->state & CLASS_INITIALIZED))
3211 if (!initialize_class(clazz))
3214 return fieldID->value.f;
3218 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3220 STATISTICS(jniinvokation());
3222 if (!(clazz->state & CLASS_INITIALIZED))
3223 if (!initialize_class(clazz))
3226 return fieldID->value.d;
3230 /* SetStatic<type>Field *******************************************************
3232 This family of accessor routines sets the value of a static field
3235 *******************************************************************************/
3237 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
3239 STATISTICS(jniinvokation());
3241 if (!(clazz->state & CLASS_INITIALIZED))
3242 if (!initialize_class(clazz))
3245 fieldID->value.a = value;
3249 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
3251 STATISTICS(jniinvokation());
3253 if (!(clazz->state & CLASS_INITIALIZED))
3254 if (!initialize_class(clazz))
3257 fieldID->value.i = value;
3261 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
3263 STATISTICS(jniinvokation());
3265 if (!(clazz->state & CLASS_INITIALIZED))
3266 if (!initialize_class(clazz))
3269 fieldID->value.i = value;
3273 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
3275 STATISTICS(jniinvokation());
3277 if (!(clazz->state & CLASS_INITIALIZED))
3278 if (!initialize_class(clazz))
3281 fieldID->value.i = value;
3285 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
3287 STATISTICS(jniinvokation());
3289 if (!(clazz->state & CLASS_INITIALIZED))
3290 if (!initialize_class(clazz))
3293 fieldID->value.i = value;
3297 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
3299 STATISTICS(jniinvokation());
3301 if (!(clazz->state & CLASS_INITIALIZED))
3302 if (!initialize_class(clazz))
3305 fieldID->value.i = value;
3309 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
3311 STATISTICS(jniinvokation());
3313 if (!(clazz->state & CLASS_INITIALIZED))
3314 if (!initialize_class(clazz))
3317 fieldID->value.l = value;
3321 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
3323 STATISTICS(jniinvokation());
3325 if (!(clazz->state & CLASS_INITIALIZED))
3326 if (!initialize_class(clazz))
3329 fieldID->value.f = value;
3333 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
3335 STATISTICS(jniinvokation());
3337 if (!(clazz->state & CLASS_INITIALIZED))
3338 if (!initialize_class(clazz))
3341 fieldID->value.d = value;
3345 /* String Operations **********************************************************/
3347 /* NewString *******************************************************************
3349 Create new java.lang.String object from an array of Unicode
3352 *******************************************************************************/
3354 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
3356 java_lang_String *s;
3360 STATISTICS(jniinvokation());
3362 s = (java_lang_String *) builtin_new(class_java_lang_String);
3363 a = builtin_newarray_char(len);
3365 /* javastring or characterarray could not be created */
3370 for (i = 0; i < len; i++)
3371 a->data[i] = buf[i];
3377 return (jstring) NewLocalRef(env, (jobject) s);
3381 static jchar emptyStringJ[]={0,0};
3383 /* GetStringLength *************************************************************
3385 Returns the length (the count of Unicode characters) of a Java
3388 *******************************************************************************/
3390 jsize GetStringLength(JNIEnv *env, jstring str)
3392 return ((java_lang_String *) str)->count;
3396 /******************** convertes javastring to u2-array ****************************/
3398 u2 *javastring_tou2(jstring so)
3400 java_lang_String *s;
3405 STATISTICS(jniinvokation());
3407 s = (java_lang_String *) so;
3417 /* allocate memory */
3419 stringbuffer = MNEW(u2, s->count + 1);
3423 for (i = 0; i < s->count; i++)
3424 stringbuffer[i] = a->data[s->offset + i];
3426 /* terminate string */
3428 stringbuffer[i] = '\0';
3430 return stringbuffer;
3434 /* GetStringChars **************************************************************
3436 Returns a pointer to the array of Unicode characters of the
3437 string. This pointer is valid until ReleaseStringchars() is called.
3439 *******************************************************************************/
3441 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
3445 STATISTICS(jniinvokation());
3447 jc = javastring_tou2(str);
3459 return emptyStringJ;
3463 /* ReleaseStringChars **********************************************************
3465 Informs the VM that the native code no longer needs access to
3466 chars. The chars argument is a pointer obtained from string using
3469 *******************************************************************************/
3471 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
3473 STATISTICS(jniinvokation());
3475 if (chars == emptyStringJ)
3478 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
3482 /* NewStringUTF ****************************************************************
3484 Constructs a new java.lang.String object from an array of UTF-8 characters.
3486 *******************************************************************************/
3488 jstring NewStringUTF(JNIEnv *env, const char *bytes)
3490 java_lang_String *s;
3492 STATISTICS(jniinvokation());
3494 s = javastring_new(utf_new_char(bytes));
3496 return (jstring) NewLocalRef(env, (jobject) s);
3500 /****************** returns the utf8 length in bytes of a string *******************/
3502 jsize GetStringUTFLength (JNIEnv *env, jstring string)
3504 java_lang_String *s = (java_lang_String*) string;
3506 STATISTICS(jniinvokation());
3508 return (jsize) u2_utflength(s->value->data, s->count);
3512 /* GetStringUTFChars ***********************************************************
3514 Returns a pointer to an array of UTF-8 characters of the
3515 string. This array is valid until it is released by
3516 ReleaseStringUTFChars().
3518 *******************************************************************************/
3520 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
3524 STATISTICS(jniinvokation());
3532 u = javastring_toutf((java_lang_String *) string, false);
3541 /* ReleaseStringUTFChars *******************************************************
3543 Informs the VM that the native code no longer needs access to
3544 utf. The utf argument is a pointer derived from string using
3545 GetStringUTFChars().
3547 *******************************************************************************/
3549 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
3551 STATISTICS(jniinvokation());
3553 /* XXX we don't release utf chars right now, perhaps that should be done
3554 later. Since there is always one reference the garbage collector will
3559 /* Array Operations ***********************************************************/
3561 /* GetArrayLength **************************************************************
3563 Returns the number of elements in the array.
3565 *******************************************************************************/
3567 jsize GetArrayLength(JNIEnv *env, jarray array)
3569 STATISTICS(jniinvokation());
3575 /* NewObjectArray **************************************************************
3577 Constructs a new array holding objects in class elementClass. All
3578 elements are initially set to initialElement.
3580 *******************************************************************************/
3582 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
3584 java_objectarray *oa;
3587 STATISTICS(jniinvokation());
3590 exceptions_throw_negativearraysizeexception();
3594 oa = builtin_anewarray(length, elementClass);
3599 /* set all elements to initialElement */
3601 for (i = 0; i < length; i++)
3602 oa->data[i] = initialElement;
3604 return (jobjectArray) NewLocalRef(env, (jobject) oa);
3608 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
3612 STATISTICS(jniinvokation());
3614 if (index >= array->header.size) {
3615 exceptions_throw_arrayindexoutofboundsexception();
3619 o = array->data[index];
3621 return NewLocalRef(env, o);
3625 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3627 java_objectarray *oa;
3628 java_objectheader *o;
3630 STATISTICS(jniinvokation());
3632 oa = (java_objectarray *) array;
3633 o = (java_objectheader *) val;
3635 if (index >= array->header.size) {
3636 exceptions_throw_arrayindexoutofboundsexception();
3640 /* check if the class of value is a subclass of the element class
3643 if (!builtin_canstore(oa, o)) {
3644 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3649 array->data[index] = val;
3653 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3655 java_booleanarray *ba;
3657 STATISTICS(jniinvokation());
3660 exceptions_throw_negativearraysizeexception();
3664 ba = builtin_newarray_boolean(len);
3666 return (jbooleanArray) NewLocalRef(env, (jobject) ba);
3670 jbyteArray NewByteArray(JNIEnv *env, jsize len)
3674 STATISTICS(jniinvokation());
3677 exceptions_throw_negativearraysizeexception();
3681 ba = builtin_newarray_byte(len);
3683 return (jbyteArray) NewLocalRef(env, (jobject) ba);
3687 jcharArray NewCharArray(JNIEnv *env, jsize len)
3691 STATISTICS(jniinvokation());
3694 exceptions_throw_negativearraysizeexception();
3698 ca = builtin_newarray_char(len);
3700 return (jcharArray) NewLocalRef(env, (jobject) ca);
3704 jshortArray NewShortArray(JNIEnv *env, jsize len)
3706 java_shortarray *sa;
3708 STATISTICS(jniinvokation());
3711 exceptions_throw_negativearraysizeexception();
3715 sa = builtin_newarray_short(len);
3717 return (jshortArray) NewLocalRef(env, (jobject) sa);
3721 jintArray NewIntArray(JNIEnv *env, jsize len)
3725 STATISTICS(jniinvokation());
3728 exceptions_throw_negativearraysizeexception();
3732 ia = builtin_newarray_int(len);
3734 return (jintArray) NewLocalRef(env, (jobject) ia);
3738 jlongArray NewLongArray(JNIEnv *env, jsize len)
3742 STATISTICS(jniinvokation());
3745 exceptions_throw_negativearraysizeexception();
3749 la = builtin_newarray_long(len);
3751 return (jlongArray) NewLocalRef(env, (jobject) la);
3755 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3757 java_floatarray *fa;
3759 STATISTICS(jniinvokation());
3762 exceptions_throw_negativearraysizeexception();
3766 fa = builtin_newarray_float(len);
3768 return (jfloatArray) NewLocalRef(env, (jobject) fa);
3772 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3774 java_doublearray *da;
3776 STATISTICS(jniinvokation());
3779 exceptions_throw_negativearraysizeexception();
3783 da = builtin_newarray_double(len);
3785 return (jdoubleArray) NewLocalRef(env, (jobject) da);
3789 /* Get<PrimitiveType>ArrayElements *********************************************
3791 A family of functions that returns the body of the primitive array.
3793 *******************************************************************************/
3795 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3798 STATISTICS(jniinvokation());
3801 *isCopy = JNI_FALSE;
3807 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3809 STATISTICS(jniinvokation());
3812 *isCopy = JNI_FALSE;
3818 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3820 STATISTICS(jniinvokation());
3823 *isCopy = JNI_FALSE;
3829 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3831 STATISTICS(jniinvokation());
3834 *isCopy = JNI_FALSE;
3840 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3842 STATISTICS(jniinvokation());
3845 *isCopy = JNI_FALSE;
3851 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3853 STATISTICS(jniinvokation());
3856 *isCopy = JNI_FALSE;
3862 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3864 STATISTICS(jniinvokation());
3867 *isCopy = JNI_FALSE;
3873 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3876 STATISTICS(jniinvokation());
3879 *isCopy = JNI_FALSE;
3885 /* Release<PrimitiveType>ArrayElements *****************************************
3887 A family of functions that informs the VM that the native code no
3888 longer needs access to elems. The elems argument is a pointer
3889 derived from array using the corresponding
3890 Get<PrimitiveType>ArrayElements() function. If necessary, this
3891 function copies back all changes made to elems to the original
3894 *******************************************************************************/
3896 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3897 jboolean *elems, jint mode)
3899 STATISTICS(jniinvokation());
3901 if (elems != array->data) {
3904 MCOPY(array->data, elems, jboolean, array->header.size);
3907 MCOPY(array->data, elems, jboolean, array->header.size);
3908 /* XXX TWISTI how should it be freed? */
3911 /* XXX TWISTI how should it be freed? */
3918 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
3921 STATISTICS(jniinvokation());
3923 if (elems != array->data) {
3926 MCOPY(array->data, elems, jboolean, array->header.size);
3929 MCOPY(array->data, elems, jboolean, array->header.size);
3930 /* XXX TWISTI how should it be freed? */
3933 /* XXX TWISTI how should it be freed? */
3940 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
3943 STATISTICS(jniinvokation());
3945 if (elems != array->data) {
3948 MCOPY(array->data, elems, jboolean, array->header.size);
3951 MCOPY(array->data, elems, jboolean, array->header.size);
3952 /* XXX TWISTI how should it be freed? */
3955 /* XXX TWISTI how should it be freed? */
3962 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
3965 STATISTICS(jniinvokation());
3967 if (elems != array->data) {
3970 MCOPY(array->data, elems, jboolean, array->header.size);
3973 MCOPY(array->data, elems, jboolean, array->header.size);
3974 /* XXX TWISTI how should it be freed? */
3977 /* XXX TWISTI how should it be freed? */
3984 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
3987 STATISTICS(jniinvokation());
3989 if (elems != array->data) {
3992 MCOPY(array->data, elems, jboolean, array->header.size);
3995 MCOPY(array->data, elems, jboolean, array->header.size);
3996 /* XXX TWISTI how should it be freed? */
3999 /* XXX TWISTI how should it be freed? */
4006 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
4009 STATISTICS(jniinvokation());
4011 if (elems != array->data) {
4014 MCOPY(array->data, elems, jboolean, array->header.size);
4017 MCOPY(array->data, elems, jboolean, array->header.size);
4018 /* XXX TWISTI how should it be freed? */
4021 /* XXX TWISTI how should it be freed? */
4028 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
4031 STATISTICS(jniinvokation());
4033 if (elems != array->data) {
4036 MCOPY(array->data, elems, jboolean, array->header.size);
4039 MCOPY(array->data, elems, jboolean, array->header.size);
4040 /* XXX TWISTI how should it be freed? */
4043 /* XXX TWISTI how should it be freed? */
4050 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
4051 jdouble *elems, jint mode)
4053 STATISTICS(jniinvokation());
4055 if (elems != array->data) {
4058 MCOPY(array->data, elems, jboolean, array->header.size);
4061 MCOPY(array->data, elems, jboolean, array->header.size);
4062 /* XXX TWISTI how should it be freed? */
4065 /* XXX TWISTI how should it be freed? */
4072 /* Get<PrimitiveType>ArrayRegion **********************************************
4074 A family of functions that copies a region of a primitive array
4077 *******************************************************************************/
4079 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
4080 jsize len, jboolean *buf)
4082 STATISTICS(jniinvokation());
4084 if (start < 0 || len < 0 || start + len > array->header.size)
4085 exceptions_throw_arrayindexoutofboundsexception();
4087 MCOPY(buf, &array->data[start], jboolean, len);
4091 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
4094 STATISTICS(jniinvokation());
4096 if (start < 0 || len < 0 || start + len > array->header.size)
4097 exceptions_throw_arrayindexoutofboundsexception();
4099 MCOPY(buf, &array->data[start], jbyte, len);
4103 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
4106 STATISTICS(jniinvokation());
4108 if (start < 0 || len < 0 || start + len > array->header.size)
4109 exceptions_throw_arrayindexoutofboundsexception();
4111 MCOPY(buf, &array->data[start], jchar, len);
4115 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
4116 jsize len, jshort *buf)
4118 STATISTICS(jniinvokation());
4120 if (start < 0 || len < 0 || start + len > array->header.size)
4121 exceptions_throw_arrayindexoutofboundsexception();
4123 MCOPY(buf, &array->data[start], jshort, len);
4127 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
4130 STATISTICS(jniinvokation());
4132 if (start < 0 || len < 0 || start + len > array->header.size)
4133 exceptions_throw_arrayindexoutofboundsexception();
4135 MCOPY(buf, &array->data[start], jint, len);
4139 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
4142 STATISTICS(jniinvokation());
4144 if (start < 0 || len < 0 || start + len > array->header.size)
4145 exceptions_throw_arrayindexoutofboundsexception();
4147 MCOPY(buf, &array->data[start], jlong, len);
4151 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
4152 jsize len, jfloat *buf)
4154 STATISTICS(jniinvokation());
4156 if (start < 0 || len < 0 || start + len > array->header.size)
4157 exceptions_throw_arrayindexoutofboundsexception();
4159 MCOPY(buf, &array->data[start], jfloat, len);
4163 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
4164 jsize len, jdouble *buf)
4166 STATISTICS(jniinvokation());
4168 if (start < 0 || len < 0 || start+len>array->header.size)
4169 exceptions_throw_arrayindexoutofboundsexception();
4171 MCOPY(buf, &array->data[start], jdouble, len);
4175 /* Set<PrimitiveType>ArrayRegion **********************************************
4177 A family of functions that copies back a region of a primitive
4178 array from a buffer.
4180 *******************************************************************************/
4182 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
4183 jsize len, jboolean *buf)
4185 STATISTICS(jniinvokation());
4187 if (start < 0 || len < 0 || start + len > array->header.size)
4188 exceptions_throw_arrayindexoutofboundsexception();
4190 MCOPY(&array->data[start], buf, jboolean, len);
4194 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
4197 STATISTICS(jniinvokation());
4199 if (start < 0 || len < 0 || start + len > array->header.size)
4200 exceptions_throw_arrayindexoutofboundsexception();
4202 MCOPY(&array->data[start], buf, jbyte, len);
4206 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
4209 STATISTICS(jniinvokation());
4211 if (start < 0 || len < 0 || start + len > array->header.size)
4212 exceptions_throw_arrayindexoutofboundsexception();
4214 MCOPY(&array->data[start], buf, jchar, len);
4218 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
4219 jsize len, jshort *buf)
4221 STATISTICS(jniinvokation());
4223 if (start < 0 || len < 0 || start + len > array->header.size)
4224 exceptions_throw_arrayindexoutofboundsexception();
4226 MCOPY(&array->data[start], buf, jshort, len);
4230 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
4233 STATISTICS(jniinvokation());
4235 if (start < 0 || len < 0 || start + len > array->header.size)
4236 exceptions_throw_arrayindexoutofboundsexception();
4238 MCOPY(&array->data[start], buf, jint, len);
4242 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
4245 STATISTICS(jniinvokation());
4247 if (start < 0 || len < 0 || start + len > array->header.size)
4248 exceptions_throw_arrayindexoutofboundsexception();
4250 MCOPY(&array->data[start], buf, jlong, len);
4254 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
4255 jsize len, jfloat *buf)
4257 STATISTICS(jniinvokation());
4259 if (start < 0 || len < 0 || start + len > array->header.size)
4260 exceptions_throw_arrayindexoutofboundsexception();
4262 MCOPY(&array->data[start], buf, jfloat, len);
4266 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
4267 jsize len, jdouble *buf)
4269 STATISTICS(jniinvokation());
4271 if (start < 0 || len < 0 || start + len > array->header.size)
4272 exceptions_throw_arrayindexoutofboundsexception();
4274 MCOPY(&array->data[start], buf, jdouble, len);
4278 /* Registering Native Methods *************************************************/
4280 /* RegisterNatives *************************************************************
4282 Registers native methods with the class specified by the clazz
4283 argument. The methods parameter specifies an array of
4284 JNINativeMethod structures that contain the names, signatures, and
4285 function pointers of the native methods. The nMethods parameter
4286 specifies the number of native methods in the array.
4288 *******************************************************************************/
4290 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
4293 STATISTICS(jniinvokation());
4295 log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
4301 /* UnregisterNatives ***********************************************************
4303 Unregisters native methods of a class. The class goes back to the
4304 state before it was linked or registered with its native method
4307 This function should not be used in normal native code. Instead, it
4308 provides special programs a way to reload and relink native
4311 *******************************************************************************/
4313 jint UnregisterNatives(JNIEnv *env, jclass clazz)
4315 STATISTICS(jniinvokation());
4317 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
4319 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
4325 /* Monitor Operations *********************************************************/
4327 /* MonitorEnter ****************************************************************
4329 Enters the monitor associated with the underlying Java object
4332 *******************************************************************************/
4334 jint MonitorEnter(JNIEnv *env, jobject obj)
4336 STATISTICS(jniinvokation());
4339 exceptions_throw_nullpointerexception();
4343 #if defined(USE_THREADS)
4344 builtin_monitorenter(obj);
4351 /* MonitorExit *****************************************************************
4353 The current thread must be the owner of the monitor associated with
4354 the underlying Java object referred to by obj. The thread
4355 decrements the counter indicating the number of times it has
4356 entered this monitor. If the value of the counter becomes zero, the
4357 current thread releases the monitor.
4359 *******************************************************************************/
4361 jint MonitorExit(JNIEnv *env, jobject obj)
4363 STATISTICS(jniinvokation());
4366 exceptions_throw_nullpointerexception();
4370 #if defined(USE_THREADS)
4371 builtin_monitorexit(obj);
4378 /* JavaVM Interface ***********************************************************/
4380 /* GetJavaVM *******************************************************************
4382 Returns the Java VM interface (used in the Invocation API)
4383 associated with the current thread. The result is placed at the
4384 location pointed to by the second argument, vm.
4386 *******************************************************************************/
4388 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
4390 STATISTICS(jniinvokation());
4398 void GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
4400 STATISTICS(jniinvokation());
4402 log_text("JNI-Call: GetStringRegion: IMPLEMENT ME!");
4406 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
4408 STATISTICS(jniinvokation());
4410 log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
4414 /* GetPrimitiveArrayCritical ***************************************************
4416 Obtain a direct pointer to array elements.
4418 *******************************************************************************/
4420 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
4425 ba = (java_bytearray *) array;
4427 /* do the same as Kaffe does */
4429 bp = GetByteArrayElements(env, ba, isCopy);
4435 /* ReleasePrimitiveArrayCritical ***********************************************
4437 No specific documentation.
4439 *******************************************************************************/
4441 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
4444 STATISTICS(jniinvokation());
4446 /* do the same as Kaffe does */
4448 ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
4452 /* GetStringCritical ***********************************************************
4454 The semantics of these two functions are similar to the existing
4455 Get/ReleaseStringChars functions.
4457 *******************************************************************************/
4459 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
4461 STATISTICS(jniinvokation());
4463 return GetStringChars(env, string, isCopy);
4467 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
4469 STATISTICS(jniinvokation());
4471 ReleaseStringChars(env, string, cstring);
4475 jweak NewWeakGlobalRef(JNIEnv* env, jobject obj)
4477 STATISTICS(jniinvokation());
4479 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
4485 void DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
4487 STATISTICS(jniinvokation());
4489 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
4493 /* NewGlobalRef ****************************************************************
4495 Creates a new global reference to the object referred to by the obj
4498 *******************************************************************************/
4500 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4502 java_objectheader *o;
4503 java_lang_Integer *refcount;
4504 java_objectheader *newval;
4506 STATISTICS(jniinvokation());
4508 #if defined(USE_THREADS)
4509 builtin_monitorenter(*global_ref_table);
4512 ASM_CALLJAVAFUNCTION_ADR(o, getmid, *global_ref_table, lobj, NULL, NULL);
4514 refcount = (java_lang_Integer *) o;
4516 if (refcount == NULL) {
4517 newval = native_new_and_init_int(class_java_lang_Integer, 1);
4519 if (newval == NULL) {
4520 #if defined(USE_THREADS)
4521 builtin_monitorexit(*global_ref_table);
4526 ASM_CALLJAVAFUNCTION(putmid, *global_ref_table, lobj, newval, NULL);
4529 /* we can access the object itself, as we are in a
4530 synchronized section */
4535 #if defined(USE_THREADS)
4536 builtin_monitorexit(*global_ref_table);
4543 /* DeleteGlobalRef *************************************************************
4545 Deletes the global reference pointed to by globalRef.
4547 *******************************************************************************/
4549 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
4551 java_objectheader *o;
4552 java_lang_Integer *refcount;
4555 STATISTICS(jniinvokation());
4557 #if defined(USE_THREADS)
4558 builtin_monitorenter(*global_ref_table);
4561 ASM_CALLJAVAFUNCTION_ADR(o, getmid, *global_ref_table, globalRef, NULL,
4564 refcount = (java_lang_Integer *) o;
4566 if (refcount == NULL) {
4567 log_text("JNI-DeleteGlobalRef: unable to find global reference");
4571 /* we can access the object itself, as we are in a synchronized
4574 val = refcount->value - 1;
4577 ASM_CALLJAVAFUNCTION(removemid, *global_ref_table, refcount, NULL,
4581 /* we do not create a new object, but set the new value into
4584 refcount->value = val;
4587 #if defined(USE_THREADS)
4588 builtin_monitorexit(*global_ref_table);
4593 /* ExceptionCheck **************************************************************
4595 Returns JNI_TRUE when there is a pending exception; otherwise,
4598 *******************************************************************************/
4600 jboolean ExceptionCheck(JNIEnv *env)
4602 STATISTICS(jniinvokation());
4604 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
4608 /* New JNI 1.4 functions ******************************************************/
4610 /* NewDirectByteBuffer *********************************************************
4612 Allocates and returns a direct java.nio.ByteBuffer referring to the
4613 block of memory starting at the memory address address and
4614 extending capacity bytes.
4616 *******************************************************************************/
4618 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
4620 java_objectheader *nbuf;
4621 #if SIZEOF_VOID_P == 8
4622 gnu_classpath_Pointer64 *paddress;
4624 gnu_classpath_Pointer32 *paddress;
4627 STATISTICS(jniinvokation());
4629 /* alocate a gnu.classpath.Pointer{32,64} object */
4631 #if SIZEOF_VOID_P == 8
4632 if (!(paddress = (gnu_classpath_Pointer64 *)
4633 builtin_new(class_gnu_classpath_Pointer64)))
4635 if (!(paddress = (gnu_classpath_Pointer32 *)
4636 builtin_new(class_gnu_classpath_Pointer32)))
4640 /* fill gnu.classpath.Pointer{32,64} with address */
4642 paddress->data = (ptrint) address;
4644 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
4646 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
4647 dbbirw_init, NULL, paddress,
4648 (jint) capacity, (jint) capacity, (jint) 0);
4650 /* add local reference and return the value */
4652 return NewLocalRef(env, nbuf);
4656 /* GetDirectBufferAddress ******************************************************
4658 Fetches and returns the starting address of the memory region
4659 referenced by the given direct java.nio.Buffer.
4661 *******************************************************************************/
4663 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
4665 java_nio_DirectByteBufferImpl *nbuf;
4666 #if SIZEOF_VOID_P == 8
4667 gnu_classpath_Pointer64 *address;
4669 gnu_classpath_Pointer32 *address;
4672 STATISTICS(jniinvokation());
4674 if (!builtin_instanceof(buf, class_java_nio_Buffer))
4677 nbuf = (java_nio_DirectByteBufferImpl *) buf;
4679 #if SIZEOF_VOID_P == 8
4680 address = (gnu_classpath_Pointer64 *) nbuf->address;
4682 address = (gnu_classpath_Pointer32 *) nbuf->address;
4685 return (void *) address->data;
4689 /* GetDirectBufferCapacity *****************************************************
4691 Fetches and returns the capacity in bytes of the memory region
4692 referenced by the given direct java.nio.Buffer.
4694 *******************************************************************************/
4696 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
4698 java_nio_Buffer *nbuf;
4700 STATISTICS(jniinvokation());
4702 if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
4705 nbuf = (java_nio_Buffer *) buf;
4707 return (jlong) nbuf->cap;
4711 jint DestroyJavaVM(JavaVM *vm)
4713 STATISTICS(jniinvokation());
4715 log_text("JNI-Call: DestroyJavaVM: IMPLEMENT ME!");
4721 /* AttachCurrentThread *********************************************************
4723 Attaches the current thread to a Java VM. Returns a JNI interface
4724 pointer in the JNIEnv argument.
4726 Trying to attach a thread that is already attached is a no-op.
4728 A native thread cannot be attached simultaneously to two Java VMs.
4730 When a thread is attached to the VM, the context class loader is
4731 the bootstrap loader.
4733 *******************************************************************************/
4735 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
4737 STATISTICS(jniinvokation());
4739 log_text("JNI-Call: AttachCurrentThread: IMPLEMENT ME!");
4741 #if !defined(HAVE___THREAD)
4742 /* cacao_thread_attach();*/
4744 #error "No idea how to implement that. Perhaps Stefan knows"
4753 jint DetachCurrentThread(JavaVM *vm)
4755 STATISTICS(jniinvokation());
4757 log_text("JNI-Call: DetachCurrentThread: IMPLEMENT ME!");
4763 /* GetEnv **********************************************************************
4765 If the current thread is not attached to the VM, sets *env to NULL,
4766 and returns JNI_EDETACHED. If the specified version is not
4767 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
4768 sets *env to the appropriate interface, and returns JNI_OK.
4770 *******************************************************************************/
4772 jint GetEnv(JavaVM *vm, void **env, jint version)
4774 STATISTICS(jniinvokation());
4776 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4777 if (thread_getself() == NULL) {
4780 return JNI_EDETACHED;
4784 if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
4785 (version == JNI_VERSION_1_4)) {
4791 #if defined(ENABLE_JVMTI)
4792 if (version == JVMTI_VERSION_1_0) {
4793 *env = (void *) new_jvmtienv();
4802 return JNI_EVERSION;
4807 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4809 STATISTICS(jniinvokation());
4811 log_text("JNI-Call: AttachCurrentThreadAsDaemon: IMPLEMENT ME!");
4817 /* JNI invocation table *******************************************************/
4819 const struct JNIInvokeInterface JNI_JavaVMTable = {
4825 AttachCurrentThread,
4826 DetachCurrentThread,
4828 AttachCurrentThreadAsDaemon
4832 /* JNI function table *********************************************************/
4834 struct JNINativeInterface JNI_JNIEnvTable = {
4843 &FromReflectedMethod,
4844 &FromReflectedField,
4864 &EnsureLocalCapacity,
4880 &CallBooleanMethodV,
4881 &CallBooleanMethodA,
4907 &CallNonvirtualObjectMethod,
4908 &CallNonvirtualObjectMethodV,
4909 &CallNonvirtualObjectMethodA,
4910 &CallNonvirtualBooleanMethod,
4911 &CallNonvirtualBooleanMethodV,
4912 &CallNonvirtualBooleanMethodA,
4913 &CallNonvirtualByteMethod,
4914 &CallNonvirtualByteMethodV,
4915 &CallNonvirtualByteMethodA,
4916 &CallNonvirtualCharMethod,
4917 &CallNonvirtualCharMethodV,
4918 &CallNonvirtualCharMethodA,
4919 &CallNonvirtualShortMethod,
4920 &CallNonvirtualShortMethodV,
4921 &CallNonvirtualShortMethodA,
4922 &CallNonvirtualIntMethod,
4923 &CallNonvirtualIntMethodV,
4924 &CallNonvirtualIntMethodA,
4925 &CallNonvirtualLongMethod,
4926 &CallNonvirtualLongMethodV,
4927 &CallNonvirtualLongMethodA,
4928 &CallNonvirtualFloatMethod,
4929 &CallNonvirtualFloatMethodV,
4930 &CallNonvirtualFloatMethodA,
4931 &CallNonvirtualDoubleMethod,
4932 &CallNonvirtualDoubleMethodV,
4933 &CallNonvirtualDoubleMethodA,
4934 &CallNonvirtualVoidMethod,
4935 &CallNonvirtualVoidMethodV,
4936 &CallNonvirtualVoidMethodA,
4961 &CallStaticObjectMethod,
4962 &CallStaticObjectMethodV,
4963 &CallStaticObjectMethodA,
4964 &CallStaticBooleanMethod,
4965 &CallStaticBooleanMethodV,
4966 &CallStaticBooleanMethodA,
4967 &CallStaticByteMethod,
4968 &CallStaticByteMethodV,
4969 &CallStaticByteMethodA,
4970 &CallStaticCharMethod,
4971 &CallStaticCharMethodV,
4972 &CallStaticCharMethodA,
4973 &CallStaticShortMethod,
4974 &CallStaticShortMethodV,
4975 &CallStaticShortMethodA,
4976 &CallStaticIntMethod,
4977 &CallStaticIntMethodV,
4978 &CallStaticIntMethodA,
4979 &CallStaticLongMethod,
4980 &CallStaticLongMethodV,
4981 &CallStaticLongMethodA,
4982 &CallStaticFloatMethod,
4983 &CallStaticFloatMethodV,
4984 &CallStaticFloatMethodA,
4985 &CallStaticDoubleMethod,
4986 &CallStaticDoubleMethodV,
4987 &CallStaticDoubleMethodA,
4988 &CallStaticVoidMethod,
4989 &CallStaticVoidMethodV,
4990 &CallStaticVoidMethodA,
4994 &GetStaticObjectField,
4995 &GetStaticBooleanField,
4996 &GetStaticByteField,
4997 &GetStaticCharField,
4998 &GetStaticShortField,
5000 &GetStaticLongField,
5001 &GetStaticFloatField,
5002 &GetStaticDoubleField,
5003 &SetStaticObjectField,
5004 &SetStaticBooleanField,
5005 &SetStaticByteField,
5006 &SetStaticCharField,
5007 &SetStaticShortField,
5009 &SetStaticLongField,
5010 &SetStaticFloatField,
5011 &SetStaticDoubleField,
5016 &ReleaseStringChars,
5019 &GetStringUTFLength,
5021 &ReleaseStringUTFChars,
5026 &GetObjectArrayElement,
5027 &SetObjectArrayElement,
5038 &GetBooleanArrayElements,
5039 &GetByteArrayElements,
5040 &GetCharArrayElements,
5041 &GetShortArrayElements,
5042 &GetIntArrayElements,
5043 &GetLongArrayElements,
5044 &GetFloatArrayElements,
5045 &GetDoubleArrayElements,
5047 &ReleaseBooleanArrayElements,
5048 &ReleaseByteArrayElements,
5049 &ReleaseCharArrayElements,
5050 &ReleaseShortArrayElements,
5051 &ReleaseIntArrayElements,
5052 &ReleaseLongArrayElements,
5053 &ReleaseFloatArrayElements,
5054 &ReleaseDoubleArrayElements,
5056 &GetBooleanArrayRegion,
5057 &GetByteArrayRegion,
5058 &GetCharArrayRegion,
5059 &GetShortArrayRegion,
5061 &GetLongArrayRegion,
5062 &GetFloatArrayRegion,
5063 &GetDoubleArrayRegion,
5064 &SetBooleanArrayRegion,
5065 &SetByteArrayRegion,
5066 &SetCharArrayRegion,
5067 &SetShortArrayRegion,
5069 &SetLongArrayRegion,
5070 &SetFloatArrayRegion,
5071 &SetDoubleArrayRegion,
5081 /* new JNI 1.2 functions */
5084 &GetStringUTFRegion,
5086 &GetPrimitiveArrayCritical,
5087 &ReleasePrimitiveArrayCritical,
5090 &ReleaseStringCritical,
5093 &DeleteWeakGlobalRef,
5097 /* new JNI 1.4 functions */
5099 &NewDirectByteBuffer,
5100 &GetDirectBufferAddress,
5101 &GetDirectBufferCapacity
5105 /* Invocation API Functions ***************************************************/
5107 /* JNI_GetDefaultJavaVMInitArgs ************************************************
5109 Returns a default configuration for the Java VM.
5111 *******************************************************************************/
5113 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
5115 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
5117 /* GNU classpath currently supports JNI 1.2 */
5119 _vm_args->version = JNI_VERSION_1_2;
5125 /* JNI_GetCreatedJavaVMs *******************************************************
5127 Returns all Java VMs that have been created. Pointers to VMs are written in
5128 the buffer vmBuf in the order they are created. At most bufLen number of
5129 entries will be written. The total number of created VMs is returned in
5132 *******************************************************************************/
5134 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
5136 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
5142 /* JNI_CreateJavaVM ************************************************************
5144 Loads and initializes a Java VM. The current thread becomes the main thread.
5145 Sets the env argument to the JNI interface pointer of the main thread.
5147 *******************************************************************************/
5149 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
5151 const struct JNIInvokeInterface *vm;
5152 struct JNINativeInterface *env;
5154 vm = &JNI_JavaVMTable;
5155 env = &JNI_JNIEnvTable;
5157 *p_vm = (JavaVM *) vm;
5158 *p_env = (JNIEnv *) env;
5165 * These are local overrides for various environment variables in Emacs.
5166 * Please do not remove this and leave it at the end of the file, where
5167 * Emacs will automagically detect them.
5168 * ---------------------------------------------------------------------
5171 * indent-tabs-mode: t
5175 * vim:noexpandtab:sw=4:ts=4: