1 /* src/native/jni.c - implementation of the Java Native Interface functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Rainhard Grafl
30 Changes: Joseph Wenninger
34 $Id: jni.c 3865 2005-12-03 14:43:47Z twisti $
46 #include "mm/memory.h"
47 #include "native/jni.h"
48 #include "native/native.h"
50 #include "native/include/gnu_classpath_Pointer.h"
52 #if SIZEOF_VOID_P == 8
53 # include "native/include/gnu_classpath_Pointer64.h"
55 # include "native/include/gnu_classpath_Pointer32.h"
58 #include "native/include/java_lang_Object.h"
59 #include "native/include/java_lang_Byte.h"
60 #include "native/include/java_lang_Character.h"
61 #include "native/include/java_lang_Short.h"
62 #include "native/include/java_lang_Integer.h"
63 #include "native/include/java_lang_Boolean.h"
64 #include "native/include/java_lang_Long.h"
65 #include "native/include/java_lang_Float.h"
66 #include "native/include/java_lang_Double.h"
67 #include "native/include/java_lang_Throwable.h"
68 #include "native/include/java_lang_reflect_Method.h"
69 #include "native/include/java_lang_reflect_Constructor.h"
70 #include "native/include/java_lang_reflect_Field.h"
72 #include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
73 #include "native/include/java_lang_VMClass.h"
74 #include "native/include/java_lang_VMClassLoader.h"
75 #include "native/include/java_nio_Buffer.h"
76 #include "native/include/java_nio_DirectByteBufferImpl.h"
78 #if defined(ENABLE_JVMTI)
79 # include "native/jvmti/jvmti.h"
82 #if defined(USE_THREADS)
83 # if defined(NATIVE_THREADS)
84 # include "threads/native/threads.h"
86 # include "threads/green/threads.h"
90 #include "toolbox/logging.h"
91 #include "vm/builtin.h"
92 #include "vm/exceptions.h"
93 #include "vm/global.h"
94 #include "vm/initialize.h"
95 #include "vm/loader.h"
96 #include "vm/options.h"
97 #include "vm/resolve.h"
98 #include "vm/statistics.h"
99 #include "vm/stringlocal.h"
100 #include "vm/jit/asmpart.h"
101 #include "vm/jit/jit.h"
102 #include "vm/statistics.h"
105 /* XXX TWISTI hack: define it extern so they can be found in this file */
107 extern const struct JNIInvokeInterface JNI_JavaVMTable;
108 extern struct JNINativeInterface JNI_JNIEnvTable;
110 /* pointers to VM and the environment needed by GetJavaVM and GetEnv */
112 static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
113 void *ptr_env = (void*) &JNI_JNIEnvTable;
116 #define PTR_TO_ITEM(ptr) ((u8)(size_t)(ptr))
118 /* global variables ***********************************************************/
120 /* global reference table *****************************************************/
122 static java_objectheader **global_ref_table;
124 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
125 static classinfo *ihmclass = NULL;
126 static methodinfo *putmid = NULL;
127 static methodinfo *getmid = NULL;
128 static methodinfo *removemid = NULL;
131 /* direct buffer stuff ********************************************************/
133 static utf *utf_java_nio_DirectByteBufferImpl_ReadWrite;
134 #if SIZEOF_VOID_P == 8
135 static utf *utf_gnu_classpath_Pointer64;
137 static utf *utf_gnu_classpath_Pointer32;
140 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
141 #if SIZEOF_VOID_P == 8
142 static classinfo *class_gnu_classpath_Pointer64;
144 static classinfo *class_gnu_classpath_Pointer32;
147 static methodinfo *dbbirw_init;
150 /* local reference table ******************************************************/
152 #if !defined(USE_THREADS)
153 localref_table *_no_threads_localref_table;
157 /* accessing instance fields macros *******************************************/
159 #define SET_FIELD(obj,type,var,value) \
160 *((type *) ((ptrint) (obj) + (ptrint) (var)->offset)) = (type) (value)
162 #define GET_FIELD(obj,type,var) \
163 *((type *) ((ptrint) (obj) + (ptrint) (var)->offset))
166 /* some forward declarations **************************************************/
168 jobject NewLocalRef(JNIEnv *env, jobject ref);
171 /* jni_init ********************************************************************
173 Initialize the JNI subsystem.
175 *******************************************************************************/
179 /* initalize global reference table */
182 load_class_bootstrap(utf_new_char("java/util/IdentityHashMap"))))
185 global_ref_table = GCNEW(jobject, 1);
187 if (!(*global_ref_table = native_new_and_init(ihmclass)))
190 if (!(getmid = class_resolvemethod(ihmclass, utf_get,
191 utf_java_lang_Object__java_lang_Object)))
194 if (!(putmid = class_resolvemethod(ihmclass, utf_put,
195 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))))
199 class_resolvemethod(ihmclass, utf_remove,
200 utf_java_lang_Object__java_lang_Object)))
204 /* direct buffer stuff */
206 utf_java_nio_DirectByteBufferImpl_ReadWrite =
207 utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite");
209 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
210 load_class_bootstrap(utf_java_nio_DirectByteBufferImpl_ReadWrite)))
213 if (!link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
217 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
219 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
222 #if SIZEOF_VOID_P == 8
223 utf_gnu_classpath_Pointer64 = utf_new_char("gnu/classpath/Pointer64");
225 if (!(class_gnu_classpath_Pointer64 =
226 load_class_bootstrap(utf_gnu_classpath_Pointer64)))
229 if (!link_class(class_gnu_classpath_Pointer64))
232 utf_gnu_classpath_Pointer32 = utf_new_char("gnu/classpath/Pointer32");
234 if (!(class_gnu_classpath_Pointer32 =
235 load_class_bootstrap(utf_gnu_classpath_Pointer32)))
238 if (!link_class(class_gnu_classpath_Pointer32))
246 static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
247 jni_callblock blk[], va_list data,
250 typedesc *paramtypes;
253 paramtypes = descr->paramtypes;
255 /* if method is non-static fill first block and skip `this' pointer */
260 /* the `this' pointer */
261 blk[0].itemtype = TYPE_ADR;
262 blk[0].item = PTR_TO_ITEM(obj);
268 for (; i < descr->paramcount; i++, paramtypes++) {
269 switch (paramtypes->decltype) {
270 /* primitive types */
271 case PRIMITIVETYPE_BYTE:
272 case PRIMITIVETYPE_CHAR:
273 case PRIMITIVETYPE_SHORT:
274 case PRIMITIVETYPE_BOOLEAN:
275 blk[i].itemtype = TYPE_INT;
276 blk[i].item = (s8) va_arg(data, s4);
279 case PRIMITIVETYPE_INT:
280 blk[i].itemtype = TYPE_INT;
281 blk[i].item = (s8) va_arg(data, s4);
284 case PRIMITIVETYPE_LONG:
285 blk[i].itemtype = TYPE_LNG;
286 blk[i].item = (s8) va_arg(data, s8);
289 case PRIMITIVETYPE_FLOAT:
290 blk[i].itemtype = TYPE_FLT;
291 #if defined(__ALPHA__)
292 /* this keeps the assembler function much simpler */
294 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
296 *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
300 case PRIMITIVETYPE_DOUBLE:
301 blk[i].itemtype = TYPE_DBL;
302 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
306 blk[i].itemtype = TYPE_ADR;
307 blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
312 /* The standard doesn't say anything about return value checking, but it */
313 /* appears to be useful. */
315 if (rettype != descr->returntype.decltype)
316 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
320 /* XXX it could be considered if we should do typechecking here in the future */
322 static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
324 java_objectarray *params)
328 typedesc *paramtypes;
333 paramcount = descr->paramcount;
334 paramtypes = descr->paramtypes;
336 /* if method is non-static fill first block and skip `this' pointer */
342 blk[0].itemtype = TYPE_ADR;
343 blk[0].item = PTR_TO_ITEM(obj);
350 for (j = 0; j < paramcount; i++, j++, paramtypes++) {
351 switch (paramtypes->type) {
352 /* primitive types */
357 param = params->data[j];
361 /* internally used data type */
362 blk[i].itemtype = paramtypes->type;
364 /* convert the value according to its declared type */
366 c = param->vftbl->class;
368 switch (paramtypes->decltype) {
369 case PRIMITIVETYPE_BOOLEAN:
370 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
371 blk[i].item = (s8) ((java_lang_Boolean *) param)->value;
376 case PRIMITIVETYPE_BYTE:
377 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
378 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
383 case PRIMITIVETYPE_CHAR:
384 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
385 blk[i].item = (s8) ((java_lang_Character *) param)->value;
390 case PRIMITIVETYPE_SHORT:
391 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
392 blk[i].item = (s8) ((java_lang_Short *) param)->value;
393 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
394 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
399 case PRIMITIVETYPE_INT:
400 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
401 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
402 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
403 blk[i].item = (s8) ((java_lang_Short *) param)->value;
404 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
405 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
410 case PRIMITIVETYPE_LONG:
411 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
412 blk[i].item = (s8) ((java_lang_Long *) param)->value;
413 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
414 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
415 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
416 blk[i].item = (s8) ((java_lang_Short *) param)->value;
417 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
418 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
423 case PRIMITIVETYPE_FLOAT:
424 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
425 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
430 case PRIMITIVETYPE_DOUBLE:
431 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
432 *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Float *) param)->value;
433 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
434 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
441 } /* end declared type switch */
445 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
448 if (params->data[j] != 0) {
449 if (paramtypes->arraydim > 0) {
450 if (!builtin_arrayinstanceof(params->data[j], c))
454 if (!builtin_instanceof(params->data[j], c))
458 blk[i].itemtype = TYPE_ADR;
459 blk[i].item = PTR_TO_ITEM(params->data[j]);
464 } /* end param type switch */
466 } /* end param loop */
469 /* *rettype = descr->returntype.decltype; */
474 *exceptionptr = new_illegalargumentexception();
479 static jmethodID get_virtual(jobject obj, jmethodID methodID)
481 if (obj->vftbl->class == methodID->class)
484 return class_resolvemethod(obj->vftbl->class, methodID->name,
485 methodID->descriptor);
489 static jmethodID get_nonvirtual(jclass clazz, jmethodID methodID)
491 if (clazz == methodID->class)
494 /* class_resolvemethod -> classfindmethod? (JOWENN) */
495 return class_resolvemethod(clazz, methodID->name, methodID->descriptor);
499 static jobject callObjectMethod(jobject obj, jmethodID methodID, va_list args)
506 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
510 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
511 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
512 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
516 if (obj && !builtin_instanceof(obj, methodID->class)) {
517 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
521 argcount = methodID->parseddesc->paramcount;
523 blk = MNEW(jni_callblock, argcount);
525 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_ADR);
527 STATS(jnicallXmethodnvokation();)
529 ret = asm_calljavafunction2(methodID,
531 argcount * sizeof(jni_callblock),
534 MFREE(blk, jni_callblock, argcount);
541 core function for integer class methods (bool, byte, short, integer)
542 This is basically needed for i386
544 static jint callIntegerMethod(jobject obj, jmethodID methodID, int retType, va_list args)
550 STATS(jniinvokation();)
553 log_text("JNI-Call: CallObjectMethodV");
554 utf_display(methodID->name);
555 utf_display(methodID->descriptor);
556 printf("\nParmaeter count: %d\n",argcount);
557 utf_display(obj->vftbl->class->name);
561 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
565 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
566 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
567 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
571 if (obj && !builtin_instanceof(obj, methodID->class)) {
572 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
576 argcount = methodID->parseddesc->paramcount;
578 blk = MNEW(jni_callblock, argcount);
580 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
582 STATS(jnicallXmethodnvokation();)
584 ret = asm_calljavafunction2int(methodID,
586 argcount * sizeof(jni_callblock),
589 MFREE(blk, jni_callblock, argcount);
595 /* callLongMethod **************************************************************
597 Core function for long class functions.
599 *******************************************************************************/
601 static jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
607 STATS(jniinvokation();)
610 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
614 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
615 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
616 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
620 if (obj && !builtin_instanceof(obj, methodID->class)) {
621 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
625 argcount = methodID->parseddesc->paramcount;
627 blk = MNEW(jni_callblock, argcount);
629 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_LNG);
631 STATS(jnicallXmethodnvokation();)
633 ret = asm_calljavafunction2long(methodID,
635 argcount * sizeof(jni_callblock),
638 MFREE(blk, jni_callblock, argcount);
644 /*core function for float class methods (float,double)*/
645 static jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,int retType)
647 int argcount = methodID->parseddesc->paramcount;
651 STATS(jniinvokation();)
656 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
657 log_text("Too many arguments. CallObjectMethod does not support that");
661 blk = MNEW(jni_callblock, /*4 */ argcount+2);
663 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
665 /* printf("parameter: obj: %p",blk[0].item); */
666 STATS(jnicallXmethodnvokation();)
667 ret = asm_calljavafunction2double(methodID,
669 (argcount + 1) * sizeof(jni_callblock),
672 MFREE(blk, jni_callblock, argcount + 1);
673 /* printf("(CallObjectMethodV)-->%p\n",ret); */
679 static void cacao_jni_CallVoidMethod(jobject obj, jmethodID m, va_list ap)
685 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
689 if (!( ((m->flags & ACC_STATIC) && (obj == 0)) ||
690 ((!(m->flags & ACC_STATIC)) && (obj != 0)) )) {
691 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
695 if (obj && !builtin_instanceof(obj, m->class)) {
696 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
700 paramcount = m->parseddesc->paramcount;
702 /* #error XXX does not work on intrp, but on JIT */
703 if (!(m->flags & ACC_STATIC))
706 blk = MNEW(jni_callblock, paramcount);
708 fill_callblock_from_vargs(obj, m->parseddesc, blk, ap, TYPE_VOID);
710 STATS(jnicallXmethodnvokation();)
712 (void) asm_calljavafunction2(m,
714 paramcount * sizeof(jni_callblock),
717 MFREE(blk, jni_callblock, paramcount);
723 /* GetVersion ******************************************************************
725 Returns the major version number in the higher 16 bits and the
726 minor version number in the lower 16 bits.
728 *******************************************************************************/
730 jint GetVersion(JNIEnv *env)
732 STATS(jniinvokation();)
734 /* we support JNI 1.4 */
736 return JNI_VERSION_1_4;
740 /* Class Operations ***********************************************************/
742 /* DefineClass *****************************************************************
744 Loads a class from a buffer of raw class data. The buffer
745 containing the raw class data is not referenced by the VM after the
746 DefineClass call returns, and it may be discarded if desired.
748 *******************************************************************************/
750 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
751 const jbyte *buf, jsize bufLen)
753 java_lang_ClassLoader *cl;
758 STATS(jniinvokation();)
760 cl = (java_lang_ClassLoader *) loader;
761 s = javastring_new_char(name);
762 ba = (java_bytearray *) buf;
764 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
767 return (jclass) NewLocalRef(env, (jobject) c);
771 /* FindClass *******************************************************************
773 This function loads a locally-defined class. It searches the
774 directories and zip files specified by the CLASSPATH environment
775 variable for the class with the specified name.
777 *******************************************************************************/
779 jclass FindClass(JNIEnv *env, const char *name)
783 java_objectheader *cl;
785 STATS(jniinvokation();)
787 u = utf_new_char_classname((char *) name);
789 /* check stacktrace for classloader, if one found use it, otherwise use */
790 /* the system classloader */
792 #if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__)
793 /* these JITs support stacktraces, and so does the interpreter */
795 cl = cacao_currentClassLoader();
797 # if defined(ENABLE_INTRP)
798 /* the interpreter supports stacktraces, even if the JIT does not */
801 cl = cacao_currentClassLoader();
807 if (!(c = load_class_from_classloader(u, cl)))
813 return (jclass) NewLocalRef(env, (jobject) c);
817 /* FromReflectedMethod *********************************************************
819 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
820 object to a method ID.
822 *******************************************************************************/
824 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
830 STATS(jniinvokation();)
835 if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
836 java_lang_reflect_Method *rm;
838 rm = (java_lang_reflect_Method *) method;
839 c = (classinfo *) (rm->declaringClass);
842 } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
843 java_lang_reflect_Constructor *rc;
845 rc = (java_lang_reflect_Constructor *) method;
846 c = (classinfo *) (rc->clazz);
852 if ((slot < 0) || (slot >= c->methodscount)) {
853 /* this usually means a severe internal cacao error or somebody
854 tempered around with the reflected method */
855 log_text("error illegal slot for method in class(FromReflectedMethod)");
859 mi = &(c->methods[slot]);
865 /* GetSuperclass ***************************************************************
867 If clazz represents any class other than the class Object, then
868 this function returns the object that represents the superclass of
869 the class specified by clazz.
871 *******************************************************************************/
873 jclass GetSuperclass(JNIEnv *env, jclass sub)
877 STATS(jniinvokation();)
879 c = ((classinfo *) sub)->super.cls;
884 return (jclass) NewLocalRef(env, (jobject) c);
888 /* IsAssignableFrom ************************************************************
890 Determines whether an object of sub can be safely cast to sup.
892 *******************************************************************************/
894 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
896 STATS(jniinvokation();)
897 return Java_java_lang_VMClass_isAssignableFrom(env,
899 (java_lang_Class *) sup,
900 (java_lang_Class *) sub);
904 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
906 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
908 STATS(jniinvokation();)
910 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!!!");
916 /* Throw ***********************************************************************
918 Causes a java.lang.Throwable object to be thrown.
920 *******************************************************************************/
922 jint Throw(JNIEnv *env, jthrowable obj)
924 STATS(jniinvokation();)
926 *exceptionptr = (java_objectheader *) obj;
932 /* ThrowNew ********************************************************************
934 Constructs an exception object from the specified class with the
935 message specified by message and causes that exception to be
938 *******************************************************************************/
940 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
942 java_lang_Throwable *o;
945 STATS(jniinvokation();)
947 s = (java_lang_String *) javastring_new_char(msg);
949 /* instantiate exception object */
951 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
957 *exceptionptr = (java_objectheader *) o;
963 /* ExceptionOccurred ***********************************************************
965 Determines if an exception is being thrown. The exception stays
966 being thrown until either the native code calls ExceptionClear(),
967 or the Java code handles the exception.
969 *******************************************************************************/
971 jthrowable ExceptionOccurred(JNIEnv *env)
973 java_objectheader *e;
975 STATS(jniinvokation();)
979 return NewLocalRef(env, (jthrowable) e);
983 /* ExceptionDescribe ***********************************************************
985 Prints an exception and a backtrace of the stack to a system
986 error-reporting channel, such as stderr. This is a convenience
987 routine provided for debugging.
989 *******************************************************************************/
991 void ExceptionDescribe(JNIEnv *env)
993 java_objectheader *e;
995 STATS(jniinvokation();)
1000 /* clear exception, because we are calling jit code again */
1002 *exceptionptr = NULL;
1004 /* get printStackTrace method from exception class */
1006 m = class_resolveclassmethod(e->vftbl->class,
1007 utf_printStackTrace,
1013 /* XXX what should we do? */
1016 /* print the stacktrace */
1018 asm_calljavafunction(m, e, NULL, NULL, NULL);
1023 /* ExceptionClear **************************************************************
1025 Clears any exception that is currently being thrown. If no
1026 exception is currently being thrown, this routine has no effect.
1028 *******************************************************************************/
1030 void ExceptionClear(JNIEnv *env)
1032 STATS(jniinvokation();)
1034 *exceptionptr = NULL;
1038 /* FatalError ******************************************************************
1040 Raises a fatal error and does not expect the VM to recover. This
1041 function does not return.
1043 *******************************************************************************/
1045 void FatalError(JNIEnv *env, const char *msg)
1047 STATS(jniinvokation();)
1049 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
1053 /* PushLocalFrame **************************************************************
1055 Creates a new local reference frame, in which at least a given
1056 number of local references can be created.
1058 *******************************************************************************/
1060 jint PushLocalFrame(JNIEnv* env, jint capacity)
1062 STATS(jniinvokation();)
1064 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
1071 /* PopLocalFrame ***************************************************************
1073 Pops off the current local reference frame, frees all the local
1074 references, and returns a local reference in the previous local
1075 reference frame for the given result object.
1077 *******************************************************************************/
1079 jobject PopLocalFrame(JNIEnv* env, jobject result)
1081 STATS(jniinvokation();)
1083 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
1087 /* add local reference and return the value */
1089 return NewLocalRef(env, NULL);
1093 /* DeleteLocalRef **************************************************************
1095 Deletes the local reference pointed to by localRef.
1097 *******************************************************************************/
1099 void DeleteLocalRef(JNIEnv *env, jobject localRef)
1101 java_objectheader *o;
1102 localref_table *lrt;
1105 STATS(jniinvokation();)
1107 o = (java_objectheader *) localRef;
1109 /* get local reference table (thread specific) */
1111 lrt = LOCALREFTABLE;
1113 /* remove the reference */
1115 for (i = 0; i < lrt->capacity; i++) {
1116 if (lrt->refs[i] == o) {
1117 lrt->refs[i] = NULL;
1124 /* this should not happen */
1126 /* if (opt_checkjni) */
1127 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1128 log_text("JNI-DeleteLocalRef: Bad global or local ref passed to JNI");
1132 /* IsSameObject ****************************************************************
1134 Tests whether two references refer to the same Java object.
1136 *******************************************************************************/
1138 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1140 STATS(jniinvokation();)
1149 /* NewLocalRef *****************************************************************
1151 Creates a new local reference that refers to the same object as ref.
1153 *******************************************************************************/
1155 jobject NewLocalRef(JNIEnv *env, jobject ref)
1157 localref_table *lrt;
1160 STATS(jniinvokation();)
1165 /* get local reference table (thread specific) */
1167 lrt = LOCALREFTABLE;
1169 /* check if we have space for the requested reference */
1171 if (lrt->used == lrt->capacity)
1172 throw_cacao_exception_exit(string_java_lang_InternalError,
1173 "Too many local references");
1175 /* insert the reference */
1177 for (i = 0; i < lrt->capacity; i++) {
1178 if (lrt->refs[i] == NULL) {
1179 lrt->refs[i] = (java_objectheader *) ref;
1186 /* should not happen, just to be sure */
1190 /* keep compiler happy */
1196 /* EnsureLocalCapacity *********************************************************
1198 Ensures that at least a given number of local references can be
1199 created in the current thread
1201 *******************************************************************************/
1203 jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
1205 localref_table *lrt;
1207 STATS(jniinvokation();)
1209 /* get local reference table (thread specific) */
1211 lrt = LOCALREFTABLE;
1213 /* check if capacity elements are available in the local references table */
1215 if ((lrt->used + capacity) > lrt->capacity) {
1216 *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
1224 /* AllocObject *****************************************************************
1226 Allocates a new Java object without invoking any of the
1227 constructors for the object. Returns a reference to the object.
1229 *******************************************************************************/
1231 jobject AllocObject(JNIEnv *env, jclass clazz)
1233 java_objectheader *o;
1235 STATS(jniinvokation();)
1237 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1239 new_exception_utfmessage(string_java_lang_InstantiationException,
1244 o = builtin_new(clazz);
1246 return NewLocalRef(env, o);
1250 /* NewObject *******************************************************************
1252 Programmers place all arguments that are to be passed to the
1253 constructor immediately following the methodID
1254 argument. NewObject() accepts these arguments and passes them to
1255 the Java method that the programmer wishes to invoke.
1257 *******************************************************************************/
1259 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1261 java_objectheader *o;
1264 STATS(jniinvokation();)
1268 o = builtin_new(clazz);
1273 /* call constructor */
1275 va_start(ap, methodID);
1276 cacao_jni_CallVoidMethod(o, methodID, ap);
1279 return NewLocalRef(env, o);
1283 /***********************************************************************************
1285 Constructs a new Java object
1286 arguments that are to be passed to the constructor are placed in va_list args
1288 ***********************************************************************************/
1290 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1292 STATS(jniinvokation();)
1294 log_text("JNI-Call: NewObjectV: IMPLEMENT ME!");
1296 return NewLocalRef(env, NULL);
1300 /***********************************************************************************
1302 Constructs a new Java object
1303 arguments that are to be passed to the constructor are placed in
1304 args array of jvalues
1306 ***********************************************************************************/
1308 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1310 STATS(jniinvokation();)
1312 log_text("JNI-Call: NewObjectA: IMPLEMENT ME!");
1314 return NewLocalRef(env, NULL);
1318 /* GetObjectClass **************************************************************
1320 Returns the class of an object.
1322 *******************************************************************************/
1324 jclass GetObjectClass(JNIEnv *env, jobject obj)
1328 STATS(jniinvokation();)
1330 if (!obj || !obj->vftbl)
1333 c = obj->vftbl->class;
1335 return (jclass) NewLocalRef(env, (jobject) c);
1339 /* IsInstanceOf ****************************************************************
1341 Tests whether an object is an instance of a class.
1343 *******************************************************************************/
1345 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1347 STATS(jniinvokation();)
1349 return Java_java_lang_VMClass_isInstance(env,
1351 (java_lang_Class *) clazz,
1352 (java_lang_Object *) obj);
1356 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1358 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1360 java_lang_reflect_Field *f;
1362 jfieldID fid; /* the JNI-fieldid of the wrapping object */
1363 STATS(jniinvokation();)
1364 /*log_text("JNI-Call: FromReflectedField");*/
1366 f=(java_lang_reflect_Field *)field;
1368 c=(classinfo*)(f->declaringClass);
1369 if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1370 /*this usually means a severe internal cacao error or somebody
1371 tempered around with the reflected method*/
1372 log_text("error illegal slot for field in class(FromReflectedField)");
1375 fid=&(c->fields[f->slot]);
1380 /**********************************************************************************
1382 converts a method ID to a java.lang.reflect.Method or
1383 java.lang.reflect.Constructor object
1385 **********************************************************************************/
1387 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1389 log_text("JNI-Call: ToReflectedMethod");
1390 STATS(jniinvokation();)
1396 /* Calling Instance Methods ***************************************************/
1398 /* GetMethodID *****************************************************************
1400 Returns the method ID for an instance (nonstatic) method of a class
1401 or interface. The method may be defined in one of the clazz's
1402 superclasses and inherited by clazz. The method is determined by
1403 its name and signature.
1405 GetMethodID() causes an uninitialized class to be initialized.
1407 *******************************************************************************/
1409 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1417 STATS(jniinvokation();)
1419 c = (classinfo *) clazz;
1424 if (!(c->state & CLASS_INITIALIZED))
1425 if (!initialize_class(c))
1428 /* try to get the method of the class or one of it's superclasses */
1430 uname = utf_new_char((char *) name);
1431 udesc = utf_new_char((char *) sig);
1433 m = class_resolvemethod(clazz, uname, udesc);
1435 if (!m || (m->flags & ACC_STATIC)) {
1436 *exceptionptr = exceptions_new_nosuchmethoderror(c, uname, udesc);
1445 /******************** JNI-functions for calling instance methods ******************/
1447 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1449 java_objectheader* ret;
1452 STATS(jniinvokation();)
1454 va_start(vaargs, methodID);
1455 ret = callObjectMethod(obj, methodID, vaargs);
1458 return NewLocalRef(env, ret);
1462 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1464 java_objectheader* ret;
1466 STATS(jniinvokation();)
1468 ret = callObjectMethod(obj, methodID, args);
1470 return NewLocalRef(env, ret);
1474 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1476 STATS(jniinvokation();)
1478 log_text("JNI-Call: CallObjectMethodA: IMPLEMENT ME!");
1480 return NewLocalRef(env, NULL);
1486 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1490 STATS(jniinvokation();)
1492 /* log_text("JNI-Call: CallBooleanMethod");*/
1494 va_start(vaargs,methodID);
1495 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1501 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1503 STATS(jniinvokation();)
1505 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
1509 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1511 STATS(jniinvokation();)
1512 log_text("JNI-Call: CallBooleanMethodA");
1517 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1521 STATS(jniinvokation();)
1523 /* log_text("JNI-Call: CallVyteMethod");*/
1525 va_start(vaargs,methodID);
1526 ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
1532 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1534 /* log_text("JNI-Call: CallByteMethodV");*/
1535 STATS(jniinvokation();)
1537 return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
1541 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1543 log_text("JNI-Call: CallByteMethodA");
1544 STATS(jniinvokation();)
1550 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1554 STATS(jniinvokation();)
1556 /* log_text("JNI-Call: CallCharMethod");*/
1558 va_start(vaargs,methodID);
1559 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
1566 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1568 STATS(jniinvokation();)
1570 /* log_text("JNI-Call: CallCharMethodV");*/
1571 return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
1575 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1577 STATS(jniinvokation();)
1579 log_text("JNI-Call: CallCharMethodA");
1585 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1589 STATS(jniinvokation();)
1591 /* log_text("JNI-Call: CallShortMethod");*/
1593 va_start(vaargs, methodID);
1594 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
1601 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1603 STATS(jniinvokation();)
1604 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
1608 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1610 STATS(jniinvokation();)
1611 log_text("JNI-Call: CallShortMethodA");
1618 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1622 STATS(jniinvokation();)
1624 va_start(vaargs,methodID);
1625 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
1632 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1634 STATS(jniinvokation();)
1635 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
1639 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1641 STATS(jniinvokation();)
1642 log_text("JNI-Call: CallIntMethodA");
1649 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1653 STATS(jniinvokation();)
1655 va_start(vaargs,methodID);
1656 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1663 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1665 STATS(jniinvokation();)
1666 return callLongMethod(obj,get_virtual(obj, methodID),args);
1670 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1672 STATS(jniinvokation();)
1673 log_text("JNI-Call: CallLongMethodA");
1680 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1685 STATS(jniinvokation();)
1686 /* log_text("JNI-Call: CallFloatMethod");*/
1688 va_start(vaargs,methodID);
1689 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
1696 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1698 STATS(jniinvokation();)
1699 log_text("JNI-Call: CallFloatMethodV");
1700 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
1704 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1706 STATS(jniinvokation();)
1707 log_text("JNI-Call: CallFloatMethodA");
1714 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1718 STATS(jniinvokation();)
1720 /* log_text("JNI-Call: CallDoubleMethod");*/
1722 va_start(vaargs,methodID);
1723 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
1730 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1732 STATS(jniinvokation();)
1733 log_text("JNI-Call: CallDoubleMethodV");
1734 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
1738 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1740 STATS(jniinvokation();)
1741 log_text("JNI-Call: CallDoubleMethodA");
1747 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1750 STATS(jniinvokation();)
1752 va_start(vaargs,methodID);
1753 (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
1758 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1760 log_text("JNI-Call: CallVoidMethodV");
1761 STATS(jniinvokation();)
1762 (void)callIntegerMethod(obj,get_virtual(obj,methodID),TYPE_VOID,args);
1766 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1768 STATS(jniinvokation();)
1769 log_text("JNI-Call: CallVoidMethodA");
1774 jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1776 STATS(jniinvokation();)
1778 log_text("JNI-Call: CallNonvirtualObjectMethod: IMPLEMENT ME!");
1780 return NewLocalRef(env, NULL);
1784 jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1786 STATS(jniinvokation();)
1788 log_text("JNI-Call: CallNonvirtualObjectMethodV: IMPLEMENT ME!");
1790 return NewLocalRef(env, NULL);
1794 jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1796 STATS(jniinvokation();)
1798 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1800 return NewLocalRef(env, NULL);
1805 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1809 STATS(jniinvokation();)
1811 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1813 va_start(vaargs,methodID);
1814 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1821 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1823 STATS(jniinvokation();)
1824 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1825 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
1829 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1831 STATS(jniinvokation();)
1832 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1839 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1844 STATS(jniinvokation();)
1845 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1847 va_start(vaargs,methodID);
1848 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
1854 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1856 STATS(jniinvokation();)
1857 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1858 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
1863 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1865 STATS(jniinvokation();)
1866 log_text("JNI-Call: CallNonvirtualByteMethodA");
1873 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1878 STATS(jniinvokation();)
1879 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1881 va_start(vaargs,methodID);
1882 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
1888 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1890 STATS(jniinvokation();)
1891 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1892 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
1896 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1898 STATS(jniinvokation();)
1899 log_text("JNI-Call: CallNonvirtualCharMethodA");
1906 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1910 STATS(jniinvokation();)
1912 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1914 va_start(vaargs,methodID);
1915 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
1921 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1923 STATS(jniinvokation();)
1924 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1925 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
1929 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1931 STATS(jniinvokation();)
1932 log_text("JNI-Call: CallNonvirtualShortMethodA");
1939 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1944 STATS(jniinvokation();)
1946 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1948 va_start(vaargs,methodID);
1949 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
1955 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1957 STATS(jniinvokation();)
1958 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1959 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
1963 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1965 STATS(jniinvokation();)
1966 log_text("JNI-Call: CallNonvirtualIntMethodA");
1973 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1975 STATS(jniinvokation();)
1976 log_text("JNI-Call: CallNonvirtualLongMethod");
1982 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1984 STATS(jniinvokation();)
1985 log_text("JNI-Call: CallNonvirtualLongMethodV");
1991 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1993 STATS(jniinvokation();)
1994 log_text("JNI-Call: CallNonvirtualLongMethodA");
2001 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2005 STATS(jniinvokation();)
2007 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
2010 va_start(vaargs,methodID);
2011 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
2018 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2020 STATS(jniinvokation();)
2021 log_text("JNI-Call: CallNonvirtualFloatMethodV");
2022 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
2026 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2028 STATS(jniinvokation();)
2029 log_text("JNI-Call: CallNonvirtualFloatMethodA");
2036 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2040 STATS(jniinvokation();)
2041 log_text("JNI-Call: CallNonvirtualDoubleMethod");
2043 va_start(vaargs,methodID);
2044 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
2051 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2053 STATS(jniinvokation();)
2054 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
2055 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
2059 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2061 STATS(jniinvokation();)
2062 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
2069 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2072 STATS(jniinvokation();)
2074 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
2076 va_start(vaargs,methodID);
2077 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
2083 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2085 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
2086 STATS(jniinvokation();)
2088 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
2093 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
2095 STATS(jniinvokation();)
2096 log_text("JNI-Call: CallNonvirtualVoidMethodA");
2100 /* Accessing Fields of Objects ************************************************/
2102 /* GetFieldID ******************************************************************
2104 Returns the field ID for an instance (nonstatic) field of a
2105 class. The field is specified by its name and signature. The
2106 Get<type>Field and Set<type>Field families of accessor functions
2107 use field IDs to retrieve object fields.
2109 *******************************************************************************/
2111 jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2118 STATS(jniinvokation();)
2120 uname = utf_new_char((char *) name);
2121 udesc = utf_new_char((char *) sig);
2123 f = class_findfield(clazz, uname, udesc);
2126 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2132 /* Get<type>Field Routines *****************************************************
2134 This family of accessor routines returns the value of an instance
2135 (nonstatic) field of an object. The field to access is specified by
2136 a field ID obtained by calling GetFieldID().
2138 *******************************************************************************/
2140 jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2142 java_objectheader *o;
2144 STATS(jniinvokation();)
2146 o = GET_FIELD(obj, java_objectheader*, fieldID);
2148 return NewLocalRef(env, o);
2152 jboolean GetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID)
2156 STATS(jniinvokation();)
2158 i = GET_FIELD(obj, s4, fieldID);
2160 return (jboolean) i;
2164 jbyte GetByteField(JNIEnv *env, jobject obj, jfieldID fieldID)
2168 STATS(jniinvokation();)
2170 i = GET_FIELD(obj, s4, fieldID);
2176 jchar GetCharField(JNIEnv *env, jobject obj, jfieldID fieldID)
2180 STATS(jniinvokation();)
2182 i = GET_FIELD(obj, s4, fieldID);
2188 jshort GetShortField(JNIEnv *env, jobject obj, jfieldID fieldID)
2192 STATS(jniinvokation();)
2194 i = GET_FIELD(obj, s4, fieldID);
2200 jint GetIntField(JNIEnv *env, jobject obj, jfieldID fieldID)
2204 STATS(jniinvokation();)
2206 i = GET_FIELD(obj, s4, fieldID);
2212 jlong GetLongField(JNIEnv *env, jobject obj, jfieldID fieldID)
2216 STATS(jniinvokation();)
2218 l = GET_FIELD(obj, s8, fieldID);
2224 jfloat GetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID)
2228 STATS(jniinvokation();)
2230 f = GET_FIELD(obj, float, fieldID);
2236 jdouble GetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID)
2240 STATS(jniinvokation();)
2242 d = GET_FIELD(obj, double, fieldID);
2248 /* Set<type>Field Routines *****************************************************
2250 This family of accessor routines sets the value of an instance
2251 (nonstatic) field of an object. The field to access is specified by
2252 a field ID obtained by calling GetFieldID().
2254 *******************************************************************************/
2256 void SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value)
2258 STATS(jniinvokation();)
2260 SET_FIELD(obj, java_objectheader*, fieldID, value);
2264 void SetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID, jboolean value)
2266 STATS(jniinvokation();)
2268 SET_FIELD(obj, s4, fieldID, value);
2272 void SetByteField(JNIEnv *env, jobject obj, jfieldID fieldID, jbyte value)
2274 STATS(jniinvokation();)
2276 SET_FIELD(obj, s4, fieldID, value);
2280 void SetCharField(JNIEnv *env, jobject obj, jfieldID fieldID, jchar value)
2282 STATS(jniinvokation();)
2284 SET_FIELD(obj, s4, fieldID, value);
2288 void SetShortField(JNIEnv *env, jobject obj, jfieldID fieldID, jshort value)
2290 STATS(jniinvokation();)
2292 SET_FIELD(obj, s4, fieldID, value);
2296 void SetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint value)
2298 STATS(jniinvokation();)
2300 SET_FIELD(obj, s4, fieldID, value);
2304 void SetLongField(JNIEnv *env, jobject obj, jfieldID fieldID, jlong value)
2306 STATS(jniinvokation();)
2308 SET_FIELD(obj, s8, fieldID, value);
2312 void SetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID, jfloat value)
2314 STATS(jniinvokation();)
2316 SET_FIELD(obj, float, fieldID, value);
2320 void SetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID, jdouble value)
2322 STATS(jniinvokation();)
2324 SET_FIELD(obj, double, fieldID, value);
2328 /* Calling Static Methods *****************************************************/
2330 /* GetStaticMethodID ***********************************************************
2332 Returns the method ID for a static method of a class. The method is
2333 specified by its name and signature.
2335 GetStaticMethodID() causes an uninitialized class to be
2338 *******************************************************************************/
2340 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2348 STATS(jniinvokation();)
2350 c = (classinfo *) clazz;
2355 if (!(c->state & CLASS_INITIALIZED))
2356 if (!initialize_class(c))
2359 /* try to get the static method of the class */
2361 uname = utf_new_char((char *) name);
2362 udesc = utf_new_char((char *) sig);
2364 m = class_resolvemethod(c, uname, udesc);
2366 if (!m || !(m->flags & ACC_STATIC)) {
2367 *exceptionptr = exceptions_new_nosuchmethoderror(c, uname, udesc);
2376 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2378 java_objectheader *ret;
2381 STATS(jniinvokation();)
2383 va_start(vaargs, methodID);
2384 ret = callObjectMethod(0, methodID, vaargs);
2387 return NewLocalRef(env, ret);
2391 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2393 java_objectheader *ret;
2395 STATS(jniinvokation();)
2397 ret = callObjectMethod(0, methodID, args);
2399 return NewLocalRef(env, ret);
2403 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2405 STATS(jniinvokation();)
2407 log_text("JNI-Call: CallStaticObjectMethodA: IMPLEMENT ME!");
2409 return NewLocalRef(env, NULL);
2413 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2418 STATS(jniinvokation();)
2420 va_start(vaargs, methodID);
2421 ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
2428 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2430 STATS(jniinvokation();)
2432 return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
2436 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2438 STATS(jniinvokation();)
2440 log_text("JNI-Call: CallStaticBooleanMethodA: IMPLEMENT ME!");
2446 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2451 STATS(jniinvokation();)
2453 va_start(vaargs, methodID);
2454 ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
2461 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2463 STATS(jniinvokation();)
2464 return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
2468 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2470 STATS(jniinvokation();)
2472 log_text("JNI-Call: CallStaticByteMethodA: IMPLEMENT ME!");
2478 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2483 STATS(jniinvokation();)
2485 va_start(vaargs, methodID);
2486 ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
2493 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2495 STATS(jniinvokation();)
2497 return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
2501 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2503 STATS(jniinvokation();)
2505 log_text("JNI-Call: CallStaticCharMethodA: IMPLEMENT ME!");
2511 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2516 STATS(jniinvokation();)
2518 va_start(vaargs, methodID);
2519 ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
2526 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2528 STATS(jniinvokation();)
2530 return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
2534 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2536 STATS(jniinvokation();)
2538 log_text("JNI-Call: CallStaticShortMethodA: IMPLEMENT ME!");
2544 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2549 STATS(jniinvokation();)
2551 va_start(vaargs, methodID);
2552 ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
2559 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2561 STATS(jniinvokation();)
2563 return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
2567 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2569 STATS(jniinvokation();)
2571 log_text("JNI-Call: CallStaticIntMethodA: IMPLEMENT ME!");
2577 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2582 STATS(jniinvokation();)
2584 va_start(vaargs, methodID);
2585 ret = callLongMethod(0, methodID, vaargs);
2592 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
2595 STATS(jniinvokation();)
2597 return callLongMethod(0, methodID, args);
2601 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2603 STATS(jniinvokation();)
2605 log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!");
2612 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2617 STATS(jniinvokation();)
2619 va_start(vaargs, methodID);
2620 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
2627 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2629 STATS(jniinvokation();)
2631 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
2636 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2638 STATS(jniinvokation();)
2640 log_text("JNI-Call: CallStaticFloatMethodA: IMPLEMENT ME!");
2646 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2651 STATS(jniinvokation();)
2653 va_start(vaargs,methodID);
2654 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
2661 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2663 STATS(jniinvokation();)
2665 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
2669 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2671 STATS(jniinvokation();)
2673 log_text("JNI-Call: CallStaticDoubleMethodA: IMPLEMENT ME!");
2679 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2683 STATS(jniinvokation();)
2685 va_start(vaargs, methodID);
2686 (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
2691 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2693 STATS(jniinvokation();)
2695 (void) callIntegerMethod(0, methodID, TYPE_VOID, args);
2699 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2701 STATS(jniinvokation();)
2703 log_text("JNI-Call: CallStaticVoidMethodA: IMPLEMENT ME!");
2707 /* Accessing Static Fields ****************************************************/
2709 /* GetStaticFieldID ************************************************************
2711 Returns the field ID for a static field of a class. The field is
2712 specified by its name and signature. The GetStatic<type>Field and
2713 SetStatic<type>Field families of accessor functions use field IDs
2714 to retrieve static fields.
2716 *******************************************************************************/
2718 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2721 STATS(jniinvokation();)
2723 f = class_findfield(clazz,
2724 utf_new_char((char *) name),
2725 utf_new_char((char *) sig));
2728 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2734 /* GetStatic<type>Field ********************************************************
2736 This family of accessor routines returns the value of a static
2739 *******************************************************************************/
2741 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2743 STATS(jniinvokation();)
2745 if (!(clazz->state & CLASS_INITIALIZED))
2746 if (!initialize_class(clazz))
2749 return NewLocalRef(env, fieldID->value.a);
2753 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2755 STATS(jniinvokation();)
2757 if (!(clazz->state & CLASS_INITIALIZED))
2758 if (!initialize_class(clazz))
2761 return fieldID->value.i;
2765 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2767 STATS(jniinvokation();)
2769 if (!(clazz->state & CLASS_INITIALIZED))
2770 if (!initialize_class(clazz))
2773 return fieldID->value.i;
2777 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2779 STATS(jniinvokation();)
2781 if (!(clazz->state & CLASS_INITIALIZED))
2782 if (!initialize_class(clazz))
2785 return fieldID->value.i;
2789 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2791 STATS(jniinvokation();)
2793 if (!(clazz->state & CLASS_INITIALIZED))
2794 if (!initialize_class(clazz))
2797 return fieldID->value.i;
2801 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2803 STATS(jniinvokation();)
2805 if (!(clazz->state & CLASS_INITIALIZED))
2806 if (!initialize_class(clazz))
2809 return fieldID->value.i;
2813 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2815 STATS(jniinvokation();)
2817 if (!(clazz->state & CLASS_INITIALIZED))
2818 if (!initialize_class(clazz))
2821 return fieldID->value.l;
2825 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2827 STATS(jniinvokation();)
2829 if (!(clazz->state & CLASS_INITIALIZED))
2830 if (!initialize_class(clazz))
2833 return fieldID->value.f;
2837 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2839 STATS(jniinvokation();)
2841 if (!(clazz->state & CLASS_INITIALIZED))
2842 if (!initialize_class(clazz))
2845 return fieldID->value.d;
2849 /* SetStatic<type>Field *******************************************************
2851 This family of accessor routines sets the value of a static field
2854 *******************************************************************************/
2856 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2858 STATS(jniinvokation();)
2860 if (!(clazz->state & CLASS_INITIALIZED))
2861 if (!initialize_class(clazz))
2864 fieldID->value.a = value;
2868 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2870 STATS(jniinvokation();)
2872 if (!(clazz->state & CLASS_INITIALIZED))
2873 if (!initialize_class(clazz))
2876 fieldID->value.i = value;
2880 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2882 STATS(jniinvokation();)
2884 if (!(clazz->state & CLASS_INITIALIZED))
2885 if (!initialize_class(clazz))
2888 fieldID->value.i = value;
2892 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2894 STATS(jniinvokation();)
2896 if (!(clazz->state & CLASS_INITIALIZED))
2897 if (!initialize_class(clazz))
2900 fieldID->value.i = value;
2904 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2906 STATS(jniinvokation();)
2908 if (!(clazz->state & CLASS_INITIALIZED))
2909 if (!initialize_class(clazz))
2912 fieldID->value.i = value;
2916 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2918 STATS(jniinvokation();)
2920 if (!(clazz->state & CLASS_INITIALIZED))
2921 if (!initialize_class(clazz))
2924 fieldID->value.i = value;
2928 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2930 STATS(jniinvokation();)
2932 if (!(clazz->state & CLASS_INITIALIZED))
2933 if (!initialize_class(clazz))
2936 fieldID->value.l = value;
2940 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2942 STATS(jniinvokation();)
2944 if (!(clazz->state & CLASS_INITIALIZED))
2945 if (!initialize_class(clazz))
2948 fieldID->value.f = value;
2952 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2954 STATS(jniinvokation();)
2956 if (!(clazz->state & CLASS_INITIALIZED))
2957 if (!initialize_class(clazz))
2960 fieldID->value.d = value;
2964 /* String Operations **********************************************************/
2966 /* NewString *******************************************************************
2968 Create new java.lang.String object from an array of Unicode
2971 *******************************************************************************/
2973 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
2975 java_lang_String *s;
2979 STATS(jniinvokation();)
2981 s = (java_lang_String *) builtin_new(class_java_lang_String);
2982 a = builtin_newarray_char(len);
2984 /* javastring or characterarray could not be created */
2989 for (i = 0; i < len; i++)
2990 a->data[i] = buf[i];
2996 return (jstring) NewLocalRef(env, (jobject) s);
3000 static jchar emptyStringJ[]={0,0};
3002 /* GetStringLength *************************************************************
3004 Returns the length (the count of Unicode characters) of a Java
3007 *******************************************************************************/
3009 jsize GetStringLength(JNIEnv *env, jstring str)
3011 return ((java_lang_String *) str)->count;
3015 /******************** convertes javastring to u2-array ****************************/
3017 u2 *javastring_tou2(jstring so)
3019 java_lang_String *s;
3024 STATS(jniinvokation();)
3026 s = (java_lang_String *) so;
3036 /* allocate memory */
3038 stringbuffer = MNEW(u2, s->count + 1);
3042 for (i = 0; i < s->count; i++)
3043 stringbuffer[i] = a->data[s->offset + i];
3045 /* terminate string */
3047 stringbuffer[i] = '\0';
3049 return stringbuffer;
3053 /* GetStringChars **************************************************************
3055 Returns a pointer to the array of Unicode characters of the
3056 string. This pointer is valid until ReleaseStringchars() is called.
3058 *******************************************************************************/
3060 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
3064 STATS(jniinvokation();)
3066 jc = javastring_tou2(str);
3078 return emptyStringJ;
3082 /* ReleaseStringChars **********************************************************
3084 Informs the VM that the native code no longer needs access to
3085 chars. The chars argument is a pointer obtained from string using
3088 *******************************************************************************/
3090 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
3092 STATS(jniinvokation();)
3094 if (chars == emptyStringJ)
3097 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
3101 /* NewStringUTF ****************************************************************
3103 Constructs a new java.lang.String object from an array of UTF-8 characters.
3105 *******************************************************************************/
3107 jstring NewStringUTF(JNIEnv *env, const char *bytes)
3109 java_lang_String *s;
3111 STATS(jniinvokation();)
3113 s = javastring_new(utf_new_char(bytes));
3115 return (jstring) NewLocalRef(env, (jobject) s);
3119 /****************** returns the utf8 length in bytes of a string *******************/
3121 jsize GetStringUTFLength (JNIEnv *env, jstring string)
3123 java_lang_String *s = (java_lang_String*) string;
3124 STATS(jniinvokation();)
3126 return (jsize) u2_utflength(s->value->data, s->count);
3130 /* GetStringUTFChars ***********************************************************
3132 Returns a pointer to an array of UTF-8 characters of the
3133 string. This array is valid until it is released by
3134 ReleaseStringUTFChars().
3136 *******************************************************************************/
3138 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
3141 STATS(jniinvokation();)
3149 u = javastring_toutf((java_lang_String *) string, false);
3158 /* ReleaseStringUTFChars *******************************************************
3160 Informs the VM that the native code no longer needs access to
3161 utf. The utf argument is a pointer derived from string using
3162 GetStringUTFChars().
3164 *******************************************************************************/
3166 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
3168 STATS(jniinvokation();)
3170 /* XXX we don't release utf chars right now, perhaps that should be done
3171 later. Since there is always one reference the garbage collector will
3176 /* Array Operations ***********************************************************/
3178 /* GetArrayLength **************************************************************
3180 Returns the number of elements in the array.
3182 *******************************************************************************/
3184 jsize GetArrayLength(JNIEnv *env, jarray array)
3186 STATS(jniinvokation();)
3192 /* NewObjectArray **************************************************************
3194 Constructs a new array holding objects in class elementClass. All
3195 elements are initially set to initialElement.
3197 *******************************************************************************/
3199 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
3201 java_objectarray *oa;
3204 STATS(jniinvokation();)
3207 *exceptionptr = new_negativearraysizeexception();
3211 oa = builtin_anewarray(length, elementClass);
3216 /* set all elements to initialElement */
3218 for (i = 0; i < length; i++)
3219 oa->data[i] = initialElement;
3221 return (jobjectArray) NewLocalRef(env, (jobject) oa);
3225 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
3229 STATS(jniinvokation();)
3231 if (index >= array->header.size) {
3233 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3237 o = array->data[index];
3239 return NewLocalRef(env, o);
3243 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3245 STATS(jniinvokation();)
3246 if (index >= array->header.size)
3247 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3250 /* check if the class of value is a subclass of the element class of the array */
3251 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
3252 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3255 array->data[index] = val;
3260 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3262 java_booleanarray *ba;
3264 STATS(jniinvokation();)
3267 *exceptionptr = new_negativearraysizeexception();
3271 ba = builtin_newarray_boolean(len);
3273 return (jbooleanArray) NewLocalRef(env, (jobject) ba);
3277 jbyteArray NewByteArray(JNIEnv *env, jsize len)
3281 STATS(jniinvokation();)
3284 *exceptionptr = new_negativearraysizeexception();
3288 ba = builtin_newarray_byte(len);
3290 return (jbyteArray) NewLocalRef(env, (jobject) ba);
3294 jcharArray NewCharArray(JNIEnv *env, jsize len)
3298 STATS(jniinvokation();)
3301 *exceptionptr = new_negativearraysizeexception();
3305 ca = builtin_newarray_char(len);
3307 return (jcharArray) NewLocalRef(env, (jobject) ca);
3311 jshortArray NewShortArray(JNIEnv *env, jsize len)
3313 java_shortarray *sa;
3315 STATS(jniinvokation();)
3318 *exceptionptr = new_negativearraysizeexception();
3322 sa = builtin_newarray_short(len);
3324 return (jshortArray) NewLocalRef(env, (jobject) sa);
3328 jintArray NewIntArray(JNIEnv *env, jsize len)
3332 STATS(jniinvokation();)
3335 *exceptionptr = new_negativearraysizeexception();
3339 ia = builtin_newarray_int(len);
3341 return (jintArray) NewLocalRef(env, (jobject) ia);
3345 jlongArray NewLongArray(JNIEnv *env, jsize len)
3349 STATS(jniinvokation();)
3352 *exceptionptr = new_negativearraysizeexception();
3356 la = builtin_newarray_long(len);
3358 return (jlongArray) NewLocalRef(env, (jobject) la);
3362 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3364 java_floatarray *fa;
3366 STATS(jniinvokation();)
3369 *exceptionptr = new_negativearraysizeexception();
3373 fa = builtin_newarray_float(len);
3375 return (jfloatArray) NewLocalRef(env, (jobject) fa);
3379 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3381 java_doublearray *da;
3383 STATS(jniinvokation();)
3386 *exceptionptr = new_negativearraysizeexception();
3390 da = builtin_newarray_double(len);
3392 return (jdoubleArray) NewLocalRef(env, (jobject) da);
3396 /* Get<PrimitiveType>ArrayElements *********************************************
3398 A family of functions that returns the body of the primitive array.
3400 *******************************************************************************/
3402 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3405 STATS(jniinvokation();)
3408 *isCopy = JNI_FALSE;
3414 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3416 STATS(jniinvokation();)
3419 *isCopy = JNI_FALSE;
3425 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3427 STATS(jniinvokation();)
3430 *isCopy = JNI_FALSE;
3436 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3438 STATS(jniinvokation();)
3441 *isCopy = JNI_FALSE;
3447 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3449 STATS(jniinvokation();)
3452 *isCopy = JNI_FALSE;
3458 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3460 STATS(jniinvokation();)
3463 *isCopy = JNI_FALSE;
3469 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3471 STATS(jniinvokation();)
3474 *isCopy = JNI_FALSE;
3480 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3483 STATS(jniinvokation();)
3486 *isCopy = JNI_FALSE;
3492 /* Release<PrimitiveType>ArrayElements *****************************************
3494 A family of functions that informs the VM that the native code no
3495 longer needs access to elems. The elems argument is a pointer
3496 derived from array using the corresponding
3497 Get<PrimitiveType>ArrayElements() function. If necessary, this
3498 function copies back all changes made to elems to the original
3501 *******************************************************************************/
3503 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3504 jboolean *elems, jint mode)
3506 STATS(jniinvokation();)
3508 if (elems != array->data) {
3511 MCOPY(array->data, elems, jboolean, array->header.size);
3514 MCOPY(array->data, elems, jboolean, array->header.size);
3515 /* XXX TWISTI how should it be freed? */
3518 /* XXX TWISTI how should it be freed? */
3525 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
3528 STATS(jniinvokation();)
3530 if (elems != array->data) {
3533 MCOPY(array->data, elems, jboolean, array->header.size);
3536 MCOPY(array->data, elems, jboolean, array->header.size);
3537 /* XXX TWISTI how should it be freed? */
3540 /* XXX TWISTI how should it be freed? */
3547 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
3550 STATS(jniinvokation();)
3552 if (elems != array->data) {
3555 MCOPY(array->data, elems, jboolean, array->header.size);
3558 MCOPY(array->data, elems, jboolean, array->header.size);
3559 /* XXX TWISTI how should it be freed? */
3562 /* XXX TWISTI how should it be freed? */
3569 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
3572 STATS(jniinvokation();)
3574 if (elems != array->data) {
3577 MCOPY(array->data, elems, jboolean, array->header.size);
3580 MCOPY(array->data, elems, jboolean, array->header.size);
3581 /* XXX TWISTI how should it be freed? */
3584 /* XXX TWISTI how should it be freed? */
3591 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
3594 STATS(jniinvokation();)
3596 if (elems != array->data) {
3599 MCOPY(array->data, elems, jboolean, array->header.size);
3602 MCOPY(array->data, elems, jboolean, array->header.size);
3603 /* XXX TWISTI how should it be freed? */
3606 /* XXX TWISTI how should it be freed? */
3613 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
3616 STATS(jniinvokation();)
3618 if (elems != array->data) {
3621 MCOPY(array->data, elems, jboolean, array->header.size);
3624 MCOPY(array->data, elems, jboolean, array->header.size);
3625 /* XXX TWISTI how should it be freed? */
3628 /* XXX TWISTI how should it be freed? */
3635 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
3638 STATS(jniinvokation();)
3640 if (elems != array->data) {
3643 MCOPY(array->data, elems, jboolean, array->header.size);
3646 MCOPY(array->data, elems, jboolean, array->header.size);
3647 /* XXX TWISTI how should it be freed? */
3650 /* XXX TWISTI how should it be freed? */
3657 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3658 jdouble *elems, jint mode)
3660 STATS(jniinvokation();)
3662 if (elems != array->data) {
3665 MCOPY(array->data, elems, jboolean, array->header.size);
3668 MCOPY(array->data, elems, jboolean, array->header.size);
3669 /* XXX TWISTI how should it be freed? */
3672 /* XXX TWISTI how should it be freed? */
3679 /* Get<PrimitiveType>ArrayRegion **********************************************
3681 A family of functions that copies a region of a primitive array
3684 *******************************************************************************/
3686 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3687 jsize len, jboolean *buf)
3689 STATS(jniinvokation();)
3691 if (start < 0 || len < 0 || start + len > array->header.size)
3693 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3696 MCOPY(buf, &array->data[start], jboolean, len);
3700 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3703 STATS(jniinvokation();)
3705 if (start < 0 || len < 0 || start + len > array->header.size)
3707 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3710 MCOPY(buf, &array->data[start], jbyte, len);
3714 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3717 STATS(jniinvokation();)
3719 if (start < 0 || len < 0 || start + len > array->header.size)
3721 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3724 MCOPY(buf, &array->data[start], jchar, len);
3728 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3729 jsize len, jshort *buf)
3731 STATS(jniinvokation();)
3733 if (start < 0 || len < 0 || start + len > array->header.size)
3735 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3738 MCOPY(buf, &array->data[start], jshort, len);
3742 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3745 STATS(jniinvokation();)
3747 if (start < 0 || len < 0 || start + len > array->header.size)
3749 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3752 MCOPY(buf, &array->data[start], jint, len);
3756 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
3759 STATS(jniinvokation();)
3761 if (start < 0 || len < 0 || start + len > array->header.size)
3763 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3766 MCOPY(buf, &array->data[start], jlong, len);
3770 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3771 jsize len, jfloat *buf)
3773 STATS(jniinvokation();)
3775 if (start < 0 || len < 0 || start + len > array->header.size)
3777 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3780 MCOPY(buf, &array->data[start], jfloat, len);
3784 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3785 jsize len, jdouble *buf)
3787 STATS(jniinvokation();)
3789 if (start < 0 || len < 0 || start+len>array->header.size)
3791 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3794 MCOPY(buf, &array->data[start], jdouble, len);
3798 /* Set<PrimitiveType>ArrayRegion **********************************************
3800 A family of functions that copies back a region of a primitive
3801 array from a buffer.
3803 *******************************************************************************/
3805 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3806 jsize len, jboolean *buf)
3808 STATS(jniinvokation();)
3810 if (start < 0 || len < 0 || start + len > array->header.size)
3812 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3815 MCOPY(&array->data[start], buf, jboolean, len);
3819 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3822 STATS(jniinvokation();)
3824 if (start < 0 || len < 0 || start + len > array->header.size)
3826 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3829 MCOPY(&array->data[start], buf, jbyte, len);
3833 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3836 STATS(jniinvokation();)
3838 if (start < 0 || len < 0 || start + len > array->header.size)
3840 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3843 MCOPY(&array->data[start], buf, jchar, len);
3848 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3849 jsize len, jshort *buf)
3851 STATS(jniinvokation();)
3853 if (start < 0 || len < 0 || start + len > array->header.size)
3855 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3858 MCOPY(&array->data[start], buf, jshort, len);
3862 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3865 STATS(jniinvokation();)
3867 if (start < 0 || len < 0 || start + len > array->header.size)
3869 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3872 MCOPY(&array->data[start], buf, jint, len);
3877 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
3880 STATS(jniinvokation();)
3882 if (start < 0 || len < 0 || start + len > array->header.size)
3884 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3887 MCOPY(&array->data[start], buf, jlong, len);
3892 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3893 jsize len, jfloat *buf)
3895 STATS(jniinvokation();)
3897 if (start < 0 || len < 0 || start + len > array->header.size)
3899 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3902 MCOPY(&array->data[start], buf, jfloat, len);
3907 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3908 jsize len, jdouble *buf)
3910 STATS(jniinvokation();)
3912 if (start < 0 || len < 0 || start + len > array->header.size)
3914 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3917 MCOPY(&array->data[start], buf, jdouble, len);
3921 /* Registering Native Methods *************************************************/
3923 /* RegisterNatives *************************************************************
3925 Registers native methods with the class specified by the clazz
3926 argument. The methods parameter specifies an array of
3927 JNINativeMethod structures that contain the names, signatures, and
3928 function pointers of the native methods. The nMethods parameter
3929 specifies the number of native methods in the array.
3931 *******************************************************************************/
3933 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
3936 STATS(jniinvokation();)
3938 log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
3944 /* UnregisterNatives ***********************************************************
3946 Unregisters native methods of a class. The class goes back to the
3947 state before it was linked or registered with its native method
3950 This function should not be used in normal native code. Instead, it
3951 provides special programs a way to reload and relink native
3954 *******************************************************************************/
3956 jint UnregisterNatives(JNIEnv *env, jclass clazz)
3958 STATS(jniinvokation();)
3960 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3962 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3968 /* Monitor Operations *********************************************************/
3970 /* MonitorEnter ****************************************************************
3972 Enters the monitor associated with the underlying Java object
3975 *******************************************************************************/
3977 jint MonitorEnter(JNIEnv *env, jobject obj)
3979 STATS(jniinvokation();)
3982 *exceptionptr = new_nullpointerexception();
3986 #if defined(USE_THREADS)
3987 builtin_monitorenter(obj);
3994 /* MonitorExit *****************************************************************
3996 The current thread must be the owner of the monitor associated with
3997 the underlying Java object referred to by obj. The thread
3998 decrements the counter indicating the number of times it has
3999 entered this monitor. If the value of the counter becomes zero, the
4000 current thread releases the monitor.
4002 *******************************************************************************/
4004 jint MonitorExit(JNIEnv *env, jobject obj)
4006 STATS(jniinvokation();)
4008 *exceptionptr = new_nullpointerexception();
4012 #if defined(USE_THREADS)
4013 builtin_monitorexit(obj);
4020 /* JavaVM Interface ***********************************************************/
4022 /* GetJavaVM *******************************************************************
4024 Returns the Java VM interface (used in the Invocation API)
4025 associated with the current thread. The result is placed at the
4026 location pointed to by the second argument, vm.
4028 *******************************************************************************/
4030 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
4032 STATS(jniinvokation();)
4039 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
4041 STATS(jniinvokation();)
4042 log_text("JNI-Call: GetStringRegion");
4046 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
4048 STATS(jniinvokation();)
4050 log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
4054 /* GetPrimitiveArrayCritical ***************************************************
4056 Obtain a direct pointer to array elements.
4058 *******************************************************************************/
4060 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
4065 ba = (java_bytearray *) array;
4067 /* do the same as Kaffe does */
4069 bp = GetByteArrayElements(env, ba, isCopy);
4075 /* ReleasePrimitiveArrayCritical ***********************************************
4077 No specific documentation.
4079 *******************************************************************************/
4081 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
4084 STATS(jniinvokation();)
4086 /* do the same as Kaffe does */
4088 ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
4092 /* GetStringCritical ***********************************************************
4094 The semantics of these two functions are similar to the existing
4095 Get/ReleaseStringChars functions.
4097 *******************************************************************************/
4099 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
4101 STATS(jniinvokation();)
4103 return GetStringChars(env, string, isCopy);
4107 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
4109 STATS(jniinvokation();)
4111 ReleaseStringChars(env, string, cstring);
4115 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
4117 STATS(jniinvokation();)
4118 log_text("JNI-Call: NewWeakGlobalRef");
4124 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
4126 STATS(jniinvokation();)
4127 log_text("JNI-Call: DeleteWeakGlobalRef");
4133 /* NewGlobalRef ****************************************************************
4135 Creates a new global reference to the object referred to by the obj
4138 *******************************************************************************/
4140 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4142 java_lang_Integer *refcount;
4143 java_objectheader *newval;
4145 STATS(jniinvokation();)
4147 #if defined(USE_THREADS)
4148 builtin_monitorenter(*global_ref_table);
4151 refcount = (java_lang_Integer *)
4152 asm_calljavafunction(getmid, *global_ref_table, lobj, NULL, NULL);
4154 if (refcount == NULL) {
4155 newval = native_new_and_init_int(class_java_lang_Integer, 1);
4157 if (newval == NULL) {
4158 #if defined(USE_THREADS)
4159 builtin_monitorexit(*global_ref_table);
4164 asm_calljavafunction(putmid, *global_ref_table, lobj, newval, NULL);
4167 /* we can access the object itself, as we are in a
4168 synchronized section */
4173 #if defined(USE_THREADS)
4174 builtin_monitorexit(*global_ref_table);
4181 /* DeleteGlobalRef *************************************************************
4183 Deletes the global reference pointed to by globalRef.
4185 *******************************************************************************/
4187 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
4189 java_lang_Integer *refcount;
4192 STATS(jniinvokation();)
4194 #if defined(USE_THREADS)
4195 builtin_monitorenter(*global_ref_table);
4198 refcount = (java_lang_Integer *)
4199 asm_calljavafunction(getmid, *global_ref_table, globalRef, NULL, NULL);
4201 if (refcount == NULL) {
4202 log_text("JNI-DeleteGlobalRef: unable to find global reference");
4206 /* we can access the object itself, as we are in a synchronized
4209 val = refcount->value - 1;
4212 asm_calljavafunction(removemid, *global_ref_table, refcount, NULL,
4216 /* we do not create a new object, but set the new value into
4219 refcount->value = val;
4222 #if defined(USE_THREADS)
4223 builtin_monitorexit(*global_ref_table);
4228 /* ExceptionCheck **************************************************************
4230 Returns JNI_TRUE when there is a pending exception; otherwise,
4233 *******************************************************************************/
4235 jboolean ExceptionCheck(JNIEnv *env)
4237 STATS(jniinvokation();)
4238 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
4242 /* New JNI 1.4 functions ******************************************************/
4244 /* NewDirectByteBuffer *********************************************************
4246 Allocates and returns a direct java.nio.ByteBuffer referring to the
4247 block of memory starting at the memory address address and
4248 extending capacity bytes.
4250 *******************************************************************************/
4252 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
4254 java_objectheader *nbuf;
4255 #if SIZEOF_VOID_P == 8
4256 gnu_classpath_Pointer64 *paddress;
4258 gnu_classpath_Pointer32 *paddress;
4261 STATS(jniinvokation();)
4263 log_text("JNI-NewDirectByteBuffer: called");
4266 /* allocate a java.nio.DirectByteBufferImpl$ReadWrite object */
4268 if (!(nbuf = (java_nio_DirectByteBufferImpl$ReadWrite *)
4269 builtin_new(class_java_nio_DirectByteBufferImpl_ReadWrite)))
4273 /* alocate a gnu.classpath.Pointer{32,64} object */
4275 #if SIZEOF_VOID_P == 8
4276 if (!(paddress = (gnu_classpath_Pointer64 *)
4277 builtin_new(class_gnu_classpath_Pointer64)))
4279 if (!(paddress = (gnu_classpath_Pointer32 *)
4280 builtin_new(class_gnu_classpath_Pointer32)))
4284 /* fill gnu.classpath.Pointer{32,64} with address */
4286 paddress->data = (ptrint) address;
4289 /* fill java.nio.Buffer object */
4291 nbuf->cap = (s4) capacity;
4292 nbuf->limit = (s4) capacity;
4294 nbuf->address = (gnu_classpath_Pointer *) paddress;
4297 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
4298 dbbirw_init, NULL, paddress,
4299 (jint) capacity, (jint) capacity, (jint) 0);
4301 /* add local reference and return the value */
4303 return NewLocalRef(env, nbuf);
4307 /* GetDirectBufferAddress ******************************************************
4309 Fetches and returns the starting address of the memory region
4310 referenced by the given direct java.nio.Buffer.
4312 *******************************************************************************/
4314 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
4316 java_nio_DirectByteBufferImpl *nbuf;
4317 #if SIZEOF_VOID_P == 8
4318 gnu_classpath_Pointer64 *address;
4320 gnu_classpath_Pointer32 *address;
4323 STATS(jniinvokation();)
4326 if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
4330 nbuf = (java_nio_DirectByteBufferImpl *) buf;
4332 #if SIZEOF_VOID_P == 8
4333 address = (gnu_classpath_Pointer64 *) nbuf->address;
4335 address = (gnu_classpath_Pointer32 *) nbuf->address;
4338 return (void *) address->data;
4342 /* GetDirectBufferCapacity *****************************************************
4344 Fetches and returns the capacity in bytes of the memory region
4345 referenced by the given direct java.nio.Buffer.
4347 *******************************************************************************/
4349 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
4351 java_nio_Buffer *nbuf;
4353 STATS(jniinvokation();)
4358 nbuf = (java_nio_Buffer *) buf;
4360 return (jlong) nbuf->cap;
4364 jint DestroyJavaVM(JavaVM *vm)
4366 STATS(jniinvokation();)
4367 log_text("DestroyJavaVM called");
4373 /* AttachCurrentThread *********************************************************
4375 Attaches the current thread to a Java VM. Returns a JNI interface
4376 pointer in the JNIEnv argument.
4378 Trying to attach a thread that is already attached is a no-op.
4380 A native thread cannot be attached simultaneously to two Java VMs.
4382 When a thread is attached to the VM, the context class loader is
4383 the bootstrap loader.
4385 *******************************************************************************/
4387 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
4389 STATS(jniinvokation();)
4391 log_text("AttachCurrentThread called");
4393 #if !defined(HAVE___THREAD)
4394 /* cacao_thread_attach();*/
4396 #error "No idea how to implement that. Perhaps Stefan knows"
4405 jint DetachCurrentThread(JavaVM *vm)
4407 STATS(jniinvokation();)
4408 log_text("DetachCurrentThread called");
4414 /* GetEnv **********************************************************************
4416 If the current thread is not attached to the VM, sets *env to NULL,
4417 and returns JNI_EDETACHED. If the specified version is not
4418 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
4419 sets *env to the appropriate interface, and returns JNI_OK.
4421 *******************************************************************************/
4423 jint GetEnv(JavaVM *vm, void **env, jint version)
4425 STATS(jniinvokation();)
4427 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4428 if (thread_getself() == NULL) {
4431 return JNI_EDETACHED;
4435 if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
4436 (version == JNI_VERSION_1_4)) {
4442 #if defined(ENABLE_JVMTI)
4443 if (version == JVMTI_VERSION_1_0) {
4444 *env = (void *) new_jvmtienv();
4453 return JNI_EVERSION;
4458 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4460 STATS(jniinvokation();)
4461 log_text("AttachCurrentThreadAsDaemon called");
4467 /* JNI invocation table *******************************************************/
4469 const struct JNIInvokeInterface JNI_JavaVMTable = {
4475 AttachCurrentThread,
4476 DetachCurrentThread,
4478 AttachCurrentThreadAsDaemon
4482 /* JNI function table *********************************************************/
4484 struct JNINativeInterface JNI_JNIEnvTable = {
4493 &FromReflectedMethod,
4494 &FromReflectedField,
4514 &EnsureLocalCapacity,
4530 &CallBooleanMethodV,
4531 &CallBooleanMethodA,
4557 &CallNonvirtualObjectMethod,
4558 &CallNonvirtualObjectMethodV,
4559 &CallNonvirtualObjectMethodA,
4560 &CallNonvirtualBooleanMethod,
4561 &CallNonvirtualBooleanMethodV,
4562 &CallNonvirtualBooleanMethodA,
4563 &CallNonvirtualByteMethod,
4564 &CallNonvirtualByteMethodV,
4565 &CallNonvirtualByteMethodA,
4566 &CallNonvirtualCharMethod,
4567 &CallNonvirtualCharMethodV,
4568 &CallNonvirtualCharMethodA,
4569 &CallNonvirtualShortMethod,
4570 &CallNonvirtualShortMethodV,
4571 &CallNonvirtualShortMethodA,
4572 &CallNonvirtualIntMethod,
4573 &CallNonvirtualIntMethodV,
4574 &CallNonvirtualIntMethodA,
4575 &CallNonvirtualLongMethod,
4576 &CallNonvirtualLongMethodV,
4577 &CallNonvirtualLongMethodA,
4578 &CallNonvirtualFloatMethod,
4579 &CallNonvirtualFloatMethodV,
4580 &CallNonvirtualFloatMethodA,
4581 &CallNonvirtualDoubleMethod,
4582 &CallNonvirtualDoubleMethodV,
4583 &CallNonvirtualDoubleMethodA,
4584 &CallNonvirtualVoidMethod,
4585 &CallNonvirtualVoidMethodV,
4586 &CallNonvirtualVoidMethodA,
4611 &CallStaticObjectMethod,
4612 &CallStaticObjectMethodV,
4613 &CallStaticObjectMethodA,
4614 &CallStaticBooleanMethod,
4615 &CallStaticBooleanMethodV,
4616 &CallStaticBooleanMethodA,
4617 &CallStaticByteMethod,
4618 &CallStaticByteMethodV,
4619 &CallStaticByteMethodA,
4620 &CallStaticCharMethod,
4621 &CallStaticCharMethodV,
4622 &CallStaticCharMethodA,
4623 &CallStaticShortMethod,
4624 &CallStaticShortMethodV,
4625 &CallStaticShortMethodA,
4626 &CallStaticIntMethod,
4627 &CallStaticIntMethodV,
4628 &CallStaticIntMethodA,
4629 &CallStaticLongMethod,
4630 &CallStaticLongMethodV,
4631 &CallStaticLongMethodA,
4632 &CallStaticFloatMethod,
4633 &CallStaticFloatMethodV,
4634 &CallStaticFloatMethodA,
4635 &CallStaticDoubleMethod,
4636 &CallStaticDoubleMethodV,
4637 &CallStaticDoubleMethodA,
4638 &CallStaticVoidMethod,
4639 &CallStaticVoidMethodV,
4640 &CallStaticVoidMethodA,
4644 &GetStaticObjectField,
4645 &GetStaticBooleanField,
4646 &GetStaticByteField,
4647 &GetStaticCharField,
4648 &GetStaticShortField,
4650 &GetStaticLongField,
4651 &GetStaticFloatField,
4652 &GetStaticDoubleField,
4653 &SetStaticObjectField,
4654 &SetStaticBooleanField,
4655 &SetStaticByteField,
4656 &SetStaticCharField,
4657 &SetStaticShortField,
4659 &SetStaticLongField,
4660 &SetStaticFloatField,
4661 &SetStaticDoubleField,
4666 &ReleaseStringChars,
4669 &GetStringUTFLength,
4671 &ReleaseStringUTFChars,
4676 &GetObjectArrayElement,
4677 &SetObjectArrayElement,
4688 &GetBooleanArrayElements,
4689 &GetByteArrayElements,
4690 &GetCharArrayElements,
4691 &GetShortArrayElements,
4692 &GetIntArrayElements,
4693 &GetLongArrayElements,
4694 &GetFloatArrayElements,
4695 &GetDoubleArrayElements,
4697 &ReleaseBooleanArrayElements,
4698 &ReleaseByteArrayElements,
4699 &ReleaseCharArrayElements,
4700 &ReleaseShortArrayElements,
4701 &ReleaseIntArrayElements,
4702 &ReleaseLongArrayElements,
4703 &ReleaseFloatArrayElements,
4704 &ReleaseDoubleArrayElements,
4706 &GetBooleanArrayRegion,
4707 &GetByteArrayRegion,
4708 &GetCharArrayRegion,
4709 &GetShortArrayRegion,
4711 &GetLongArrayRegion,
4712 &GetFloatArrayRegion,
4713 &GetDoubleArrayRegion,
4714 &SetBooleanArrayRegion,
4715 &SetByteArrayRegion,
4716 &SetCharArrayRegion,
4717 &SetShortArrayRegion,
4719 &SetLongArrayRegion,
4720 &SetFloatArrayRegion,
4721 &SetDoubleArrayRegion,
4731 /* new JNI 1.2 functions */
4734 &GetStringUTFRegion,
4736 &GetPrimitiveArrayCritical,
4737 &ReleasePrimitiveArrayCritical,
4740 &ReleaseStringCritical,
4743 &DeleteWeakGlobalRef,
4747 /* new JNI 1.4 functions */
4749 &NewDirectByteBuffer,
4750 &GetDirectBufferAddress,
4751 &GetDirectBufferCapacity
4755 /* Invocation API Functions ***************************************************/
4757 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4759 Returns a default configuration for the Java VM.
4761 *******************************************************************************/
4763 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4765 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4767 /* GNU classpath currently supports JNI 1.2 */
4769 _vm_args->version = JNI_VERSION_1_2;
4775 /* JNI_GetCreatedJavaVMs *******************************************************
4777 Returns all Java VMs that have been created. Pointers to VMs are written in
4778 the buffer vmBuf in the order they are created. At most bufLen number of
4779 entries will be written. The total number of created VMs is returned in
4782 *******************************************************************************/
4784 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4786 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4792 /* JNI_CreateJavaVM ************************************************************
4794 Loads and initializes a Java VM. The current thread becomes the main thread.
4795 Sets the env argument to the JNI interface pointer of the main thread.
4797 *******************************************************************************/
4799 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4801 const struct JNIInvokeInterface *vm;
4802 struct JNINativeInterface *env;
4804 vm = &JNI_JavaVMTable;
4805 env = &JNI_JNIEnvTable;
4807 *p_vm = (JavaVM *) vm;
4808 *p_env = (JNIEnv *) env;
4814 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4815 jobject obj, java_objectarray *params)
4822 if (methodID == 0) {
4823 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
4827 argcount = methodID->parseddesc->paramcount;
4828 paramcount = argcount;
4830 /* if method is non-static, remove the `this' pointer */
4832 if (!(methodID->flags & ACC_STATIC))
4835 /* the method is an instance method the obj has to be an instance of the
4836 class the method belongs to. For static methods the obj parameter
4839 if (!(methodID->flags & ACC_STATIC) && obj &&
4840 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4842 new_exception_message(string_java_lang_IllegalArgumentException,
4843 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4847 if (((params == NULL) && (paramcount != 0)) ||
4848 (params && (params->header.size != paramcount))) {
4850 new_exception(string_java_lang_IllegalArgumentException);
4855 if (!(methodID->flags & ACC_STATIC) && !obj) {
4857 new_exception_message(string_java_lang_NullPointerException,
4858 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4862 if ((methodID->flags & ACC_STATIC) && (obj))
4866 if ((methodID->flags & ACC_ABSTRACT) ||
4867 (methodID->class->flags & ACC_INTERFACE)) {
4868 methodID = get_virtual(obj, methodID);
4872 blk = MNEW(jni_callblock, argcount);
4874 if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4878 switch (methodID->parseddesc->returntype.decltype) {
4880 (void) asm_calljavafunction2(methodID, argcount,
4881 argcount * sizeof(jni_callblock),
4883 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4886 case PRIMITIVETYPE_INT: {
4888 i = asm_calljavafunction2int(methodID, argcount,
4889 argcount * sizeof(jni_callblock),
4892 o = native_new_and_init_int(class_java_lang_Integer, i);
4896 case PRIMITIVETYPE_BYTE: {
4898 i = asm_calljavafunction2int(methodID, argcount,
4899 argcount * sizeof(jni_callblock),
4902 /* o = native_new_and_init_int(class_java_lang_Byte, i); */
4903 o = builtin_new(class_java_lang_Byte);
4906 class_resolvemethod(o->vftbl->class,
4913 case PRIMITIVETYPE_CHAR: {
4915 intVal = asm_calljavafunction2int(methodID,
4917 argcount * sizeof(jni_callblock),
4919 o = builtin_new(class_java_lang_Character);
4922 class_resolvemethod(o->vftbl->class,
4929 case PRIMITIVETYPE_SHORT: {
4931 intVal = asm_calljavafunction2int(methodID,
4933 argcount * sizeof(jni_callblock),
4935 o = builtin_new(class_java_lang_Short);
4938 class_resolvemethod(o->vftbl->class,
4945 case PRIMITIVETYPE_BOOLEAN: {
4947 intVal = asm_calljavafunction2int(methodID,
4949 argcount * sizeof(jni_callblock),
4951 o = builtin_new(class_java_lang_Boolean);
4954 class_resolvemethod(o->vftbl->class,
4961 case PRIMITIVETYPE_LONG: {
4963 longVal = asm_calljavafunction2long(methodID,
4965 argcount * sizeof(jni_callblock),
4967 o = builtin_new(class_java_lang_Long);
4970 class_resolvemethod(o->vftbl->class,
4977 case PRIMITIVETYPE_FLOAT: {
4979 floatVal = asm_calljavafunction2float(methodID,
4981 argcount * sizeof(jni_callblock),
4983 o = builtin_new(class_java_lang_Float);
4986 class_resolvemethod(o->vftbl->class,
4993 case PRIMITIVETYPE_DOUBLE: {
4995 doubleVal = asm_calljavafunction2double(methodID,
4997 argcount * sizeof(jni_callblock),
4999 o = builtin_new(class_java_lang_Double);
5002 class_resolvemethod(o->vftbl->class,
5010 o = asm_calljavafunction2(methodID, argcount,
5011 argcount * sizeof(jni_callblock), blk);
5015 /* if this happens the exception has already been set by */
5016 /* fill_callblock_from_objectarray */
5018 MFREE(blk, jni_callblock, argcount);
5019 return (jobject *) 0;
5022 MFREE(blk, jni_callblock, argcount);
5024 if (*exceptionptr) {
5025 java_objectheader *cause;
5027 cause = *exceptionptr;
5029 /* clear exception pointer, we are calling JIT code again */
5031 *exceptionptr = NULL;
5034 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
5035 (java_lang_Throwable *) cause);
5038 return (jobject *) o;
5043 * These are local overrides for various environment variables in Emacs.
5044 * Please do not remove this and leave it at the end of the file, where
5045 * Emacs will automagically detect them.
5046 * ---------------------------------------------------------------------
5049 * indent-tabs-mode: t