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 3668 2005-11-14 19:48:30Z twisti $
45 #include "mm/memory.h"
46 #include "native/jni.h"
47 #include "native/native.h"
49 #include "native/include/gnu_classpath_Pointer.h"
51 #if SIZEOF_VOID_P == 8
52 # include "native/include/gnu_classpath_Pointer64.h"
54 # include "native/include/gnu_classpath_Pointer32.h"
57 #include "native/include/java_lang_Object.h"
58 #include "native/include/java_lang_Byte.h"
59 #include "native/include/java_lang_Character.h"
60 #include "native/include/java_lang_Short.h"
61 #include "native/include/java_lang_Integer.h"
62 #include "native/include/java_lang_Boolean.h"
63 #include "native/include/java_lang_Long.h"
64 #include "native/include/java_lang_Float.h"
65 #include "native/include/java_lang_Double.h"
66 #include "native/include/java_lang_Throwable.h"
67 #include "native/include/java_lang_reflect_Method.h"
68 #include "native/include/java_lang_reflect_Constructor.h"
69 #include "native/include/java_lang_reflect_Field.h"
71 #include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
72 #include "native/include/java_lang_VMClass.h"
73 #include "native/include/java_lang_VMClassLoader.h"
74 #include "native/include/java_nio_Buffer.h"
75 #include "native/include/java_nio_DirectByteBufferImpl.h"
77 #if defined(ENABLE_JVMTI)
78 # include "native/jvmti/jvmti.h"
81 #if defined(USE_THREADS)
82 # if defined(NATIVE_THREADS)
83 # include "threads/native/threads.h"
85 # include "threads/green/threads.h"
89 #include "toolbox/logging.h"
90 #include "vm/builtin.h"
91 #include "vm/exceptions.h"
92 #include "vm/global.h"
93 #include "vm/initialize.h"
94 #include "vm/loader.h"
95 #include "vm/options.h"
96 #include "vm/resolve.h"
97 #include "vm/statistics.h"
98 #include "vm/stringlocal.h"
99 #include "vm/tables.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;
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;
141 #if SIZEOF_VOID_P == 8
142 static classinfo *class_gnu_classpath_Pointer64;
144 static classinfo *class_gnu_classpath_Pointer32;
148 /* local reference table ******************************************************/
150 #if !defined(USE_THREADS)
151 localref_table *_no_threads_localref_table;
155 /* accessing instance fields macros *******************************************/
157 #define SET_FIELD(obj,type,var,value) \
158 *((type *) ((ptrint) (obj) + (ptrint) (var)->offset)) = (type) (value)
160 #define GET_FIELD(obj,type,var) \
161 *((type *) ((ptrint) (obj) + (ptrint) (var)->offset))
164 /* some forward declarations **************************************************/
166 jobject NewLocalRef(JNIEnv *env, jobject ref);
169 /* jni_init ********************************************************************
171 Initialize the JNI subsystem.
173 *******************************************************************************/
177 /* initalize global reference table */
180 load_class_bootstrap(utf_new_char("java/util/IdentityHashMap"))))
183 global_ref_table = GCNEW(jobject, 1);
185 if (!(*global_ref_table = native_new_and_init(ihmclass)))
188 if (!(getmid = class_resolvemethod(ihmclass, utf_get,
189 utf_java_lang_Object__java_lang_Object)))
192 if (!(putmid = class_resolvemethod(ihmclass, utf_put,
193 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))))
197 class_resolvemethod(ihmclass, utf_remove,
198 utf_java_lang_Object__java_lang_Object)))
202 /* direct buffer stuff */
204 utf_java_nio_DirectByteBufferImpl =
205 utf_new_char("java/nio/DirectByteBufferImpl");
207 if (!(class_java_nio_DirectByteBufferImpl =
208 load_class_bootstrap(utf_java_nio_DirectByteBufferImpl)))
211 if (!link_class(class_java_nio_DirectByteBufferImpl))
214 #if SIZEOF_VOID_P == 8
215 utf_gnu_classpath_Pointer64 = utf_new_char("gnu/classpath/Pointer64");
217 if (!(class_gnu_classpath_Pointer64 =
218 load_class_bootstrap(utf_gnu_classpath_Pointer64)))
221 if (!link_class(class_gnu_classpath_Pointer64))
224 utf_gnu_classpath_Pointer32 = utf_new_char("gnu/classpath/Pointer32");
226 if (!(class_gnu_classpath_Pointer32 =
227 load_class_bootstrap(utf_gnu_classpath_Pointer32)))
230 if (!link_class(class_gnu_classpath_Pointer32))
238 static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
239 jni_callblock blk[], va_list data,
242 typedesc *paramtypes;
245 paramtypes = descr->paramtypes;
247 /* if method is non-static fill first block and skip `this' pointer */
252 /* the `this' pointer */
253 blk[0].itemtype = TYPE_ADR;
254 blk[0].item = PTR_TO_ITEM(obj);
260 for (; i < descr->paramcount; i++, paramtypes++) {
261 switch (paramtypes->decltype) {
262 /* primitive types */
263 case PRIMITIVETYPE_BYTE:
264 case PRIMITIVETYPE_CHAR:
265 case PRIMITIVETYPE_SHORT:
266 case PRIMITIVETYPE_BOOLEAN:
267 blk[i].itemtype = TYPE_INT;
268 blk[i].item = (s8) va_arg(data, s4);
271 case PRIMITIVETYPE_INT:
272 blk[i].itemtype = TYPE_INT;
273 blk[i].item = (s8) va_arg(data, s4);
276 case PRIMITIVETYPE_LONG:
277 blk[i].itemtype = TYPE_LNG;
278 blk[i].item = (s8) va_arg(data, s8);
281 case PRIMITIVETYPE_FLOAT:
282 blk[i].itemtype = TYPE_FLT;
283 #if defined(__ALPHA__)
284 /* this keeps the assembler function much simpler */
286 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
288 *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
292 case PRIMITIVETYPE_DOUBLE:
293 blk[i].itemtype = TYPE_DBL;
294 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
298 blk[i].itemtype = TYPE_ADR;
299 blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
304 /* The standard doesn't say anything about return value checking, but it */
305 /* appears to be useful. */
307 if (rettype != descr->returntype.decltype)
308 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
312 /* XXX it could be considered if we should do typechecking here in the future */
314 static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
316 java_objectarray *params)
320 typedesc *paramtypes;
325 paramcount = descr->paramcount;
326 paramtypes = descr->paramtypes;
328 /* if method is non-static fill first block and skip `this' pointer */
334 blk[0].itemtype = TYPE_ADR;
335 blk[0].item = PTR_TO_ITEM(obj);
342 for (j = 0; j < paramcount; i++, j++, paramtypes++) {
343 switch (paramtypes->type) {
344 /* primitive types */
349 param = params->data[j];
353 /* internally used data type */
354 blk[i].itemtype = paramtypes->type;
356 /* convert the value according to its declared type */
358 c = param->vftbl->class;
360 switch (paramtypes->decltype) {
361 case PRIMITIVETYPE_BOOLEAN:
362 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
363 blk[i].item = (s8) ((java_lang_Boolean *) param)->value;
368 case PRIMITIVETYPE_BYTE:
369 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
370 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
375 case PRIMITIVETYPE_CHAR:
376 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
377 blk[i].item = (s8) ((java_lang_Character *) param)->value;
382 case PRIMITIVETYPE_SHORT:
383 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
384 blk[i].item = (s8) ((java_lang_Short *) param)->value;
385 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
386 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
391 case PRIMITIVETYPE_INT:
392 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
393 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
394 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
395 blk[i].item = (s8) ((java_lang_Short *) param)->value;
396 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
397 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
402 case PRIMITIVETYPE_LONG:
403 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
404 blk[i].item = (s8) ((java_lang_Long *) param)->value;
405 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
406 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
407 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
408 blk[i].item = (s8) ((java_lang_Short *) param)->value;
409 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
410 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
415 case PRIMITIVETYPE_FLOAT:
416 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
417 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
422 case PRIMITIVETYPE_DOUBLE:
423 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
424 *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Float *) param)->value;
425 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
426 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
433 } /* end declared type switch */
437 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
440 if (params->data[j] != 0) {
441 if (paramtypes->arraydim > 0) {
442 if (!builtin_arrayinstanceof(params->data[j], c))
446 if (!builtin_instanceof(params->data[j], c))
450 blk[i].itemtype = TYPE_ADR;
451 blk[i].item = PTR_TO_ITEM(params->data[j]);
456 } /* end param type switch */
458 } /* end param loop */
461 /* *rettype = descr->returntype.decltype; */
466 *exceptionptr = new_illegalargumentexception();
471 static jmethodID get_virtual(jobject obj, jmethodID methodID)
473 if (obj->vftbl->class == methodID->class)
476 return class_resolvemethod(obj->vftbl->class, methodID->name,
477 methodID->descriptor);
481 static jmethodID get_nonvirtual(jclass clazz, jmethodID methodID)
483 if (clazz == methodID->class)
486 /* class_resolvemethod -> classfindmethod? (JOWENN) */
487 return class_resolvemethod(clazz, methodID->name, methodID->descriptor);
491 static jobject callObjectMethod(jobject obj, jmethodID methodID, va_list args)
498 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
502 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
503 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
504 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
508 if (obj && !builtin_instanceof(obj, methodID->class)) {
509 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
513 argcount = methodID->parseddesc->paramcount;
515 blk = MNEW(jni_callblock, argcount);
517 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_ADR);
519 STATS(jnicallXmethodnvokation();)
521 ret = asm_calljavafunction2(methodID,
523 argcount * sizeof(jni_callblock),
526 MFREE(blk, jni_callblock, argcount);
533 core function for integer class methods (bool, byte, short, integer)
534 This is basically needed for i386
536 static jint callIntegerMethod(jobject obj, jmethodID methodID, int retType, va_list args)
542 STATS(jniinvokation();)
545 log_text("JNI-Call: CallObjectMethodV");
546 utf_display(methodID->name);
547 utf_display(methodID->descriptor);
548 printf("\nParmaeter count: %d\n",argcount);
549 utf_display(obj->vftbl->class->name);
553 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
557 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
558 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
559 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
563 if (obj && !builtin_instanceof(obj, methodID->class)) {
564 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
568 argcount = methodID->parseddesc->paramcount;
570 blk = MNEW(jni_callblock, argcount);
572 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
574 STATS(jnicallXmethodnvokation();)
576 ret = asm_calljavafunction2int(methodID,
578 argcount * sizeof(jni_callblock),
581 MFREE(blk, jni_callblock, argcount);
587 /* callLongMethod **************************************************************
589 Core function for long class functions.
591 *******************************************************************************/
593 static jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
599 STATS(jniinvokation();)
602 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
606 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
607 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
608 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
612 if (obj && !builtin_instanceof(obj, methodID->class)) {
613 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
617 argcount = methodID->parseddesc->paramcount;
619 blk = MNEW(jni_callblock, argcount);
621 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_LNG);
623 STATS(jnicallXmethodnvokation();)
625 ret = asm_calljavafunction2long(methodID,
627 argcount * sizeof(jni_callblock),
630 MFREE(blk, jni_callblock, argcount);
636 /*core function for float class methods (float,double)*/
637 static jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,int retType)
639 int argcount = methodID->parseddesc->paramcount;
643 STATS(jniinvokation();)
648 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
649 log_text("Too many arguments. CallObjectMethod does not support that");
653 blk = MNEW(jni_callblock, /*4 */ argcount+2);
655 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
657 /* printf("parameter: obj: %p",blk[0].item); */
658 STATS(jnicallXmethodnvokation();)
659 ret = asm_calljavafunction2double(methodID,
661 (argcount + 1) * sizeof(jni_callblock),
664 MFREE(blk, jni_callblock, argcount + 1);
665 /* printf("(CallObjectMethodV)-->%p\n",ret); */
671 static void cacao_jni_CallVoidMethod(jobject obj, jmethodID m, va_list ap)
677 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
681 if (!( ((m->flags & ACC_STATIC) && (obj == 0)) ||
682 ((!(m->flags & ACC_STATIC)) && (obj != 0)) )) {
683 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
687 if (obj && !builtin_instanceof(obj, m->class)) {
688 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
692 paramcount = m->parseddesc->paramcount;
694 /* #error XXX does not work on intrp, but on JIT */
695 if (!(m->flags & ACC_STATIC))
698 blk = MNEW(jni_callblock, paramcount);
700 fill_callblock_from_vargs(obj, m->parseddesc, blk, ap, TYPE_VOID);
702 STATS(jnicallXmethodnvokation();)
704 (void) asm_calljavafunction2(m,
706 paramcount * sizeof(jni_callblock),
709 MFREE(blk, jni_callblock, paramcount);
715 /* GetVersion ******************************************************************
717 Returns the major version number in the higher 16 bits and the
718 minor version number in the lower 16 bits.
720 *******************************************************************************/
722 jint GetVersion(JNIEnv *env)
724 STATS(jniinvokation();)
726 /* we support JNI 1.4 */
728 return JNI_VERSION_1_4;
732 /* Class Operations ***********************************************************/
734 /* DefineClass *****************************************************************
736 Loads a class from a buffer of raw class data. The buffer
737 containing the raw class data is not referenced by the VM after the
738 DefineClass call returns, and it may be discarded if desired.
740 *******************************************************************************/
742 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
743 const jbyte *buf, jsize bufLen)
745 java_lang_ClassLoader *cl;
750 STATS(jniinvokation();)
752 cl = (java_lang_ClassLoader *) loader;
753 s = javastring_new_char(name);
754 ba = (java_bytearray *) buf;
756 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
759 return (jclass) NewLocalRef(env, (jobject) c);
763 /* FindClass *******************************************************************
765 This function loads a locally-defined class. It searches the
766 directories and zip files specified by the CLASSPATH environment
767 variable for the class with the specified name.
769 *******************************************************************************/
771 jclass FindClass(JNIEnv *env, const char *name)
775 java_objectheader *cl;
777 STATS(jniinvokation();)
779 u = utf_new_char_classname((char *) name);
781 /* check stacktrace for classloader, if one found use it, otherwise use */
782 /* the system classloader */
784 #if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__)
785 /* these JITs support stacktraces, and so does the interpreter */
787 cl = cacao_currentClassLoader();
789 # if defined(ENABLE_INTRP)
790 /* the interpreter supports stacktraces, even if the JIT does not */
793 cl = cacao_currentClassLoader();
799 if (!(c = load_class_from_classloader(u, cl)))
805 if (!use_class_as_object(c))
808 return (jclass) NewLocalRef(env, (jobject) c);
812 /* FromReflectedMethod *********************************************************
814 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
815 object to a method ID.
817 *******************************************************************************/
819 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
825 STATS(jniinvokation();)
830 if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
831 java_lang_reflect_Method *rm;
833 rm = (java_lang_reflect_Method *) method;
834 c = (classinfo *) (rm->declaringClass);
837 } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
838 java_lang_reflect_Constructor *rc;
840 rc = (java_lang_reflect_Constructor *) method;
841 c = (classinfo *) (rc->clazz);
847 if ((slot < 0) || (slot >= c->methodscount)) {
848 /* this usually means a severe internal cacao error or somebody
849 tempered around with the reflected method */
850 log_text("error illegal slot for method in class(FromReflectedMethod)");
854 mi = &(c->methods[slot]);
860 /* GetSuperclass ***************************************************************
862 If clazz represents any class other than the class Object, then
863 this function returns the object that represents the superclass of
864 the class specified by clazz.
866 *******************************************************************************/
868 jclass GetSuperclass(JNIEnv *env, jclass sub)
872 STATS(jniinvokation();)
874 c = ((classinfo *) sub)->super.cls;
879 if (!use_class_as_object(c))
882 return (jclass) NewLocalRef(env, (jobject) c);
886 /* IsAssignableFrom ************************************************************
888 Determines whether an object of sub can be safely cast to sup.
890 *******************************************************************************/
892 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
894 STATS(jniinvokation();)
895 return Java_java_lang_VMClass_isAssignableFrom(env,
897 (java_lang_Class *) sup,
898 (java_lang_Class *) sub);
902 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
904 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
906 STATS(jniinvokation();)
908 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!!!");
914 /* Throw ***********************************************************************
916 Causes a java.lang.Throwable object to be thrown.
918 *******************************************************************************/
920 jint Throw(JNIEnv *env, jthrowable obj)
922 STATS(jniinvokation();)
924 *exceptionptr = (java_objectheader *) obj;
930 /* ThrowNew ********************************************************************
932 Constructs an exception object from the specified class with the
933 message specified by message and causes that exception to be
936 *******************************************************************************/
938 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
940 java_lang_Throwable *o;
943 STATS(jniinvokation();)
945 s = (java_lang_String *) javastring_new_char(msg);
947 /* instantiate exception object */
949 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
955 *exceptionptr = (java_objectheader *) o;
961 /* ExceptionOccurred ***********************************************************
963 Determines if an exception is being thrown. The exception stays
964 being thrown until either the native code calls ExceptionClear(),
965 or the Java code handles the exception.
967 *******************************************************************************/
969 jthrowable ExceptionOccurred(JNIEnv *env)
971 java_objectheader *e;
973 STATS(jniinvokation();)
977 return NewLocalRef(env, (jthrowable) e);
981 /* ExceptionDescribe ***********************************************************
983 Prints an exception and a backtrace of the stack to a system
984 error-reporting channel, such as stderr. This is a convenience
985 routine provided for debugging.
987 *******************************************************************************/
989 void ExceptionDescribe(JNIEnv *env)
991 java_objectheader *e;
993 STATS(jniinvokation();)
998 /* clear exception, because we are calling jit code again */
1000 *exceptionptr = NULL;
1002 /* get printStackTrace method from exception class */
1004 m = class_resolveclassmethod(e->vftbl->class,
1005 utf_printStackTrace,
1011 /* XXX what should we do? */
1014 /* print the stacktrace */
1016 asm_calljavafunction(m, e, NULL, NULL, NULL);
1021 /* ExceptionClear **************************************************************
1023 Clears any exception that is currently being thrown. If no
1024 exception is currently being thrown, this routine has no effect.
1026 *******************************************************************************/
1028 void ExceptionClear(JNIEnv *env)
1030 STATS(jniinvokation();)
1032 *exceptionptr = NULL;
1036 /* FatalError ******************************************************************
1038 Raises a fatal error and does not expect the VM to recover. This
1039 function does not return.
1041 *******************************************************************************/
1043 void FatalError(JNIEnv *env, const char *msg)
1045 STATS(jniinvokation();)
1047 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
1051 /* PushLocalFrame **************************************************************
1053 Creates a new local reference frame, in which at least a given
1054 number of local references can be created.
1056 *******************************************************************************/
1058 jint PushLocalFrame(JNIEnv* env, jint capacity)
1060 STATS(jniinvokation();)
1062 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
1069 /* PopLocalFrame ***************************************************************
1071 Pops off the current local reference frame, frees all the local
1072 references, and returns a local reference in the previous local
1073 reference frame for the given result object.
1075 *******************************************************************************/
1077 jobject PopLocalFrame(JNIEnv* env, jobject result)
1079 STATS(jniinvokation();)
1081 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
1085 /* add local reference and return the value */
1087 return NewLocalRef(env, NULL);
1091 /* DeleteLocalRef **************************************************************
1093 Deletes the local reference pointed to by localRef.
1095 *******************************************************************************/
1097 void DeleteLocalRef(JNIEnv *env, jobject localRef)
1099 java_objectheader *o;
1100 localref_table *lrt;
1103 STATS(jniinvokation();)
1105 o = (java_objectheader *) localRef;
1107 /* get local reference table (thread specific) */
1109 lrt = LOCALREFTABLE;
1111 /* remove the reference */
1113 for (i = 0; i < lrt->capacity; i++) {
1114 if (lrt->refs[i] == o) {
1115 lrt->refs[i] = NULL;
1122 /* this should not happen */
1124 /* if (opt_checkjni) */
1125 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1126 log_text("JNI-DeleteLocalRef: Bad global or local ref passed to JNI");
1130 /* IsSameObject ****************************************************************
1132 Tests whether two references refer to the same Java object.
1134 *******************************************************************************/
1136 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1138 STATS(jniinvokation();)
1147 /* NewLocalRef *****************************************************************
1149 Creates a new local reference that refers to the same object as ref.
1151 *******************************************************************************/
1153 jobject NewLocalRef(JNIEnv *env, jobject ref)
1155 localref_table *lrt;
1158 STATS(jniinvokation();)
1163 /* get local reference table (thread specific) */
1165 lrt = LOCALREFTABLE;
1167 /* check if we have space for the requested reference */
1169 if (lrt->used == lrt->capacity)
1170 throw_cacao_exception_exit(string_java_lang_InternalError,
1171 "Too many local references");
1173 /* insert the reference */
1175 for (i = 0; i < lrt->capacity; i++) {
1176 if (lrt->refs[i] == NULL) {
1177 lrt->refs[i] = (java_objectheader *) ref;
1184 /* should not happen, just to be sure */
1188 /* keep compiler happy */
1194 /* EnsureLocalCapacity *********************************************************
1196 Ensures that at least a given number of local references can be
1197 created in the current thread
1199 *******************************************************************************/
1201 jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
1203 localref_table *lrt;
1205 STATS(jniinvokation();)
1207 /* get local reference table (thread specific) */
1209 lrt = LOCALREFTABLE;
1211 /* check if capacity elements are available in the local references table */
1213 if ((lrt->used + capacity) > lrt->capacity) {
1214 *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
1222 /* AllocObject *****************************************************************
1224 Allocates a new Java object without invoking any of the
1225 constructors for the object. Returns a reference to the object.
1227 *******************************************************************************/
1229 jobject AllocObject(JNIEnv *env, jclass clazz)
1231 java_objectheader *o;
1233 STATS(jniinvokation();)
1235 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1237 new_exception_utfmessage(string_java_lang_InstantiationException,
1242 o = builtin_new(clazz);
1244 return NewLocalRef(env, o);
1248 /* NewObject *******************************************************************
1250 Programmers place all arguments that are to be passed to the
1251 constructor immediately following the methodID
1252 argument. NewObject() accepts these arguments and passes them to
1253 the Java method that the programmer wishes to invoke.
1255 *******************************************************************************/
1257 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1259 java_objectheader *o;
1262 STATS(jniinvokation();)
1266 o = builtin_new(clazz);
1271 /* call constructor */
1273 va_start(ap, methodID);
1274 cacao_jni_CallVoidMethod(o, methodID, ap);
1277 return NewLocalRef(env, o);
1281 /***********************************************************************************
1283 Constructs a new Java object
1284 arguments that are to be passed to the constructor are placed in va_list args
1286 ***********************************************************************************/
1288 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1290 STATS(jniinvokation();)
1292 log_text("JNI-Call: NewObjectV: IMPLEMENT ME!");
1294 return NewLocalRef(env, NULL);
1298 /***********************************************************************************
1300 Constructs a new Java object
1301 arguments that are to be passed to the constructor are placed in
1302 args array of jvalues
1304 ***********************************************************************************/
1306 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1308 STATS(jniinvokation();)
1310 log_text("JNI-Call: NewObjectA: IMPLEMENT ME!");
1312 return NewLocalRef(env, NULL);
1316 /* GetObjectClass **************************************************************
1318 Returns the class of an object.
1320 *******************************************************************************/
1322 jclass GetObjectClass(JNIEnv *env, jobject obj)
1326 STATS(jniinvokation();)
1328 if (!obj || !obj->vftbl)
1331 c = obj->vftbl->class;
1333 if (!use_class_as_object(c))
1336 return (jclass) NewLocalRef(env, (jobject) c);
1340 /* IsInstanceOf ****************************************************************
1342 Tests whether an object is an instance of a class.
1344 *******************************************************************************/
1346 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1348 STATS(jniinvokation();)
1350 return Java_java_lang_VMClass_isInstance(env,
1352 (java_lang_Class *) clazz,
1353 (java_lang_Object *) obj);
1357 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1359 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1361 java_lang_reflect_Field *f;
1363 jfieldID fid; /* the JNI-fieldid of the wrapping object */
1364 STATS(jniinvokation();)
1365 /*log_text("JNI-Call: FromReflectedField");*/
1367 f=(java_lang_reflect_Field *)field;
1369 c=(classinfo*)(f->declaringClass);
1370 if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1371 /*this usually means a severe internal cacao error or somebody
1372 tempered around with the reflected method*/
1373 log_text("error illegal slot for field in class(FromReflectedField)");
1376 fid=&(c->fields[f->slot]);
1381 /**********************************************************************************
1383 converts a method ID to a java.lang.reflect.Method or
1384 java.lang.reflect.Constructor object
1386 **********************************************************************************/
1388 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1390 log_text("JNI-Call: ToReflectedMethod");
1391 STATS(jniinvokation();)
1397 /* Calling Instance Methods ***************************************************/
1399 /* GetMethodID *****************************************************************
1401 Returns the method ID for an instance (nonstatic) method of a class
1402 or interface. The method may be defined in one of the clazz's
1403 superclasses and inherited by clazz. The method is determined by
1404 its name and signature.
1406 GetMethodID() causes an uninitialized class to be initialized.
1408 *******************************************************************************/
1410 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1418 STATS(jniinvokation();)
1420 c = (classinfo *) clazz;
1425 if (!c->initialized)
1426 if (!initialize_class(c))
1429 /* try to get the method of the class or one of it's superclasses */
1431 uname = utf_new_char((char *) name);
1432 udesc = utf_new_char((char *) sig);
1434 m = class_resolvemethod(clazz, uname, udesc);
1436 if (!m || (m->flags & ACC_STATIC)) {
1437 *exceptionptr = exceptions_new_nosuchmethoderror(c, uname, udesc);
1446 /******************** JNI-functions for calling instance methods ******************/
1448 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1450 java_objectheader* ret;
1453 STATS(jniinvokation();)
1455 va_start(vaargs, methodID);
1456 ret = callObjectMethod(obj, methodID, vaargs);
1459 return NewLocalRef(env, ret);
1463 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1465 java_objectheader* ret;
1467 STATS(jniinvokation();)
1469 ret = callObjectMethod(obj, methodID, args);
1471 return NewLocalRef(env, ret);
1475 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1477 STATS(jniinvokation();)
1479 log_text("JNI-Call: CallObjectMethodA: IMPLEMENT ME!");
1481 return NewLocalRef(env, NULL);
1487 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1491 STATS(jniinvokation();)
1493 /* log_text("JNI-Call: CallBooleanMethod");*/
1495 va_start(vaargs,methodID);
1496 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1502 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1504 STATS(jniinvokation();)
1506 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
1510 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1512 STATS(jniinvokation();)
1513 log_text("JNI-Call: CallBooleanMethodA");
1518 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1522 STATS(jniinvokation();)
1524 /* log_text("JNI-Call: CallVyteMethod");*/
1526 va_start(vaargs,methodID);
1527 ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
1533 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1535 /* log_text("JNI-Call: CallByteMethodV");*/
1536 STATS(jniinvokation();)
1538 return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
1542 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1544 log_text("JNI-Call: CallByteMethodA");
1545 STATS(jniinvokation();)
1551 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1555 STATS(jniinvokation();)
1557 /* log_text("JNI-Call: CallCharMethod");*/
1559 va_start(vaargs,methodID);
1560 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
1567 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1569 STATS(jniinvokation();)
1571 /* log_text("JNI-Call: CallCharMethodV");*/
1572 return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
1576 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1578 STATS(jniinvokation();)
1580 log_text("JNI-Call: CallCharMethodA");
1586 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1590 STATS(jniinvokation();)
1592 /* log_text("JNI-Call: CallShortMethod");*/
1594 va_start(vaargs, methodID);
1595 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
1602 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1604 STATS(jniinvokation();)
1605 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
1609 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1611 STATS(jniinvokation();)
1612 log_text("JNI-Call: CallShortMethodA");
1619 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1623 STATS(jniinvokation();)
1625 va_start(vaargs,methodID);
1626 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
1633 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1635 STATS(jniinvokation();)
1636 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
1640 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1642 STATS(jniinvokation();)
1643 log_text("JNI-Call: CallIntMethodA");
1650 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1654 STATS(jniinvokation();)
1656 va_start(vaargs,methodID);
1657 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1664 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1666 STATS(jniinvokation();)
1667 return callLongMethod(obj,get_virtual(obj, methodID),args);
1671 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1673 STATS(jniinvokation();)
1674 log_text("JNI-Call: CallLongMethodA");
1681 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1686 STATS(jniinvokation();)
1687 /* log_text("JNI-Call: CallFloatMethod");*/
1689 va_start(vaargs,methodID);
1690 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
1697 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1699 STATS(jniinvokation();)
1700 log_text("JNI-Call: CallFloatMethodV");
1701 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
1705 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1707 STATS(jniinvokation();)
1708 log_text("JNI-Call: CallFloatMethodA");
1715 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1719 STATS(jniinvokation();)
1721 /* log_text("JNI-Call: CallDoubleMethod");*/
1723 va_start(vaargs,methodID);
1724 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
1731 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1733 STATS(jniinvokation();)
1734 log_text("JNI-Call: CallDoubleMethodV");
1735 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
1739 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1741 STATS(jniinvokation();)
1742 log_text("JNI-Call: CallDoubleMethodA");
1748 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1751 STATS(jniinvokation();)
1753 va_start(vaargs,methodID);
1754 (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
1759 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1761 log_text("JNI-Call: CallVoidMethodV");
1762 STATS(jniinvokation();)
1763 (void)callIntegerMethod(obj,get_virtual(obj,methodID),TYPE_VOID,args);
1767 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1769 STATS(jniinvokation();)
1770 log_text("JNI-Call: CallVoidMethodA");
1775 jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1777 STATS(jniinvokation();)
1779 log_text("JNI-Call: CallNonvirtualObjectMethod: IMPLEMENT ME!");
1781 return NewLocalRef(env, NULL);
1785 jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1787 STATS(jniinvokation();)
1789 log_text("JNI-Call: CallNonvirtualObjectMethodV: IMPLEMENT ME!");
1791 return NewLocalRef(env, NULL);
1795 jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1797 STATS(jniinvokation();)
1799 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1801 return NewLocalRef(env, NULL);
1806 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1810 STATS(jniinvokation();)
1812 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1814 va_start(vaargs,methodID);
1815 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1822 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1824 STATS(jniinvokation();)
1825 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1826 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
1830 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1832 STATS(jniinvokation();)
1833 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1840 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1845 STATS(jniinvokation();)
1846 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1848 va_start(vaargs,methodID);
1849 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
1855 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1857 STATS(jniinvokation();)
1858 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1859 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
1864 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1866 STATS(jniinvokation();)
1867 log_text("JNI-Call: CallNonvirtualByteMethodA");
1874 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1879 STATS(jniinvokation();)
1880 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1882 va_start(vaargs,methodID);
1883 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
1889 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1891 STATS(jniinvokation();)
1892 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1893 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
1897 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1899 STATS(jniinvokation();)
1900 log_text("JNI-Call: CallNonvirtualCharMethodA");
1907 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1911 STATS(jniinvokation();)
1913 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1915 va_start(vaargs,methodID);
1916 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
1922 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1924 STATS(jniinvokation();)
1925 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1926 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
1930 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1932 STATS(jniinvokation();)
1933 log_text("JNI-Call: CallNonvirtualShortMethodA");
1940 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1945 STATS(jniinvokation();)
1947 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1949 va_start(vaargs,methodID);
1950 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
1956 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1958 STATS(jniinvokation();)
1959 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1960 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
1964 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1966 STATS(jniinvokation();)
1967 log_text("JNI-Call: CallNonvirtualIntMethodA");
1974 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1976 STATS(jniinvokation();)
1977 log_text("JNI-Call: CallNonvirtualLongMethod");
1983 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1985 STATS(jniinvokation();)
1986 log_text("JNI-Call: CallNonvirtualLongMethodV");
1992 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1994 STATS(jniinvokation();)
1995 log_text("JNI-Call: CallNonvirtualLongMethodA");
2002 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2006 STATS(jniinvokation();)
2008 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
2011 va_start(vaargs,methodID);
2012 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
2019 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2021 STATS(jniinvokation();)
2022 log_text("JNI-Call: CallNonvirtualFloatMethodV");
2023 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
2027 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2029 STATS(jniinvokation();)
2030 log_text("JNI-Call: CallNonvirtualFloatMethodA");
2037 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2041 STATS(jniinvokation();)
2042 log_text("JNI-Call: CallNonvirtualDoubleMethod");
2044 va_start(vaargs,methodID);
2045 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
2052 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2054 STATS(jniinvokation();)
2055 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
2056 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
2060 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2062 STATS(jniinvokation();)
2063 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
2070 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2073 STATS(jniinvokation();)
2075 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
2077 va_start(vaargs,methodID);
2078 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
2084 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2086 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
2087 STATS(jniinvokation();)
2089 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
2094 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
2096 STATS(jniinvokation();)
2097 log_text("JNI-Call: CallNonvirtualVoidMethodA");
2101 /* Accessing Fields of Objects ************************************************/
2103 /* GetFieldID ******************************************************************
2105 Returns the field ID for an instance (nonstatic) field of a
2106 class. The field is specified by its name and signature. The
2107 Get<type>Field and Set<type>Field families of accessor functions
2108 use field IDs to retrieve object fields.
2110 *******************************************************************************/
2112 jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2119 STATS(jniinvokation();)
2121 uname = utf_new_char((char *) name);
2122 udesc = utf_new_char((char *) sig);
2124 f = class_findfield(clazz, uname, udesc);
2127 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2133 /* Get<type>Field Routines *****************************************************
2135 This family of accessor routines returns the value of an instance
2136 (nonstatic) field of an object. The field to access is specified by
2137 a field ID obtained by calling GetFieldID().
2139 *******************************************************************************/
2141 jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2143 java_objectheader *o;
2145 STATS(jniinvokation();)
2147 o = GET_FIELD(obj, java_objectheader*, fieldID);
2149 return NewLocalRef(env, o);
2153 jboolean GetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID)
2157 STATS(jniinvokation();)
2159 i = GET_FIELD(obj, s4, fieldID);
2161 return (jboolean) i;
2165 jbyte GetByteField(JNIEnv *env, jobject obj, jfieldID fieldID)
2169 STATS(jniinvokation();)
2171 i = GET_FIELD(obj, s4, fieldID);
2177 jchar GetCharField(JNIEnv *env, jobject obj, jfieldID fieldID)
2181 STATS(jniinvokation();)
2183 i = GET_FIELD(obj, s4, fieldID);
2189 jshort GetShortField(JNIEnv *env, jobject obj, jfieldID fieldID)
2193 STATS(jniinvokation();)
2195 i = GET_FIELD(obj, s4, fieldID);
2201 jint GetIntField(JNIEnv *env, jobject obj, jfieldID fieldID)
2205 STATS(jniinvokation();)
2207 i = GET_FIELD(obj, s4, fieldID);
2213 jlong GetLongField(JNIEnv *env, jobject obj, jfieldID fieldID)
2217 STATS(jniinvokation();)
2219 l = GET_FIELD(obj, s8, fieldID);
2225 jfloat GetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID)
2229 STATS(jniinvokation();)
2231 f = GET_FIELD(obj, float, fieldID);
2237 jdouble GetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID)
2241 STATS(jniinvokation();)
2243 d = GET_FIELD(obj, double, fieldID);
2249 /* Set<type>Field Routines *****************************************************
2251 This family of accessor routines sets the value of an instance
2252 (nonstatic) field of an object. The field to access is specified by
2253 a field ID obtained by calling GetFieldID().
2255 *******************************************************************************/
2257 void SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value)
2259 STATS(jniinvokation();)
2261 SET_FIELD(obj, java_objectheader*, fieldID, value);
2265 void SetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID, jboolean value)
2267 STATS(jniinvokation();)
2269 SET_FIELD(obj, s4, fieldID, value);
2273 void SetByteField(JNIEnv *env, jobject obj, jfieldID fieldID, jbyte value)
2275 STATS(jniinvokation();)
2277 SET_FIELD(obj, s4, fieldID, value);
2281 void SetCharField(JNIEnv *env, jobject obj, jfieldID fieldID, jchar value)
2283 STATS(jniinvokation();)
2285 SET_FIELD(obj, s4, fieldID, value);
2289 void SetShortField(JNIEnv *env, jobject obj, jfieldID fieldID, jshort value)
2291 STATS(jniinvokation();)
2293 SET_FIELD(obj, s4, fieldID, value);
2297 void SetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint value)
2299 STATS(jniinvokation();)
2301 SET_FIELD(obj, s4, fieldID, value);
2305 void SetLongField(JNIEnv *env, jobject obj, jfieldID fieldID, jlong value)
2307 STATS(jniinvokation();)
2309 SET_FIELD(obj, s8, fieldID, value);
2313 void SetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID, jfloat value)
2315 STATS(jniinvokation();)
2317 SET_FIELD(obj, float, fieldID, value);
2321 void SetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID, jdouble value)
2323 STATS(jniinvokation();)
2325 SET_FIELD(obj, double, fieldID, value);
2329 /* Calling Static Methods *****************************************************/
2331 /* GetStaticMethodID ***********************************************************
2333 Returns the method ID for a static method of a class. The method is
2334 specified by its name and signature.
2336 GetStaticMethodID() causes an uninitialized class to be
2339 *******************************************************************************/
2341 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2349 STATS(jniinvokation();)
2351 c = (classinfo *) clazz;
2356 if (!c->initialized)
2357 if (!initialize_class(c))
2360 /* try to get the static method of the class */
2362 uname = utf_new_char((char *) name);
2363 udesc = utf_new_char((char *) sig);
2365 m = class_resolvemethod(c, uname, udesc);
2367 if (!m || !(m->flags & ACC_STATIC)) {
2368 *exceptionptr = exceptions_new_nosuchmethoderror(c, uname, udesc);
2377 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2379 java_objectheader *ret;
2382 STATS(jniinvokation();)
2384 va_start(vaargs, methodID);
2385 ret = callObjectMethod(0, methodID, vaargs);
2388 return NewLocalRef(env, ret);
2392 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2394 java_objectheader *ret;
2396 STATS(jniinvokation();)
2398 ret = callObjectMethod(0, methodID, args);
2400 return NewLocalRef(env, ret);
2404 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2406 STATS(jniinvokation();)
2408 log_text("JNI-Call: CallStaticObjectMethodA: IMPLEMENT ME!");
2410 return NewLocalRef(env, NULL);
2414 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2419 STATS(jniinvokation();)
2421 va_start(vaargs, methodID);
2422 ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
2429 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2431 STATS(jniinvokation();)
2433 return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
2437 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2439 STATS(jniinvokation();)
2441 log_text("JNI-Call: CallStaticBooleanMethodA: IMPLEMENT ME!");
2447 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2452 STATS(jniinvokation();)
2454 va_start(vaargs, methodID);
2455 ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
2462 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2464 STATS(jniinvokation();)
2465 return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
2469 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2471 STATS(jniinvokation();)
2473 log_text("JNI-Call: CallStaticByteMethodA: IMPLEMENT ME!");
2479 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2484 STATS(jniinvokation();)
2486 va_start(vaargs, methodID);
2487 ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
2494 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2496 STATS(jniinvokation();)
2498 return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
2502 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2504 STATS(jniinvokation();)
2506 log_text("JNI-Call: CallStaticCharMethodA: IMPLEMENT ME!");
2512 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2517 STATS(jniinvokation();)
2519 va_start(vaargs, methodID);
2520 ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
2527 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2529 STATS(jniinvokation();)
2531 return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
2535 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2537 STATS(jniinvokation();)
2539 log_text("JNI-Call: CallStaticShortMethodA: IMPLEMENT ME!");
2545 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2550 STATS(jniinvokation();)
2552 va_start(vaargs, methodID);
2553 ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
2560 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2562 STATS(jniinvokation();)
2564 return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
2568 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2570 STATS(jniinvokation();)
2572 log_text("JNI-Call: CallStaticIntMethodA: IMPLEMENT ME!");
2578 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2583 STATS(jniinvokation();)
2585 va_start(vaargs, methodID);
2586 ret = callLongMethod(0, methodID, vaargs);
2593 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
2596 STATS(jniinvokation();)
2598 return callLongMethod(0, methodID, args);
2602 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2604 STATS(jniinvokation();)
2606 log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!");
2613 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2618 STATS(jniinvokation();)
2620 va_start(vaargs, methodID);
2621 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
2628 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2630 STATS(jniinvokation();)
2632 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
2637 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2639 STATS(jniinvokation();)
2641 log_text("JNI-Call: CallStaticFloatMethodA: IMPLEMENT ME!");
2647 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2652 STATS(jniinvokation();)
2654 va_start(vaargs,methodID);
2655 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
2662 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2664 STATS(jniinvokation();)
2666 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
2670 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2672 STATS(jniinvokation();)
2674 log_text("JNI-Call: CallStaticDoubleMethodA: IMPLEMENT ME!");
2680 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2684 STATS(jniinvokation();)
2686 va_start(vaargs, methodID);
2687 (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
2692 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2694 STATS(jniinvokation();)
2696 (void) callIntegerMethod(0, methodID, TYPE_VOID, args);
2700 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2702 STATS(jniinvokation();)
2704 log_text("JNI-Call: CallStaticVoidMethodA: IMPLEMENT ME!");
2708 /* Accessing Static Fields ****************************************************/
2710 /* GetStaticFieldID ************************************************************
2712 Returns the field ID for a static field of a class. The field is
2713 specified by its name and signature. The GetStatic<type>Field and
2714 SetStatic<type>Field families of accessor functions use field IDs
2715 to retrieve static fields.
2717 *******************************************************************************/
2719 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2722 STATS(jniinvokation();)
2724 f = class_findfield(clazz,
2725 utf_new_char((char *) name),
2726 utf_new_char((char *) sig));
2729 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2735 /* GetStatic<type>Field ********************************************************
2737 This family of accessor routines returns the value of a static
2740 *******************************************************************************/
2742 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2744 STATS(jniinvokation();)
2746 if (!clazz->initialized)
2747 if (!initialize_class(clazz))
2750 return NewLocalRef(env, fieldID->value.a);
2754 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2756 STATS(jniinvokation();)
2758 if (!clazz->initialized)
2759 if (!initialize_class(clazz))
2762 return fieldID->value.i;
2766 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2768 STATS(jniinvokation();)
2770 if (!clazz->initialized)
2771 if (!initialize_class(clazz))
2774 return fieldID->value.i;
2778 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2780 STATS(jniinvokation();)
2782 if (!clazz->initialized)
2783 if (!initialize_class(clazz))
2786 return fieldID->value.i;
2790 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2792 STATS(jniinvokation();)
2794 if (!clazz->initialized)
2795 if (!initialize_class(clazz))
2798 return fieldID->value.i;
2802 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2804 STATS(jniinvokation();)
2806 if (!clazz->initialized)
2807 if (!initialize_class(clazz))
2810 return fieldID->value.i;
2814 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2816 STATS(jniinvokation();)
2818 if (!clazz->initialized)
2819 if (!initialize_class(clazz))
2822 return fieldID->value.l;
2826 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2828 STATS(jniinvokation();)
2830 if (!clazz->initialized)
2831 if (!initialize_class(clazz))
2834 return fieldID->value.f;
2838 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2840 STATS(jniinvokation();)
2842 if (!clazz->initialized)
2843 if (!initialize_class(clazz))
2846 return fieldID->value.d;
2850 /* SetStatic<type>Field *******************************************************
2852 This family of accessor routines sets the value of a static field
2855 *******************************************************************************/
2857 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2859 STATS(jniinvokation();)
2861 if (!clazz->initialized)
2862 if (!initialize_class(clazz))
2865 fieldID->value.a = value;
2869 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2871 STATS(jniinvokation();)
2873 if (!clazz->initialized)
2874 if (!initialize_class(clazz))
2877 fieldID->value.i = value;
2881 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2883 STATS(jniinvokation();)
2885 if (!clazz->initialized)
2886 if (!initialize_class(clazz))
2889 fieldID->value.i = value;
2893 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2895 STATS(jniinvokation();)
2897 if (!clazz->initialized)
2898 if (!initialize_class(clazz))
2901 fieldID->value.i = value;
2905 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2907 STATS(jniinvokation();)
2909 if (!clazz->initialized)
2910 if (!initialize_class(clazz))
2913 fieldID->value.i = value;
2917 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2919 STATS(jniinvokation();)
2921 if (!clazz->initialized)
2922 if (!initialize_class(clazz))
2925 fieldID->value.i = value;
2929 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2931 STATS(jniinvokation();)
2933 if (!clazz->initialized)
2934 if (!initialize_class(clazz))
2937 fieldID->value.l = value;
2941 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2943 STATS(jniinvokation();)
2945 if (!clazz->initialized)
2946 if (!initialize_class(clazz))
2949 fieldID->value.f = value;
2953 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2955 STATS(jniinvokation();)
2957 if (!clazz->initialized)
2958 if (!initialize_class(clazz))
2961 fieldID->value.d = value;
2965 /* String Operations **********************************************************/
2967 /* NewString *******************************************************************
2969 Create new java.lang.String object from an array of Unicode
2972 *******************************************************************************/
2974 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
2976 java_lang_String *s;
2980 STATS(jniinvokation();)
2982 s = (java_lang_String *) builtin_new(class_java_lang_String);
2983 a = builtin_newarray_char(len);
2985 /* javastring or characterarray could not be created */
2990 for (i = 0; i < len; i++)
2991 a->data[i] = buf[i];
2997 return (jstring) NewLocalRef(env, (jobject) s);
3001 static jchar emptyStringJ[]={0,0};
3003 /* GetStringLength *************************************************************
3005 Returns the length (the count of Unicode characters) of a Java
3008 *******************************************************************************/
3010 jsize GetStringLength(JNIEnv *env, jstring str)
3012 return ((java_lang_String *) str)->count;
3016 /******************** convertes javastring to u2-array ****************************/
3018 u2 *javastring_tou2(jstring so)
3020 java_lang_String *s;
3025 STATS(jniinvokation();)
3027 s = (java_lang_String *) so;
3037 /* allocate memory */
3039 stringbuffer = MNEW(u2, s->count + 1);
3043 for (i = 0; i < s->count; i++)
3044 stringbuffer[i] = a->data[s->offset + i];
3046 /* terminate string */
3048 stringbuffer[i] = '\0';
3050 return stringbuffer;
3054 /* GetStringChars **************************************************************
3056 Returns a pointer to the array of Unicode characters of the
3057 string. This pointer is valid until ReleaseStringchars() is called.
3059 *******************************************************************************/
3061 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
3065 STATS(jniinvokation();)
3067 jc = javastring_tou2(str);
3079 return emptyStringJ;
3083 /* ReleaseStringChars **********************************************************
3085 Informs the VM that the native code no longer needs access to
3086 chars. The chars argument is a pointer obtained from string using
3089 *******************************************************************************/
3091 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
3093 STATS(jniinvokation();)
3095 if (chars == emptyStringJ)
3098 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
3102 /* NewStringUTF ****************************************************************
3104 Constructs a new java.lang.String object from an array of UTF-8 characters.
3106 *******************************************************************************/
3108 jstring NewStringUTF(JNIEnv *env, const char *bytes)
3110 java_lang_String *s;
3112 STATS(jniinvokation();)
3114 s = javastring_new(utf_new_char(bytes));
3116 return (jstring) NewLocalRef(env, (jobject) s);
3120 /****************** returns the utf8 length in bytes of a string *******************/
3122 jsize GetStringUTFLength (JNIEnv *env, jstring string)
3124 java_lang_String *s = (java_lang_String*) string;
3125 STATS(jniinvokation();)
3127 return (jsize) u2_utflength(s->value->data, s->count);
3131 /* GetStringUTFChars ***********************************************************
3133 Returns a pointer to an array of UTF-8 characters of the
3134 string. This array is valid until it is released by
3135 ReleaseStringUTFChars().
3137 *******************************************************************************/
3139 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
3142 STATS(jniinvokation();)
3150 u = javastring_toutf((java_lang_String *) string, false);
3159 /* ReleaseStringUTFChars *******************************************************
3161 Informs the VM that the native code no longer needs access to
3162 utf. The utf argument is a pointer derived from string using
3163 GetStringUTFChars().
3165 *******************************************************************************/
3167 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
3169 STATS(jniinvokation();)
3171 /* XXX we don't release utf chars right now, perhaps that should be done
3172 later. Since there is always one reference the garbage collector will
3177 /* Array Operations ***********************************************************/
3179 /* GetArrayLength **************************************************************
3181 Returns the number of elements in the array.
3183 *******************************************************************************/
3185 jsize GetArrayLength(JNIEnv *env, jarray array)
3187 STATS(jniinvokation();)
3193 /* NewObjectArray **************************************************************
3195 Constructs a new array holding objects in class elementClass. All
3196 elements are initially set to initialElement.
3198 *******************************************************************************/
3200 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
3202 java_objectarray *oa;
3205 STATS(jniinvokation();)
3208 *exceptionptr = new_negativearraysizeexception();
3212 oa = builtin_anewarray(length, elementClass);
3217 /* set all elements to initialElement */
3219 for (i = 0; i < length; i++)
3220 oa->data[i] = initialElement;
3222 return (jobjectArray) NewLocalRef(env, (jobject) oa);
3226 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
3230 STATS(jniinvokation();)
3232 if (index >= array->header.size) {
3234 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3238 o = array->data[index];
3240 return NewLocalRef(env, o);
3244 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3246 STATS(jniinvokation();)
3247 if (index >= array->header.size)
3248 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3251 /* check if the class of value is a subclass of the element class of the array */
3252 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
3253 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3256 array->data[index] = val;
3261 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3263 java_booleanarray *ba;
3265 STATS(jniinvokation();)
3268 *exceptionptr = new_negativearraysizeexception();
3272 ba = builtin_newarray_boolean(len);
3274 return (jbooleanArray) NewLocalRef(env, (jobject) ba);
3278 jbyteArray NewByteArray(JNIEnv *env, jsize len)
3282 STATS(jniinvokation();)
3285 *exceptionptr = new_negativearraysizeexception();
3289 ba = builtin_newarray_byte(len);
3291 return (jbyteArray) NewLocalRef(env, (jobject) ba);
3295 jcharArray NewCharArray(JNIEnv *env, jsize len)
3299 STATS(jniinvokation();)
3302 *exceptionptr = new_negativearraysizeexception();
3306 ca = builtin_newarray_char(len);
3308 return (jcharArray) NewLocalRef(env, (jobject) ca);
3312 jshortArray NewShortArray(JNIEnv *env, jsize len)
3314 java_shortarray *sa;
3316 STATS(jniinvokation();)
3319 *exceptionptr = new_negativearraysizeexception();
3323 sa = builtin_newarray_short(len);
3325 return (jshortArray) NewLocalRef(env, (jobject) sa);
3329 jintArray NewIntArray(JNIEnv *env, jsize len)
3333 STATS(jniinvokation();)
3336 *exceptionptr = new_negativearraysizeexception();
3340 ia = builtin_newarray_int(len);
3342 return (jintArray) NewLocalRef(env, (jobject) ia);
3346 jlongArray NewLongArray(JNIEnv *env, jsize len)
3350 STATS(jniinvokation();)
3353 *exceptionptr = new_negativearraysizeexception();
3357 la = builtin_newarray_long(len);
3359 return (jlongArray) NewLocalRef(env, (jobject) la);
3363 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3365 java_floatarray *fa;
3367 STATS(jniinvokation();)
3370 *exceptionptr = new_negativearraysizeexception();
3374 fa = builtin_newarray_float(len);
3376 return (jfloatArray) NewLocalRef(env, (jobject) fa);
3380 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3382 java_doublearray *da;
3384 STATS(jniinvokation();)
3387 *exceptionptr = new_negativearraysizeexception();
3391 da = builtin_newarray_double(len);
3393 return (jdoubleArray) NewLocalRef(env, (jobject) da);
3397 /* Get<PrimitiveType>ArrayElements *********************************************
3399 A family of functions that returns the body of the primitive array.
3401 *******************************************************************************/
3403 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3406 STATS(jniinvokation();)
3409 *isCopy = JNI_FALSE;
3415 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3417 STATS(jniinvokation();)
3420 *isCopy = JNI_FALSE;
3426 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3428 STATS(jniinvokation();)
3431 *isCopy = JNI_FALSE;
3437 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3439 STATS(jniinvokation();)
3442 *isCopy = JNI_FALSE;
3448 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3450 STATS(jniinvokation();)
3453 *isCopy = JNI_FALSE;
3459 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3461 STATS(jniinvokation();)
3464 *isCopy = JNI_FALSE;
3470 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3472 STATS(jniinvokation();)
3475 *isCopy = JNI_FALSE;
3481 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3484 STATS(jniinvokation();)
3487 *isCopy = JNI_FALSE;
3493 /* Release<PrimitiveType>ArrayElements *****************************************
3495 A family of functions that informs the VM that the native code no
3496 longer needs access to elems. The elems argument is a pointer
3497 derived from array using the corresponding
3498 Get<PrimitiveType>ArrayElements() function. If necessary, this
3499 function copies back all changes made to elems to the original
3502 *******************************************************************************/
3504 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3505 jboolean *elems, jint mode)
3507 STATS(jniinvokation();)
3509 if (elems != array->data) {
3512 MCOPY(array->data, elems, jboolean, array->header.size);
3515 MCOPY(array->data, elems, jboolean, array->header.size);
3516 /* XXX TWISTI how should it be freed? */
3519 /* XXX TWISTI how should it be freed? */
3526 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
3529 STATS(jniinvokation();)
3531 if (elems != array->data) {
3534 MCOPY(array->data, elems, jboolean, array->header.size);
3537 MCOPY(array->data, elems, jboolean, array->header.size);
3538 /* XXX TWISTI how should it be freed? */
3541 /* XXX TWISTI how should it be freed? */
3548 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
3551 STATS(jniinvokation();)
3553 if (elems != array->data) {
3556 MCOPY(array->data, elems, jboolean, array->header.size);
3559 MCOPY(array->data, elems, jboolean, array->header.size);
3560 /* XXX TWISTI how should it be freed? */
3563 /* XXX TWISTI how should it be freed? */
3570 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
3573 STATS(jniinvokation();)
3575 if (elems != array->data) {
3578 MCOPY(array->data, elems, jboolean, array->header.size);
3581 MCOPY(array->data, elems, jboolean, array->header.size);
3582 /* XXX TWISTI how should it be freed? */
3585 /* XXX TWISTI how should it be freed? */
3592 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
3595 STATS(jniinvokation();)
3597 if (elems != array->data) {
3600 MCOPY(array->data, elems, jboolean, array->header.size);
3603 MCOPY(array->data, elems, jboolean, array->header.size);
3604 /* XXX TWISTI how should it be freed? */
3607 /* XXX TWISTI how should it be freed? */
3614 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
3617 STATS(jniinvokation();)
3619 if (elems != array->data) {
3622 MCOPY(array->data, elems, jboolean, array->header.size);
3625 MCOPY(array->data, elems, jboolean, array->header.size);
3626 /* XXX TWISTI how should it be freed? */
3629 /* XXX TWISTI how should it be freed? */
3636 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
3639 STATS(jniinvokation();)
3641 if (elems != array->data) {
3644 MCOPY(array->data, elems, jboolean, array->header.size);
3647 MCOPY(array->data, elems, jboolean, array->header.size);
3648 /* XXX TWISTI how should it be freed? */
3651 /* XXX TWISTI how should it be freed? */
3658 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3659 jdouble *elems, jint mode)
3661 STATS(jniinvokation();)
3663 if (elems != array->data) {
3666 MCOPY(array->data, elems, jboolean, array->header.size);
3669 MCOPY(array->data, elems, jboolean, array->header.size);
3670 /* XXX TWISTI how should it be freed? */
3673 /* XXX TWISTI how should it be freed? */
3680 /* Get<PrimitiveType>ArrayRegion **********************************************
3682 A family of functions that copies a region of a primitive array
3685 *******************************************************************************/
3687 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3688 jsize len, jboolean *buf)
3690 STATS(jniinvokation();)
3692 if (start < 0 || len < 0 || start + len > array->header.size)
3694 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3697 MCOPY(buf, &array->data[start], jboolean, len);
3701 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3704 STATS(jniinvokation();)
3706 if (start < 0 || len < 0 || start + len > array->header.size)
3708 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3711 MCOPY(buf, &array->data[start], jbyte, len);
3715 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3718 STATS(jniinvokation();)
3720 if (start < 0 || len < 0 || start + len > array->header.size)
3722 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3725 MCOPY(buf, &array->data[start], jchar, len);
3729 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3730 jsize len, jshort *buf)
3732 STATS(jniinvokation();)
3734 if (start < 0 || len < 0 || start + len > array->header.size)
3736 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3739 MCOPY(buf, &array->data[start], jshort, len);
3743 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3746 STATS(jniinvokation();)
3748 if (start < 0 || len < 0 || start + len > array->header.size)
3750 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3753 MCOPY(buf, &array->data[start], jint, len);
3757 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
3760 STATS(jniinvokation();)
3762 if (start < 0 || len < 0 || start + len > array->header.size)
3764 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3767 MCOPY(buf, &array->data[start], jlong, len);
3771 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3772 jsize len, jfloat *buf)
3774 STATS(jniinvokation();)
3776 if (start < 0 || len < 0 || start + len > array->header.size)
3778 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3781 MCOPY(buf, &array->data[start], jfloat, len);
3785 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3786 jsize len, jdouble *buf)
3788 STATS(jniinvokation();)
3790 if (start < 0 || len < 0 || start+len>array->header.size)
3792 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3795 MCOPY(buf, &array->data[start], jdouble, len);
3799 /* Set<PrimitiveType>ArrayRegion **********************************************
3801 A family of functions that copies back a region of a primitive
3802 array from a buffer.
3804 *******************************************************************************/
3806 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3807 jsize len, jboolean *buf)
3809 STATS(jniinvokation();)
3811 if (start < 0 || len < 0 || start + len > array->header.size)
3813 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3816 MCOPY(&array->data[start], buf, jboolean, len);
3820 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3823 STATS(jniinvokation();)
3825 if (start < 0 || len < 0 || start + len > array->header.size)
3827 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3830 MCOPY(&array->data[start], buf, jbyte, len);
3834 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3837 STATS(jniinvokation();)
3839 if (start < 0 || len < 0 || start + len > array->header.size)
3841 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3844 MCOPY(&array->data[start], buf, jchar, len);
3849 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3850 jsize len, jshort *buf)
3852 STATS(jniinvokation();)
3854 if (start < 0 || len < 0 || start + len > array->header.size)
3856 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3859 MCOPY(&array->data[start], buf, jshort, len);
3863 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3866 STATS(jniinvokation();)
3868 if (start < 0 || len < 0 || start + len > array->header.size)
3870 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3873 MCOPY(&array->data[start], buf, jint, len);
3878 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
3881 STATS(jniinvokation();)
3883 if (start < 0 || len < 0 || start + len > array->header.size)
3885 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3888 MCOPY(&array->data[start], buf, jlong, len);
3893 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3894 jsize len, jfloat *buf)
3896 STATS(jniinvokation();)
3898 if (start < 0 || len < 0 || start + len > array->header.size)
3900 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3903 MCOPY(&array->data[start], buf, jfloat, len);
3908 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3909 jsize len, jdouble *buf)
3911 STATS(jniinvokation();)
3913 if (start < 0 || len < 0 || start + len > array->header.size)
3915 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3918 MCOPY(&array->data[start], buf, jdouble, len);
3922 /* Registering Native Methods *************************************************/
3924 /* RegisterNatives *************************************************************
3926 Registers native methods with the class specified by the clazz
3927 argument. The methods parameter specifies an array of
3928 JNINativeMethod structures that contain the names, signatures, and
3929 function pointers of the native methods. The nMethods parameter
3930 specifies the number of native methods in the array.
3932 *******************************************************************************/
3934 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
3937 STATS(jniinvokation();)
3939 log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
3945 /* UnregisterNatives ***********************************************************
3947 Unregisters native methods of a class. The class goes back to the
3948 state before it was linked or registered with its native method
3951 This function should not be used in normal native code. Instead, it
3952 provides special programs a way to reload and relink native
3955 *******************************************************************************/
3957 jint UnregisterNatives(JNIEnv *env, jclass clazz)
3959 STATS(jniinvokation();)
3961 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3963 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3969 /* Monitor Operations *********************************************************/
3971 /* MonitorEnter ****************************************************************
3973 Enters the monitor associated with the underlying Java object
3976 *******************************************************************************/
3978 jint MonitorEnter(JNIEnv *env, jobject obj)
3980 STATS(jniinvokation();)
3983 *exceptionptr = new_nullpointerexception();
3987 #if defined(USE_THREADS)
3988 builtin_monitorenter(obj);
3995 /* MonitorExit *****************************************************************
3997 The current thread must be the owner of the monitor associated with
3998 the underlying Java object referred to by obj. The thread
3999 decrements the counter indicating the number of times it has
4000 entered this monitor. If the value of the counter becomes zero, the
4001 current thread releases the monitor.
4003 *******************************************************************************/
4005 jint MonitorExit(JNIEnv *env, jobject obj)
4007 STATS(jniinvokation();)
4009 *exceptionptr = new_nullpointerexception();
4013 #if defined(USE_THREADS)
4014 builtin_monitorexit(obj);
4021 /* JavaVM Interface ***********************************************************/
4023 /* GetJavaVM *******************************************************************
4025 Returns the Java VM interface (used in the Invocation API)
4026 associated with the current thread. The result is placed at the
4027 location pointed to by the second argument, vm.
4029 *******************************************************************************/
4031 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
4033 STATS(jniinvokation();)
4040 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
4042 STATS(jniinvokation();)
4043 log_text("JNI-Call: GetStringRegion");
4047 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
4049 STATS(jniinvokation();)
4051 log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
4055 /* GetPrimitiveArrayCritical ***************************************************
4057 Obtain a direct pointer to array elements.
4059 *******************************************************************************/
4061 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
4066 ba = (java_bytearray *) array;
4068 /* do the same as Kaffe does */
4070 bp = GetByteArrayElements(env, ba, isCopy);
4076 /* ReleasePrimitiveArrayCritical ***********************************************
4078 No specific documentation.
4080 *******************************************************************************/
4082 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
4085 STATS(jniinvokation();)
4087 /* do the same as Kaffe does */
4089 ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
4093 /* GetStringCritical ***********************************************************
4095 The semantics of these two functions are similar to the existing
4096 Get/ReleaseStringChars functions.
4098 *******************************************************************************/
4100 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
4102 STATS(jniinvokation();)
4104 return GetStringChars(env, string, isCopy);
4108 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
4110 STATS(jniinvokation();)
4112 ReleaseStringChars(env, string, cstring);
4116 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
4118 STATS(jniinvokation();)
4119 log_text("JNI-Call: NewWeakGlobalRef");
4125 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
4127 STATS(jniinvokation();)
4128 log_text("JNI-Call: DeleteWeakGlobalRef");
4134 /* NewGlobalRef ****************************************************************
4136 Creates a new global reference to the object referred to by the obj
4139 *******************************************************************************/
4141 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4143 java_lang_Integer *refcount;
4144 java_objectheader *newval;
4146 STATS(jniinvokation();)
4148 #if defined(USE_THREADS)
4149 builtin_monitorenter(*global_ref_table);
4152 refcount = (java_lang_Integer *)
4153 asm_calljavafunction(getmid, *global_ref_table, lobj, NULL, NULL);
4155 if (refcount == NULL) {
4156 newval = native_new_and_init_int(class_java_lang_Integer, 1);
4158 if (newval == NULL) {
4159 #if defined(USE_THREADS)
4160 builtin_monitorexit(*global_ref_table);
4165 asm_calljavafunction(putmid, *global_ref_table, lobj, newval, NULL);
4168 /* we can access the object itself, as we are in a
4169 synchronized section */
4174 #if defined(USE_THREADS)
4175 builtin_monitorexit(*global_ref_table);
4182 /* DeleteGlobalRef *************************************************************
4184 Deletes the global reference pointed to by globalRef.
4186 *******************************************************************************/
4188 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
4190 java_lang_Integer *refcount;
4193 STATS(jniinvokation();)
4195 #if defined(USE_THREADS)
4196 builtin_monitorenter(*global_ref_table);
4199 refcount = (java_lang_Integer *)
4200 asm_calljavafunction(getmid, *global_ref_table, globalRef, NULL, NULL);
4202 if (refcount == NULL) {
4203 log_text("JNI-DeleteGlobalRef: unable to find global reference");
4207 /* we can access the object itself, as we are in a synchronized
4210 val = refcount->value - 1;
4213 asm_calljavafunction(removemid, *global_ref_table, refcount, NULL,
4217 /* we do not create a new object, but set the new value into
4220 refcount->value = val;
4223 #if defined(USE_THREADS)
4224 builtin_monitorexit(*global_ref_table);
4229 /* ExceptionCheck **************************************************************
4231 Returns JNI_TRUE when there is a pending exception; otherwise,
4234 *******************************************************************************/
4236 jboolean ExceptionCheck(JNIEnv *env)
4238 STATS(jniinvokation();)
4239 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
4243 /* New JNI 1.4 functions ******************************************************/
4245 /* NewDirectByteBuffer *********************************************************
4247 Allocates and returns a direct java.nio.ByteBuffer referring to the
4248 block of memory starting at the memory address address and
4249 extending capacity bytes.
4251 *******************************************************************************/
4253 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
4255 java_nio_DirectByteBufferImpl *nbuf;
4256 #if SIZEOF_VOID_P == 8
4257 gnu_classpath_Pointer64 *paddress;
4259 gnu_classpath_Pointer32 *paddress;
4262 STATS(jniinvokation();)
4264 log_text("JNI-NewDirectByteBuffer: called");
4266 /* allocate a java.nio.DirectByteBufferImpl object */
4268 if (!(nbuf = (java_nio_DirectByteBufferImpl *) builtin_new(class_java_nio_DirectByteBufferImpl)))
4271 /* alocate a gnu.classpath.Pointer{32,64} object */
4273 #if SIZEOF_VOID_P == 8
4274 if (!(paddress = (gnu_classpath_Pointer64 *) builtin_new(class_gnu_classpath_Pointer64)))
4276 if (!(paddress = (gnu_classpath_Pointer32 *) builtin_new(class_gnu_classpath_Pointer32)))
4280 /* fill gnu.classpath.Pointer{32,64} with address */
4282 paddress->data = (ptrint) address;
4284 /* fill java.nio.Buffer object */
4286 nbuf->cap = (s4) capacity;
4287 nbuf->limit = (s4) capacity;
4289 nbuf->address = (gnu_classpath_Pointer *) paddress;
4291 /* add local reference and return the value */
4293 return NewLocalRef(env, (jobject) nbuf);
4297 /* GetDirectBufferAddress ******************************************************
4299 Fetches and returns the starting address of the memory region
4300 referenced by the given direct java.nio.Buffer.
4302 *******************************************************************************/
4304 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
4306 java_nio_DirectByteBufferImpl *nbuf;
4307 #if SIZEOF_VOID_P == 8
4308 gnu_classpath_Pointer64 *address;
4310 gnu_classpath_Pointer32 *address;
4313 STATS(jniinvokation();)
4316 if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
4320 nbuf = (java_nio_DirectByteBufferImpl *) buf;
4322 #if SIZEOF_VOID_P == 8
4323 address = (gnu_classpath_Pointer64 *) nbuf->address;
4325 address = (gnu_classpath_Pointer32 *) nbuf->address;
4328 return (void *) address->data;
4332 /* GetDirectBufferCapacity *****************************************************
4334 Fetches and returns the capacity in bytes of the memory region
4335 referenced by the given direct java.nio.Buffer.
4337 *******************************************************************************/
4339 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
4341 java_nio_Buffer *nbuf;
4343 STATS(jniinvokation();)
4348 nbuf = (java_nio_Buffer *) buf;
4350 return (jlong) nbuf->cap;
4354 jint DestroyJavaVM(JavaVM *vm)
4356 STATS(jniinvokation();)
4357 log_text("DestroyJavaVM called");
4363 /* AttachCurrentThread *********************************************************
4365 Attaches the current thread to a Java VM. Returns a JNI interface
4366 pointer in the JNIEnv argument.
4368 Trying to attach a thread that is already attached is a no-op.
4370 A native thread cannot be attached simultaneously to two Java VMs.
4372 When a thread is attached to the VM, the context class loader is
4373 the bootstrap loader.
4375 *******************************************************************************/
4377 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
4379 STATS(jniinvokation();)
4381 log_text("AttachCurrentThread called");
4383 #if !defined(HAVE___THREAD)
4384 /* cacao_thread_attach();*/
4386 #error "No idea how to implement that. Perhaps Stefan knows"
4395 jint DetachCurrentThread(JavaVM *vm)
4397 STATS(jniinvokation();)
4398 log_text("DetachCurrentThread called");
4404 /* GetEnv **********************************************************************
4406 If the current thread is not attached to the VM, sets *env to NULL,
4407 and returns JNI_EDETACHED. If the specified version is not
4408 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
4409 sets *env to the appropriate interface, and returns JNI_OK.
4411 *******************************************************************************/
4413 jint GetEnv(JavaVM *vm, void **env, jint version)
4415 STATS(jniinvokation();)
4417 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4418 if (thread_getself() == NULL) {
4421 return JNI_EDETACHED;
4425 if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
4426 (version == JNI_VERSION_1_4)) {
4432 #if defined(ENABLE_JVMTI)
4433 if (version == JVMTI_VERSION_1_0) {
4434 *env = (void *) new_jvmtienv();
4443 return JNI_EVERSION;
4448 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4450 STATS(jniinvokation();)
4451 log_text("AttachCurrentThreadAsDaemon called");
4457 /* JNI invocation table *******************************************************/
4459 const struct JNIInvokeInterface JNI_JavaVMTable = {
4465 AttachCurrentThread,
4466 DetachCurrentThread,
4468 AttachCurrentThreadAsDaemon
4472 /* JNI function table *********************************************************/
4474 struct JNINativeInterface JNI_JNIEnvTable = {
4483 &FromReflectedMethod,
4484 &FromReflectedField,
4504 &EnsureLocalCapacity,
4520 &CallBooleanMethodV,
4521 &CallBooleanMethodA,
4547 &CallNonvirtualObjectMethod,
4548 &CallNonvirtualObjectMethodV,
4549 &CallNonvirtualObjectMethodA,
4550 &CallNonvirtualBooleanMethod,
4551 &CallNonvirtualBooleanMethodV,
4552 &CallNonvirtualBooleanMethodA,
4553 &CallNonvirtualByteMethod,
4554 &CallNonvirtualByteMethodV,
4555 &CallNonvirtualByteMethodA,
4556 &CallNonvirtualCharMethod,
4557 &CallNonvirtualCharMethodV,
4558 &CallNonvirtualCharMethodA,
4559 &CallNonvirtualShortMethod,
4560 &CallNonvirtualShortMethodV,
4561 &CallNonvirtualShortMethodA,
4562 &CallNonvirtualIntMethod,
4563 &CallNonvirtualIntMethodV,
4564 &CallNonvirtualIntMethodA,
4565 &CallNonvirtualLongMethod,
4566 &CallNonvirtualLongMethodV,
4567 &CallNonvirtualLongMethodA,
4568 &CallNonvirtualFloatMethod,
4569 &CallNonvirtualFloatMethodV,
4570 &CallNonvirtualFloatMethodA,
4571 &CallNonvirtualDoubleMethod,
4572 &CallNonvirtualDoubleMethodV,
4573 &CallNonvirtualDoubleMethodA,
4574 &CallNonvirtualVoidMethod,
4575 &CallNonvirtualVoidMethodV,
4576 &CallNonvirtualVoidMethodA,
4601 &CallStaticObjectMethod,
4602 &CallStaticObjectMethodV,
4603 &CallStaticObjectMethodA,
4604 &CallStaticBooleanMethod,
4605 &CallStaticBooleanMethodV,
4606 &CallStaticBooleanMethodA,
4607 &CallStaticByteMethod,
4608 &CallStaticByteMethodV,
4609 &CallStaticByteMethodA,
4610 &CallStaticCharMethod,
4611 &CallStaticCharMethodV,
4612 &CallStaticCharMethodA,
4613 &CallStaticShortMethod,
4614 &CallStaticShortMethodV,
4615 &CallStaticShortMethodA,
4616 &CallStaticIntMethod,
4617 &CallStaticIntMethodV,
4618 &CallStaticIntMethodA,
4619 &CallStaticLongMethod,
4620 &CallStaticLongMethodV,
4621 &CallStaticLongMethodA,
4622 &CallStaticFloatMethod,
4623 &CallStaticFloatMethodV,
4624 &CallStaticFloatMethodA,
4625 &CallStaticDoubleMethod,
4626 &CallStaticDoubleMethodV,
4627 &CallStaticDoubleMethodA,
4628 &CallStaticVoidMethod,
4629 &CallStaticVoidMethodV,
4630 &CallStaticVoidMethodA,
4634 &GetStaticObjectField,
4635 &GetStaticBooleanField,
4636 &GetStaticByteField,
4637 &GetStaticCharField,
4638 &GetStaticShortField,
4640 &GetStaticLongField,
4641 &GetStaticFloatField,
4642 &GetStaticDoubleField,
4643 &SetStaticObjectField,
4644 &SetStaticBooleanField,
4645 &SetStaticByteField,
4646 &SetStaticCharField,
4647 &SetStaticShortField,
4649 &SetStaticLongField,
4650 &SetStaticFloatField,
4651 &SetStaticDoubleField,
4656 &ReleaseStringChars,
4659 &GetStringUTFLength,
4661 &ReleaseStringUTFChars,
4666 &GetObjectArrayElement,
4667 &SetObjectArrayElement,
4678 &GetBooleanArrayElements,
4679 &GetByteArrayElements,
4680 &GetCharArrayElements,
4681 &GetShortArrayElements,
4682 &GetIntArrayElements,
4683 &GetLongArrayElements,
4684 &GetFloatArrayElements,
4685 &GetDoubleArrayElements,
4687 &ReleaseBooleanArrayElements,
4688 &ReleaseByteArrayElements,
4689 &ReleaseCharArrayElements,
4690 &ReleaseShortArrayElements,
4691 &ReleaseIntArrayElements,
4692 &ReleaseLongArrayElements,
4693 &ReleaseFloatArrayElements,
4694 &ReleaseDoubleArrayElements,
4696 &GetBooleanArrayRegion,
4697 &GetByteArrayRegion,
4698 &GetCharArrayRegion,
4699 &GetShortArrayRegion,
4701 &GetLongArrayRegion,
4702 &GetFloatArrayRegion,
4703 &GetDoubleArrayRegion,
4704 &SetBooleanArrayRegion,
4705 &SetByteArrayRegion,
4706 &SetCharArrayRegion,
4707 &SetShortArrayRegion,
4709 &SetLongArrayRegion,
4710 &SetFloatArrayRegion,
4711 &SetDoubleArrayRegion,
4721 /* new JNI 1.2 functions */
4724 &GetStringUTFRegion,
4726 &GetPrimitiveArrayCritical,
4727 &ReleasePrimitiveArrayCritical,
4730 &ReleaseStringCritical,
4733 &DeleteWeakGlobalRef,
4737 /* new JNI 1.4 functions */
4739 &NewDirectByteBuffer,
4740 &GetDirectBufferAddress,
4741 &GetDirectBufferCapacity
4745 /* Invocation API Functions ***************************************************/
4747 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4749 Returns a default configuration for the Java VM.
4751 *******************************************************************************/
4753 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4755 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4757 /* GNU classpath currently supports JNI 1.2 */
4759 _vm_args->version = JNI_VERSION_1_2;
4765 /* JNI_GetCreatedJavaVMs *******************************************************
4767 Returns all Java VMs that have been created. Pointers to VMs are written in
4768 the buffer vmBuf in the order they are created. At most bufLen number of
4769 entries will be written. The total number of created VMs is returned in
4772 *******************************************************************************/
4774 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4776 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4782 /* JNI_CreateJavaVM ************************************************************
4784 Loads and initializes a Java VM. The current thread becomes the main thread.
4785 Sets the env argument to the JNI interface pointer of the main thread.
4787 *******************************************************************************/
4789 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4791 const struct JNIInvokeInterface *vm;
4792 struct JNINativeInterface *env;
4794 vm = &JNI_JavaVMTable;
4795 env = &JNI_JNIEnvTable;
4797 *p_vm = (JavaVM *) vm;
4798 *p_env = (JNIEnv *) env;
4804 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4805 jobject obj, java_objectarray *params)
4812 if (methodID == 0) {
4813 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
4817 argcount = methodID->parseddesc->paramcount;
4818 paramcount = argcount;
4820 /* if method is non-static, remove the `this' pointer */
4822 if (!(methodID->flags & ACC_STATIC))
4825 /* the method is an instance method the obj has to be an instance of the
4826 class the method belongs to. For static methods the obj parameter
4829 if (!(methodID->flags & ACC_STATIC) && obj &&
4830 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4832 new_exception_message(string_java_lang_IllegalArgumentException,
4833 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4837 if (((params == NULL) && (paramcount != 0)) ||
4838 (params && (params->header.size != paramcount))) {
4840 new_exception(string_java_lang_IllegalArgumentException);
4845 if (!(methodID->flags & ACC_STATIC) && !obj) {
4847 new_exception_message(string_java_lang_NullPointerException,
4848 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4852 if ((methodID->flags & ACC_STATIC) && (obj))
4856 if ((methodID->flags & ACC_ABSTRACT) ||
4857 (methodID->class->flags & ACC_INTERFACE)) {
4858 methodID = get_virtual(obj, methodID);
4862 blk = MNEW(jni_callblock, argcount);
4864 if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4868 switch (methodID->parseddesc->returntype.decltype) {
4870 (void) asm_calljavafunction2(methodID, argcount,
4871 argcount * sizeof(jni_callblock),
4873 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4876 case PRIMITIVETYPE_INT: {
4878 i = asm_calljavafunction2int(methodID, argcount,
4879 argcount * sizeof(jni_callblock),
4882 o = native_new_and_init_int(class_java_lang_Integer, i);
4886 case PRIMITIVETYPE_BYTE: {
4888 i = asm_calljavafunction2int(methodID, argcount,
4889 argcount * sizeof(jni_callblock),
4892 /* o = native_new_and_init_int(class_java_lang_Byte, i); */
4893 o = builtin_new(class_java_lang_Byte);
4896 class_resolvemethod(o->vftbl->class,
4903 case PRIMITIVETYPE_CHAR: {
4905 intVal = asm_calljavafunction2int(methodID,
4907 argcount * sizeof(jni_callblock),
4909 o = builtin_new(class_java_lang_Character);
4912 class_resolvemethod(o->vftbl->class,
4919 case PRIMITIVETYPE_SHORT: {
4921 intVal = asm_calljavafunction2int(methodID,
4923 argcount * sizeof(jni_callblock),
4925 o = builtin_new(class_java_lang_Short);
4928 class_resolvemethod(o->vftbl->class,
4935 case PRIMITIVETYPE_BOOLEAN: {
4937 intVal = asm_calljavafunction2int(methodID,
4939 argcount * sizeof(jni_callblock),
4941 o = builtin_new(class_java_lang_Boolean);
4944 class_resolvemethod(o->vftbl->class,
4951 case PRIMITIVETYPE_LONG: {
4953 longVal = asm_calljavafunction2long(methodID,
4955 argcount * sizeof(jni_callblock),
4957 o = builtin_new(class_java_lang_Long);
4960 class_resolvemethod(o->vftbl->class,
4967 case PRIMITIVETYPE_FLOAT: {
4969 floatVal = asm_calljavafunction2float(methodID,
4971 argcount * sizeof(jni_callblock),
4973 o = builtin_new(class_java_lang_Float);
4976 class_resolvemethod(o->vftbl->class,
4983 case PRIMITIVETYPE_DOUBLE: {
4985 doubleVal = asm_calljavafunction2double(methodID,
4987 argcount * sizeof(jni_callblock),
4989 o = builtin_new(class_java_lang_Double);
4992 class_resolvemethod(o->vftbl->class,
5000 o = asm_calljavafunction2(methodID, argcount,
5001 argcount * sizeof(jni_callblock), blk);
5005 /* if this happens the exception has already been set by */
5006 /* fill_callblock_from_objectarray */
5008 MFREE(blk, jni_callblock, argcount);
5009 return (jobject *) 0;
5012 MFREE(blk, jni_callblock, argcount);
5014 if (*exceptionptr) {
5015 java_objectheader *cause;
5017 cause = *exceptionptr;
5019 /* clear exception pointer, we are calling JIT code again */
5021 *exceptionptr = NULL;
5024 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
5025 (java_lang_Throwable *) cause);
5028 return (jobject *) o;
5033 * These are local overrides for various environment variables in Emacs.
5034 * Please do not remove this and leave it at the end of the file, where
5035 * Emacs will automagically detect them.
5036 * ---------------------------------------------------------------------
5039 * indent-tabs-mode: t