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 3663 2005-11-11 14:06:36Z 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 **********************************/
157 #define setField(obj,typ,var,val) *((typ*) ((long int) obj + (long int) var->offset))=val;
158 #define getField(obj,typ,var) *((typ*) ((long int) obj + (long int) var->offset))
161 /* some forward declarations **************************************************/
163 jobject NewLocalRef(JNIEnv *env, jobject ref);
166 /* jni_init ********************************************************************
168 Initialize the JNI subsystem.
170 *******************************************************************************/
174 /* initalize global reference table */
177 load_class_bootstrap(utf_new_char("java/util/IdentityHashMap"))))
180 global_ref_table = GCNEW(jobject, 1);
182 if (!(*global_ref_table = native_new_and_init(ihmclass)))
185 if (!(getmid = class_resolvemethod(ihmclass, utf_get,
186 utf_java_lang_Object__java_lang_Object)))
189 if (!(putmid = class_resolvemethod(ihmclass, utf_put,
190 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))))
194 class_resolvemethod(ihmclass, utf_remove,
195 utf_java_lang_Object__java_lang_Object)))
199 /* direct buffer stuff */
201 utf_java_nio_DirectByteBufferImpl =
202 utf_new_char("java/nio/DirectByteBufferImpl");
204 if (!(class_java_nio_DirectByteBufferImpl =
205 load_class_bootstrap(utf_java_nio_DirectByteBufferImpl)))
208 if (!link_class(class_java_nio_DirectByteBufferImpl))
211 #if SIZEOF_VOID_P == 8
212 utf_gnu_classpath_Pointer64 = utf_new_char("gnu/classpath/Pointer64");
214 if (!(class_gnu_classpath_Pointer64 =
215 load_class_bootstrap(utf_gnu_classpath_Pointer64)))
218 if (!link_class(class_gnu_classpath_Pointer64))
221 utf_gnu_classpath_Pointer32 = utf_new_char("gnu/classpath/Pointer32");
223 if (!(class_gnu_classpath_Pointer32 =
224 load_class_bootstrap(utf_gnu_classpath_Pointer32)))
227 if (!link_class(class_gnu_classpath_Pointer32))
235 static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
236 jni_callblock blk[], va_list data,
239 typedesc *paramtypes;
242 paramtypes = descr->paramtypes;
244 /* if method is non-static fill first block and skip `this' pointer */
249 /* the `this' pointer */
250 blk[0].itemtype = TYPE_ADR;
251 blk[0].item = PTR_TO_ITEM(obj);
257 for (; i < descr->paramcount; i++, paramtypes++) {
258 switch (paramtypes->decltype) {
259 /* primitive types */
260 case PRIMITIVETYPE_BYTE:
261 case PRIMITIVETYPE_CHAR:
262 case PRIMITIVETYPE_SHORT:
263 case PRIMITIVETYPE_BOOLEAN:
264 blk[i].itemtype = TYPE_INT;
265 blk[i].item = (s8) va_arg(data, s4);
268 case PRIMITIVETYPE_INT:
269 blk[i].itemtype = TYPE_INT;
270 blk[i].item = (s8) va_arg(data, s4);
273 case PRIMITIVETYPE_LONG:
274 blk[i].itemtype = TYPE_LNG;
275 blk[i].item = (s8) va_arg(data, s8);
278 case PRIMITIVETYPE_FLOAT:
279 blk[i].itemtype = TYPE_FLT;
280 #if defined(__ALPHA__)
281 /* this keeps the assembler function much simpler */
283 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
285 *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
289 case PRIMITIVETYPE_DOUBLE:
290 blk[i].itemtype = TYPE_DBL;
291 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
295 blk[i].itemtype = TYPE_ADR;
296 blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
301 /* The standard doesn't say anything about return value checking, but it */
302 /* appears to be useful. */
304 if (rettype != descr->returntype.decltype)
305 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
309 /* XXX it could be considered if we should do typechecking here in the future */
311 static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
313 java_objectarray *params)
317 typedesc *paramtypes;
322 paramcount = descr->paramcount;
323 paramtypes = descr->paramtypes;
325 /* if method is non-static fill first block and skip `this' pointer */
331 blk[0].itemtype = TYPE_ADR;
332 blk[0].item = PTR_TO_ITEM(obj);
339 for (j = 0; j < paramcount; i++, j++, paramtypes++) {
340 switch (paramtypes->type) {
341 /* primitive types */
346 param = params->data[j];
350 /* internally used data type */
351 blk[i].itemtype = paramtypes->type;
353 /* convert the value according to its declared type */
355 c = param->vftbl->class;
357 switch (paramtypes->decltype) {
358 case PRIMITIVETYPE_BOOLEAN:
359 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
360 blk[i].item = (s8) ((java_lang_Boolean *) param)->value;
365 case PRIMITIVETYPE_BYTE:
366 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
367 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
372 case PRIMITIVETYPE_CHAR:
373 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
374 blk[i].item = (s8) ((java_lang_Character *) param)->value;
379 case PRIMITIVETYPE_SHORT:
380 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
381 blk[i].item = (s8) ((java_lang_Short *) param)->value;
382 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
383 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
388 case PRIMITIVETYPE_INT:
389 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
390 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
391 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
392 blk[i].item = (s8) ((java_lang_Short *) param)->value;
393 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
394 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
399 case PRIMITIVETYPE_LONG:
400 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
401 blk[i].item = (s8) ((java_lang_Long *) param)->value;
402 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
403 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
404 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
405 blk[i].item = (s8) ((java_lang_Short *) param)->value;
406 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
407 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
412 case PRIMITIVETYPE_FLOAT:
413 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
414 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
419 case PRIMITIVETYPE_DOUBLE:
420 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
421 *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Float *) param)->value;
422 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
423 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
430 } /* end declared type switch */
434 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
437 if (params->data[j] != 0) {
438 if (paramtypes->arraydim > 0) {
439 if (!builtin_arrayinstanceof(params->data[j], c))
443 if (!builtin_instanceof(params->data[j], c))
447 blk[i].itemtype = TYPE_ADR;
448 blk[i].item = PTR_TO_ITEM(params->data[j]);
453 } /* end param type switch */
455 } /* end param loop */
458 /* *rettype = descr->returntype.decltype; */
463 *exceptionptr = new_illegalargumentexception();
468 static jmethodID get_virtual(jobject obj, jmethodID methodID)
470 if (obj->vftbl->class == methodID->class)
473 return class_resolvemethod(obj->vftbl->class, methodID->name,
474 methodID->descriptor);
478 static jmethodID get_nonvirtual(jclass clazz, jmethodID methodID)
480 if (clazz == methodID->class)
483 /* class_resolvemethod -> classfindmethod? (JOWENN) */
484 return class_resolvemethod(clazz, methodID->name, methodID->descriptor);
488 static jobject callObjectMethod(jobject obj, jmethodID methodID, va_list args)
495 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
499 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
500 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
501 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
505 if (obj && !builtin_instanceof(obj, methodID->class)) {
506 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
510 argcount = methodID->parseddesc->paramcount;
512 blk = MNEW(jni_callblock, argcount);
514 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_ADR);
516 STATS(jnicallXmethodnvokation();)
518 ret = asm_calljavafunction2(methodID,
520 argcount * sizeof(jni_callblock),
523 MFREE(blk, jni_callblock, argcount);
530 core function for integer class methods (bool, byte, short, integer)
531 This is basically needed for i386
533 static jint callIntegerMethod(jobject obj, jmethodID methodID, int retType, va_list args)
539 STATS(jniinvokation();)
542 log_text("JNI-Call: CallObjectMethodV");
543 utf_display(methodID->name);
544 utf_display(methodID->descriptor);
545 printf("\nParmaeter count: %d\n",argcount);
546 utf_display(obj->vftbl->class->name);
550 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
554 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
555 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
556 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
560 if (obj && !builtin_instanceof(obj, methodID->class)) {
561 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
565 argcount = methodID->parseddesc->paramcount;
567 blk = MNEW(jni_callblock, argcount);
569 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
571 STATS(jnicallXmethodnvokation();)
573 ret = asm_calljavafunction2int(methodID,
575 argcount * sizeof(jni_callblock),
578 MFREE(blk, jni_callblock, argcount);
584 /* callLongMethod **************************************************************
586 Core function for long class functions.
588 *******************************************************************************/
590 static jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
596 STATS(jniinvokation();)
599 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
603 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
604 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
605 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
609 if (obj && !builtin_instanceof(obj, methodID->class)) {
610 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
614 argcount = methodID->parseddesc->paramcount;
616 blk = MNEW(jni_callblock, argcount);
618 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_LNG);
620 STATS(jnicallXmethodnvokation();)
622 ret = asm_calljavafunction2long(methodID,
624 argcount * sizeof(jni_callblock),
627 MFREE(blk, jni_callblock, argcount);
633 /*core function for float class methods (float,double)*/
634 static jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,int retType)
636 int argcount = methodID->parseddesc->paramcount;
640 STATS(jniinvokation();)
645 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
646 log_text("Too many arguments. CallObjectMethod does not support that");
650 blk = MNEW(jni_callblock, /*4 */ argcount+2);
652 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
654 /* printf("parameter: obj: %p",blk[0].item); */
655 STATS(jnicallXmethodnvokation();)
656 ret = asm_calljavafunction2double(methodID,
658 (argcount + 1) * sizeof(jni_callblock),
661 MFREE(blk, jni_callblock, argcount + 1);
662 /* printf("(CallObjectMethodV)-->%p\n",ret); */
668 static void cacao_jni_CallVoidMethod(jobject obj, jmethodID m, va_list ap)
674 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
678 if (!( ((m->flags & ACC_STATIC) && (obj == 0)) ||
679 ((!(m->flags & ACC_STATIC)) && (obj != 0)) )) {
680 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
684 if (obj && !builtin_instanceof(obj, m->class)) {
685 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
689 paramcount = m->parseddesc->paramcount;
691 /* #error XXX does not work on intrp, but on JIT */
692 if (!(m->flags & ACC_STATIC))
695 blk = MNEW(jni_callblock, paramcount);
697 fill_callblock_from_vargs(obj, m->parseddesc, blk, ap, TYPE_VOID);
699 STATS(jnicallXmethodnvokation();)
701 (void) asm_calljavafunction2(m,
703 paramcount * sizeof(jni_callblock),
706 MFREE(blk, jni_callblock, paramcount);
712 /* GetVersion ******************************************************************
714 Returns the major version number in the higher 16 bits and the
715 minor version number in the lower 16 bits.
717 *******************************************************************************/
719 jint GetVersion(JNIEnv *env)
721 STATS(jniinvokation();)
723 /* we support JNI 1.4 */
725 return JNI_VERSION_1_4;
729 /* Class Operations ***********************************************************/
731 /* DefineClass *****************************************************************
733 Loads a class from a buffer of raw class data. The buffer
734 containing the raw class data is not referenced by the VM after the
735 DefineClass call returns, and it may be discarded if desired.
737 *******************************************************************************/
739 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
740 const jbyte *buf, jsize bufLen)
742 java_lang_ClassLoader *cl;
747 STATS(jniinvokation();)
749 cl = (java_lang_ClassLoader *) loader;
750 s = javastring_new_char(name);
751 ba = (java_bytearray *) buf;
753 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
756 return (jclass) NewLocalRef(env, (jobject) c);
760 /* FindClass *******************************************************************
762 This function loads a locally-defined class. It searches the
763 directories and zip files specified by the CLASSPATH environment
764 variable for the class with the specified name.
766 *******************************************************************************/
768 jclass FindClass(JNIEnv *env, const char *name)
772 java_objectheader *cl;
774 STATS(jniinvokation();)
776 u = utf_new_char_classname((char *) name);
778 /* check stacktrace for classloader, if one found use it, otherwise use */
779 /* the system classloader */
781 #if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__)
782 /* these JITs support stacktraces, and so does the interpreter */
784 cl = cacao_currentClassLoader();
786 # if defined(ENABLE_INTRP)
787 /* the interpreter supports stacktraces, even if the JIT does not */
790 cl = cacao_currentClassLoader();
796 if (!(c = load_class_from_classloader(u, cl)))
802 if (!use_class_as_object(c))
805 return (jclass) NewLocalRef(env, (jobject) c);
809 /* FromReflectedMethod *********************************************************
811 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
812 object to a method ID.
814 *******************************************************************************/
816 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
822 STATS(jniinvokation();)
827 if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
828 java_lang_reflect_Method *rm;
830 rm = (java_lang_reflect_Method *) method;
831 c = (classinfo *) (rm->declaringClass);
834 } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
835 java_lang_reflect_Constructor *rc;
837 rc = (java_lang_reflect_Constructor *) method;
838 c = (classinfo *) (rc->clazz);
844 if ((slot < 0) || (slot >= c->methodscount)) {
845 /* this usually means a severe internal cacao error or somebody
846 tempered around with the reflected method */
847 log_text("error illegal slot for method in class(FromReflectedMethod)");
851 mi = &(c->methods[slot]);
857 /* GetSuperclass ***************************************************************
859 If clazz represents any class other than the class Object, then
860 this function returns the object that represents the superclass of
861 the class specified by clazz.
863 *******************************************************************************/
865 jclass GetSuperclass(JNIEnv *env, jclass sub)
869 STATS(jniinvokation();)
871 c = ((classinfo *) sub)->super.cls;
876 if (!use_class_as_object(c))
879 return (jclass) NewLocalRef(env, (jobject) c);
883 /* IsAssignableFrom ************************************************************
885 Determines whether an object of sub can be safely cast to sup.
887 *******************************************************************************/
889 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
891 STATS(jniinvokation();)
892 return Java_java_lang_VMClass_isAssignableFrom(env,
894 (java_lang_Class *) sup,
895 (java_lang_Class *) sub);
899 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
901 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
903 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!!!");
904 STATS(jniinvokation();)
909 /* Throw ***********************************************************************
911 Causes a java.lang.Throwable object to be thrown.
913 *******************************************************************************/
915 jint Throw(JNIEnv *env, jthrowable obj)
917 *exceptionptr = (java_objectheader *) obj;
918 STATS(jniinvokation();)
924 /* ThrowNew ********************************************************************
926 Constructs an exception object from the specified class with the
927 message specified by message and causes that exception to be
930 *******************************************************************************/
932 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
934 java_lang_Throwable *o;
936 STATS(jniinvokation();)
938 s = (java_lang_String *) javastring_new_char(msg);
940 /* instantiate exception object */
942 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
948 *exceptionptr = (java_objectheader *) o;
954 /* ExceptionOccurred ***********************************************************
956 Determines if an exception is being thrown. The exception stays
957 being thrown until either the native code calls ExceptionClear(),
958 or the Java code handles the exception.
960 *******************************************************************************/
962 jthrowable ExceptionOccurred(JNIEnv *env)
964 java_objectheader *e;
966 STATS(jniinvokation();)
970 return NewLocalRef(env, (jthrowable) e);
974 /* ExceptionDescribe ***********************************************************
976 Prints an exception and a backtrace of the stack to a system
977 error-reporting channel, such as stderr. This is a convenience
978 routine provided for debugging.
980 *******************************************************************************/
982 void ExceptionDescribe(JNIEnv *env)
984 java_objectheader *e;
986 STATS(jniinvokation();)
991 /* clear exception, because we are calling jit code again */
993 *exceptionptr = NULL;
995 /* get printStackTrace method from exception class */
997 m = class_resolveclassmethod(e->vftbl->class,
1004 /* XXX what should we do? */
1007 /* print the stacktrace */
1009 asm_calljavafunction(m, e, NULL, NULL, NULL);
1014 /* ExceptionClear **************************************************************
1016 Clears any exception that is currently being thrown. If no
1017 exception is currently being thrown, this routine has no effect.
1019 *******************************************************************************/
1021 void ExceptionClear(JNIEnv *env)
1023 STATS(jniinvokation();)
1025 *exceptionptr = NULL;
1029 /* FatalError ******************************************************************
1031 Raises a fatal error and does not expect the VM to recover. This
1032 function does not return.
1034 *******************************************************************************/
1036 void FatalError(JNIEnv *env, const char *msg)
1038 STATS(jniinvokation();)
1040 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
1044 /* PushLocalFrame **************************************************************
1046 Creates a new local reference frame, in which at least a given
1047 number of local references can be created.
1049 *******************************************************************************/
1051 jint PushLocalFrame(JNIEnv* env, jint capacity)
1053 STATS(jniinvokation();)
1055 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
1062 /* PopLocalFrame ***************************************************************
1064 Pops off the current local reference frame, frees all the local
1065 references, and returns a local reference in the previous local
1066 reference frame for the given result object.
1068 *******************************************************************************/
1070 jobject PopLocalFrame(JNIEnv* env, jobject result)
1072 STATS(jniinvokation();)
1074 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
1078 /* add local reference and return the value */
1080 return NewLocalRef(env, NULL);
1084 /* DeleteLocalRef **************************************************************
1086 Deletes the local reference pointed to by localRef.
1088 *******************************************************************************/
1090 void DeleteLocalRef(JNIEnv *env, jobject localRef)
1092 java_objectheader *o;
1093 localref_table *lrt;
1096 STATS(jniinvokation();)
1098 o = (java_objectheader *) localRef;
1100 /* get local reference table (thread specific) */
1102 lrt = LOCALREFTABLE;
1104 /* remove the reference */
1106 for (i = 0; i < lrt->capacity; i++) {
1107 if (lrt->refs[i] == o) {
1108 lrt->refs[i] = NULL;
1115 /* this should not happen */
1117 /* if (opt_checkjni) */
1118 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1119 log_text("JNI-DeleteLocalRef: Bad global or local ref passed to JNI");
1123 /* IsSameObject ****************************************************************
1125 Tests whether two references refer to the same Java object.
1127 *******************************************************************************/
1129 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1131 STATS(jniinvokation();)
1140 /* NewLocalRef *****************************************************************
1142 Creates a new local reference that refers to the same object as ref.
1144 *******************************************************************************/
1146 jobject NewLocalRef(JNIEnv *env, jobject ref)
1148 localref_table *lrt;
1151 STATS(jniinvokation();)
1156 /* get local reference table (thread specific) */
1158 lrt = LOCALREFTABLE;
1160 /* check if we have space for the requested reference */
1162 if (lrt->used == lrt->capacity)
1163 throw_cacao_exception_exit(string_java_lang_InternalError,
1164 "Too many local references");
1166 /* insert the reference */
1168 for (i = 0; i < lrt->capacity; i++) {
1169 if (lrt->refs[i] == NULL) {
1170 lrt->refs[i] = (java_objectheader *) ref;
1177 /* should not happen, just to be sure */
1181 /* keep compiler happy */
1187 /* EnsureLocalCapacity *********************************************************
1189 Ensures that at least a given number of local references can be
1190 created in the current thread
1192 *******************************************************************************/
1194 jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
1196 localref_table *lrt;
1198 STATS(jniinvokation();)
1200 /* get local reference table (thread specific) */
1202 lrt = LOCALREFTABLE;
1204 /* check if capacity elements are available in the local references table */
1206 if ((lrt->used + capacity) > lrt->capacity) {
1207 *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
1215 /* AllocObject *****************************************************************
1217 Allocates a new Java object without invoking any of the
1218 constructors for the object. Returns a reference to the object.
1220 *******************************************************************************/
1222 jobject AllocObject(JNIEnv *env, jclass clazz)
1224 java_objectheader *o;
1226 STATS(jniinvokation();)
1228 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1230 new_exception_utfmessage(string_java_lang_InstantiationException,
1235 o = builtin_new(clazz);
1237 return NewLocalRef(env, o);
1241 /* NewObject *******************************************************************
1243 Programmers place all arguments that are to be passed to the
1244 constructor immediately following the methodID
1245 argument. NewObject() accepts these arguments and passes them to
1246 the Java method that the programmer wishes to invoke.
1248 *******************************************************************************/
1250 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1252 java_objectheader *o;
1255 STATS(jniinvokation();)
1259 o = builtin_new(clazz);
1264 /* call constructor */
1266 va_start(ap, methodID);
1267 cacao_jni_CallVoidMethod(o, methodID, ap);
1270 return NewLocalRef(env, o);
1274 /***********************************************************************************
1276 Constructs a new Java object
1277 arguments that are to be passed to the constructor are placed in va_list args
1279 ***********************************************************************************/
1281 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1283 STATS(jniinvokation();)
1285 log_text("JNI-Call: NewObjectV: IMPLEMENT ME!");
1287 return NewLocalRef(env, NULL);
1291 /***********************************************************************************
1293 Constructs a new Java object
1294 arguments that are to be passed to the constructor are placed in
1295 args array of jvalues
1297 ***********************************************************************************/
1299 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1301 STATS(jniinvokation();)
1303 log_text("JNI-Call: NewObjectA: IMPLEMENT ME!");
1305 return NewLocalRef(env, NULL);
1309 /* GetObjectClass **************************************************************
1311 Returns the class of an object.
1313 *******************************************************************************/
1315 jclass GetObjectClass(JNIEnv *env, jobject obj)
1319 STATS(jniinvokation();)
1321 if (!obj || !obj->vftbl)
1324 c = obj->vftbl->class;
1326 if (!use_class_as_object(c))
1329 return (jclass) NewLocalRef(env, (jobject) c);
1333 /* IsInstanceOf ****************************************************************
1335 Tests whether an object is an instance of a class.
1337 *******************************************************************************/
1339 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1341 STATS(jniinvokation();)
1343 return Java_java_lang_VMClass_isInstance(env,
1345 (java_lang_Class *) clazz,
1346 (java_lang_Object *) obj);
1350 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1352 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1354 java_lang_reflect_Field *f;
1356 jfieldID fid; /* the JNI-fieldid of the wrapping object */
1357 STATS(jniinvokation();)
1358 /*log_text("JNI-Call: FromReflectedField");*/
1360 f=(java_lang_reflect_Field *)field;
1362 c=(classinfo*)(f->declaringClass);
1363 if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1364 /*this usually means a severe internal cacao error or somebody
1365 tempered around with the reflected method*/
1366 log_text("error illegal slot for field in class(FromReflectedField)");
1369 fid=&(c->fields[f->slot]);
1374 /**********************************************************************************
1376 converts a method ID to a java.lang.reflect.Method or
1377 java.lang.reflect.Constructor object
1379 **********************************************************************************/
1381 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1383 log_text("JNI-Call: ToReflectedMethod");
1384 STATS(jniinvokation();)
1390 /* Calling Instance Methods ***************************************************/
1392 /* GetMethodID *****************************************************************
1394 Returns the method ID for an instance (nonstatic) method of a class
1395 or interface. The method may be defined in one of the clazz's
1396 superclasses and inherited by clazz. The method is determined by
1397 its name and signature.
1399 GetMethodID() causes an uninitialized class to be initialized.
1401 *******************************************************************************/
1403 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1411 STATS(jniinvokation();)
1413 c = (classinfo *) clazz;
1418 if (!c->initialized)
1419 if (!initialize_class(c))
1422 /* try to get the method of the class or one of it's superclasses */
1424 uname = utf_new_char((char *) name);
1425 udesc = utf_new_char((char *) sig);
1427 m = class_resolvemethod(clazz, uname, udesc);
1429 if (!m || (m->flags & ACC_STATIC)) {
1430 *exceptionptr = exceptions_new_nosuchmethoderror(c, uname, udesc);
1439 /******************** JNI-functions for calling instance methods ******************/
1441 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1443 java_objectheader* ret;
1446 STATS(jniinvokation();)
1448 va_start(vaargs, methodID);
1449 ret = callObjectMethod(obj, methodID, vaargs);
1452 return NewLocalRef(env, ret);
1456 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1458 java_objectheader* ret;
1460 STATS(jniinvokation();)
1462 ret = callObjectMethod(obj, methodID, args);
1464 return NewLocalRef(env, ret);
1468 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1470 STATS(jniinvokation();)
1472 log_text("JNI-Call: CallObjectMethodA: IMPLEMENT ME!");
1474 return NewLocalRef(env, NULL);
1480 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1484 STATS(jniinvokation();)
1486 /* log_text("JNI-Call: CallBooleanMethod");*/
1488 va_start(vaargs,methodID);
1489 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1495 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1497 STATS(jniinvokation();)
1499 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
1503 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1505 STATS(jniinvokation();)
1506 log_text("JNI-Call: CallBooleanMethodA");
1511 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1515 STATS(jniinvokation();)
1517 /* log_text("JNI-Call: CallVyteMethod");*/
1519 va_start(vaargs,methodID);
1520 ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
1526 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1528 /* log_text("JNI-Call: CallByteMethodV");*/
1529 STATS(jniinvokation();)
1531 return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
1535 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1537 log_text("JNI-Call: CallByteMethodA");
1538 STATS(jniinvokation();)
1544 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1548 STATS(jniinvokation();)
1550 /* log_text("JNI-Call: CallCharMethod");*/
1552 va_start(vaargs,methodID);
1553 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
1560 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1562 STATS(jniinvokation();)
1564 /* log_text("JNI-Call: CallCharMethodV");*/
1565 return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
1569 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1571 STATS(jniinvokation();)
1573 log_text("JNI-Call: CallCharMethodA");
1579 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1583 STATS(jniinvokation();)
1585 /* log_text("JNI-Call: CallShortMethod");*/
1587 va_start(vaargs, methodID);
1588 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
1595 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1597 STATS(jniinvokation();)
1598 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
1602 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1604 STATS(jniinvokation();)
1605 log_text("JNI-Call: CallShortMethodA");
1612 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1616 STATS(jniinvokation();)
1618 va_start(vaargs,methodID);
1619 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
1626 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1628 STATS(jniinvokation();)
1629 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
1633 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1635 STATS(jniinvokation();)
1636 log_text("JNI-Call: CallIntMethodA");
1643 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1647 STATS(jniinvokation();)
1649 va_start(vaargs,methodID);
1650 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1657 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1659 STATS(jniinvokation();)
1660 return callLongMethod(obj,get_virtual(obj, methodID),args);
1664 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1666 STATS(jniinvokation();)
1667 log_text("JNI-Call: CallLongMethodA");
1674 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1679 STATS(jniinvokation();)
1680 /* log_text("JNI-Call: CallFloatMethod");*/
1682 va_start(vaargs,methodID);
1683 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
1690 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1692 STATS(jniinvokation();)
1693 log_text("JNI-Call: CallFloatMethodV");
1694 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
1698 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1700 STATS(jniinvokation();)
1701 log_text("JNI-Call: CallFloatMethodA");
1708 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1712 STATS(jniinvokation();)
1714 /* log_text("JNI-Call: CallDoubleMethod");*/
1716 va_start(vaargs,methodID);
1717 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
1724 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1726 STATS(jniinvokation();)
1727 log_text("JNI-Call: CallDoubleMethodV");
1728 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
1732 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1734 STATS(jniinvokation();)
1735 log_text("JNI-Call: CallDoubleMethodA");
1741 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1744 STATS(jniinvokation();)
1746 va_start(vaargs,methodID);
1747 (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
1752 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1754 log_text("JNI-Call: CallVoidMethodV");
1755 STATS(jniinvokation();)
1756 (void)callIntegerMethod(obj,get_virtual(obj,methodID),TYPE_VOID,args);
1760 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1762 STATS(jniinvokation();)
1763 log_text("JNI-Call: CallVoidMethodA");
1768 jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1770 STATS(jniinvokation();)
1772 log_text("JNI-Call: CallNonvirtualObjectMethod: IMPLEMENT ME!");
1774 return NewLocalRef(env, NULL);
1778 jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1780 STATS(jniinvokation();)
1782 log_text("JNI-Call: CallNonvirtualObjectMethodV: IMPLEMENT ME!");
1784 return NewLocalRef(env, NULL);
1788 jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1790 STATS(jniinvokation();)
1792 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1794 return NewLocalRef(env, NULL);
1799 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1803 STATS(jniinvokation();)
1805 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1807 va_start(vaargs,methodID);
1808 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1815 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1817 STATS(jniinvokation();)
1818 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1819 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
1823 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1825 STATS(jniinvokation();)
1826 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1833 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1838 STATS(jniinvokation();)
1839 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1841 va_start(vaargs,methodID);
1842 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
1848 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1850 STATS(jniinvokation();)
1851 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1852 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
1857 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1859 STATS(jniinvokation();)
1860 log_text("JNI-Call: CallNonvirtualByteMethodA");
1867 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1872 STATS(jniinvokation();)
1873 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1875 va_start(vaargs,methodID);
1876 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
1882 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1884 STATS(jniinvokation();)
1885 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1886 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
1890 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1892 STATS(jniinvokation();)
1893 log_text("JNI-Call: CallNonvirtualCharMethodA");
1900 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1904 STATS(jniinvokation();)
1906 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1908 va_start(vaargs,methodID);
1909 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
1915 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1917 STATS(jniinvokation();)
1918 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1919 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
1923 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1925 STATS(jniinvokation();)
1926 log_text("JNI-Call: CallNonvirtualShortMethodA");
1933 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1938 STATS(jniinvokation();)
1940 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1942 va_start(vaargs,methodID);
1943 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
1949 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1951 STATS(jniinvokation();)
1952 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1953 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
1957 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1959 STATS(jniinvokation();)
1960 log_text("JNI-Call: CallNonvirtualIntMethodA");
1967 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1969 STATS(jniinvokation();)
1970 log_text("JNI-Call: CallNonvirtualLongMethod");
1976 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1978 STATS(jniinvokation();)
1979 log_text("JNI-Call: CallNonvirtualLongMethodV");
1985 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1987 STATS(jniinvokation();)
1988 log_text("JNI-Call: CallNonvirtualLongMethodA");
1995 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1999 STATS(jniinvokation();)
2001 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
2004 va_start(vaargs,methodID);
2005 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
2012 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2014 STATS(jniinvokation();)
2015 log_text("JNI-Call: CallNonvirtualFloatMethodV");
2016 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
2020 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2022 STATS(jniinvokation();)
2023 log_text("JNI-Call: CallNonvirtualFloatMethodA");
2030 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2034 STATS(jniinvokation();)
2035 log_text("JNI-Call: CallNonvirtualDoubleMethod");
2037 va_start(vaargs,methodID);
2038 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
2045 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2047 STATS(jniinvokation();)
2048 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
2049 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
2053 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2055 STATS(jniinvokation();)
2056 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
2063 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2066 STATS(jniinvokation();)
2068 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
2070 va_start(vaargs,methodID);
2071 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
2077 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2079 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
2080 STATS(jniinvokation();)
2082 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
2087 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
2089 STATS(jniinvokation();)
2090 log_text("JNI-Call: CallNonvirtualVoidMethodA");
2093 /************************* JNI-functions for accessing fields ************************/
2095 jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2099 STATS(jniinvokation();)
2101 f = class_findfield(clazz, utf_new_char((char *) name), utf_new_char((char *) sig));
2104 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2110 jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2112 java_objectheader *o;
2114 STATS(jniinvokation();)
2116 o = getField(obj, java_objectheader*, fieldID);
2118 return NewLocalRef(env, o);
2122 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
2124 STATS(jniinvokation();)
2125 return getField(obj,jboolean,fieldID);
2129 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
2131 STATS(jniinvokation();)
2132 return getField(obj,jbyte,fieldID);
2136 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
2138 STATS(jniinvokation();)
2139 return getField(obj,jchar,fieldID);
2143 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
2145 STATS(jniinvokation();)
2146 return getField(obj,jshort,fieldID);
2150 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
2152 STATS(jniinvokation();)
2153 return getField(obj,jint,fieldID);
2157 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
2159 STATS(jniinvokation();)
2160 return getField(obj,jlong,fieldID);
2164 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
2166 STATS(jniinvokation();)
2167 return getField(obj,jfloat,fieldID);
2171 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
2173 STATS(jniinvokation();)
2174 return getField(obj,jdouble,fieldID);
2177 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
2179 STATS(jniinvokation();)
2180 setField(obj,jobject,fieldID,val);
2184 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
2186 STATS(jniinvokation();)
2187 setField(obj,jboolean,fieldID,val);
2191 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
2193 STATS(jniinvokation();)
2194 setField(obj,jbyte,fieldID,val);
2198 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
2200 STATS(jniinvokation();)
2201 setField(obj,jchar,fieldID,val);
2205 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
2207 STATS(jniinvokation();)
2208 setField(obj,jshort,fieldID,val);
2212 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
2214 STATS(jniinvokation();)
2215 setField(obj,jint,fieldID,val);
2219 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
2221 STATS(jniinvokation();)
2222 setField(obj,jlong,fieldID,val);
2226 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
2228 STATS(jniinvokation();)
2229 setField(obj,jfloat,fieldID,val);
2233 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
2235 STATS(jniinvokation();)
2236 setField(obj,jdouble,fieldID,val);
2240 /* Calling Static Methods *****************************************************/
2242 /* GetStaticMethodID ***********************************************************
2244 Returns the method ID for a static method of a class. The method is
2245 specified by its name and signature.
2247 GetStaticMethodID() causes an uninitialized class to be
2250 *******************************************************************************/
2252 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2260 STATS(jniinvokation();)
2262 c = (classinfo *) clazz;
2267 if (!c->initialized)
2268 if (!initialize_class(c))
2271 /* try to get the static method of the class */
2273 uname = utf_new_char((char *) name);
2274 udesc = utf_new_char((char *) sig);
2276 m = class_resolvemethod(c, uname, udesc);
2278 if (!m || !(m->flags & ACC_STATIC)) {
2279 *exceptionptr = exceptions_new_nosuchmethoderror(c, uname, udesc);
2288 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2290 java_objectheader *ret;
2293 STATS(jniinvokation();)
2295 va_start(vaargs, methodID);
2296 ret = callObjectMethod(0, methodID, vaargs);
2299 return NewLocalRef(env, ret);
2303 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2305 java_objectheader *ret;
2307 STATS(jniinvokation();)
2309 ret = callObjectMethod(0, methodID, args);
2311 return NewLocalRef(env, ret);
2315 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2317 STATS(jniinvokation();)
2319 log_text("JNI-Call: CallStaticObjectMethodA: IMPLEMENT ME!");
2321 return NewLocalRef(env, NULL);
2325 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2330 STATS(jniinvokation();)
2332 va_start(vaargs, methodID);
2333 ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
2340 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2342 STATS(jniinvokation();)
2344 return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
2348 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2350 STATS(jniinvokation();)
2352 log_text("JNI-Call: CallStaticBooleanMethodA: IMPLEMENT ME!");
2358 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2363 STATS(jniinvokation();)
2365 va_start(vaargs, methodID);
2366 ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
2373 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2375 STATS(jniinvokation();)
2376 return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
2380 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2382 STATS(jniinvokation();)
2384 log_text("JNI-Call: CallStaticByteMethodA: IMPLEMENT ME!");
2390 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2395 STATS(jniinvokation();)
2397 va_start(vaargs, methodID);
2398 ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
2405 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2407 STATS(jniinvokation();)
2409 return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
2413 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2415 STATS(jniinvokation();)
2417 log_text("JNI-Call: CallStaticCharMethodA: IMPLEMENT ME!");
2423 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2428 STATS(jniinvokation();)
2430 va_start(vaargs, methodID);
2431 ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
2438 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2440 STATS(jniinvokation();)
2442 return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
2446 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2448 STATS(jniinvokation();)
2450 log_text("JNI-Call: CallStaticShortMethodA: IMPLEMENT ME!");
2456 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2461 STATS(jniinvokation();)
2463 va_start(vaargs, methodID);
2464 ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
2471 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2473 STATS(jniinvokation();)
2475 return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
2479 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2481 STATS(jniinvokation();)
2483 log_text("JNI-Call: CallStaticIntMethodA: IMPLEMENT ME!");
2489 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2494 STATS(jniinvokation();)
2496 va_start(vaargs, methodID);
2497 ret = callLongMethod(0, methodID, vaargs);
2504 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
2507 STATS(jniinvokation();)
2509 return callLongMethod(0, methodID, args);
2513 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2515 STATS(jniinvokation();)
2517 log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!");
2524 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2529 STATS(jniinvokation();)
2531 va_start(vaargs, methodID);
2532 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
2539 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2541 STATS(jniinvokation();)
2543 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
2548 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2550 STATS(jniinvokation();)
2552 log_text("JNI-Call: CallStaticFloatMethodA: IMPLEMENT ME!");
2558 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2563 STATS(jniinvokation();)
2565 va_start(vaargs,methodID);
2566 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
2573 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2575 STATS(jniinvokation();)
2577 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
2581 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2583 STATS(jniinvokation();)
2585 log_text("JNI-Call: CallStaticDoubleMethodA: IMPLEMENT ME!");
2591 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2595 STATS(jniinvokation();)
2597 va_start(vaargs, methodID);
2598 (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
2603 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2605 STATS(jniinvokation();)
2607 (void) callIntegerMethod(0, methodID, TYPE_VOID, args);
2611 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2613 STATS(jniinvokation();)
2615 log_text("JNI-Call: CallStaticVoidMethodA: IMPLEMENT ME!");
2619 /* Accessing Static Fields ****************************************************/
2621 /* GetStaticFieldID ************************************************************
2623 Returns the field ID for a static field of a class. The field is
2624 specified by its name and signature. The GetStatic<type>Field and
2625 SetStatic<type>Field families of accessor functions use field IDs
2626 to retrieve static fields.
2628 *******************************************************************************/
2630 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2633 STATS(jniinvokation();)
2635 f = class_findfield(clazz,
2636 utf_new_char((char *) name),
2637 utf_new_char((char *) sig));
2640 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2646 /* GetStatic<type>Field ********************************************************
2648 This family of accessor routines returns the value of a static
2651 *******************************************************************************/
2653 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2655 STATS(jniinvokation();)
2657 if (!clazz->initialized)
2658 if (!initialize_class(clazz))
2661 return NewLocalRef(env, fieldID->value.a);
2665 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2667 STATS(jniinvokation();)
2669 if (!clazz->initialized)
2670 if (!initialize_class(clazz))
2673 return fieldID->value.i;
2677 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2679 STATS(jniinvokation();)
2681 if (!clazz->initialized)
2682 if (!initialize_class(clazz))
2685 return fieldID->value.i;
2689 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2691 STATS(jniinvokation();)
2693 if (!clazz->initialized)
2694 if (!initialize_class(clazz))
2697 return fieldID->value.i;
2701 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2703 STATS(jniinvokation();)
2705 if (!clazz->initialized)
2706 if (!initialize_class(clazz))
2709 return fieldID->value.i;
2713 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2715 STATS(jniinvokation();)
2717 if (!clazz->initialized)
2718 if (!initialize_class(clazz))
2721 return fieldID->value.i;
2725 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2727 STATS(jniinvokation();)
2729 if (!clazz->initialized)
2730 if (!initialize_class(clazz))
2733 return fieldID->value.l;
2737 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2739 STATS(jniinvokation();)
2741 if (!clazz->initialized)
2742 if (!initialize_class(clazz))
2745 return fieldID->value.f;
2749 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2751 STATS(jniinvokation();)
2753 if (!clazz->initialized)
2754 if (!initialize_class(clazz))
2757 return fieldID->value.d;
2761 /* SetStatic<type>Field *******************************************************
2763 This family of accessor routines sets the value of a static field
2766 *******************************************************************************/
2768 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2770 STATS(jniinvokation();)
2772 if (!clazz->initialized)
2773 if (!initialize_class(clazz))
2776 fieldID->value.a = value;
2780 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2782 STATS(jniinvokation();)
2784 if (!clazz->initialized)
2785 if (!initialize_class(clazz))
2788 fieldID->value.i = value;
2792 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2794 STATS(jniinvokation();)
2796 if (!clazz->initialized)
2797 if (!initialize_class(clazz))
2800 fieldID->value.i = value;
2804 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2806 STATS(jniinvokation();)
2808 if (!clazz->initialized)
2809 if (!initialize_class(clazz))
2812 fieldID->value.i = value;
2816 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2818 STATS(jniinvokation();)
2820 if (!clazz->initialized)
2821 if (!initialize_class(clazz))
2824 fieldID->value.i = value;
2828 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2830 STATS(jniinvokation();)
2832 if (!clazz->initialized)
2833 if (!initialize_class(clazz))
2836 fieldID->value.i = value;
2840 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2842 STATS(jniinvokation();)
2844 if (!clazz->initialized)
2845 if (!initialize_class(clazz))
2848 fieldID->value.l = value;
2852 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2854 STATS(jniinvokation();)
2856 if (!clazz->initialized)
2857 if (!initialize_class(clazz))
2860 fieldID->value.f = value;
2864 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2866 STATS(jniinvokation();)
2868 if (!clazz->initialized)
2869 if (!initialize_class(clazz))
2872 fieldID->value.d = value;
2876 /* String Operations **********************************************************/
2878 /* NewString *******************************************************************
2880 Create new java.lang.String object from an array of Unicode
2883 *******************************************************************************/
2885 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
2887 java_lang_String *s;
2891 STATS(jniinvokation();)
2893 s = (java_lang_String *) builtin_new(class_java_lang_String);
2894 a = builtin_newarray_char(len);
2896 /* javastring or characterarray could not be created */
2901 for (i = 0; i < len; i++)
2902 a->data[i] = buf[i];
2908 return (jstring) NewLocalRef(env, (jobject) s);
2912 static jchar emptyStringJ[]={0,0};
2914 /* GetStringLength *************************************************************
2916 Returns the length (the count of Unicode characters) of a Java
2919 *******************************************************************************/
2921 jsize GetStringLength(JNIEnv *env, jstring str)
2923 return ((java_lang_String *) str)->count;
2927 /******************** convertes javastring to u2-array ****************************/
2929 u2 *javastring_tou2(jstring so)
2931 java_lang_String *s;
2936 STATS(jniinvokation();)
2938 s = (java_lang_String *) so;
2948 /* allocate memory */
2950 stringbuffer = MNEW(u2, s->count + 1);
2954 for (i = 0; i < s->count; i++)
2955 stringbuffer[i] = a->data[s->offset + i];
2957 /* terminate string */
2959 stringbuffer[i] = '\0';
2961 return stringbuffer;
2965 /* GetStringChars **************************************************************
2967 Returns a pointer to the array of Unicode characters of the
2968 string. This pointer is valid until ReleaseStringchars() is called.
2970 *******************************************************************************/
2972 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2976 STATS(jniinvokation();)
2978 jc = javastring_tou2(str);
2990 return emptyStringJ;
2994 /* ReleaseStringChars **********************************************************
2996 Informs the VM that the native code no longer needs access to
2997 chars. The chars argument is a pointer obtained from string using
3000 *******************************************************************************/
3002 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
3004 STATS(jniinvokation();)
3006 if (chars == emptyStringJ)
3009 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
3013 /* NewStringUTF ****************************************************************
3015 Constructs a new java.lang.String object from an array of UTF-8 characters.
3017 *******************************************************************************/
3019 jstring NewStringUTF(JNIEnv *env, const char *bytes)
3021 java_lang_String *s;
3023 STATS(jniinvokation();)
3025 s = javastring_new(utf_new_char(bytes));
3027 return (jstring) NewLocalRef(env, (jobject) s);
3031 /****************** returns the utf8 length in bytes of a string *******************/
3033 jsize GetStringUTFLength (JNIEnv *env, jstring string)
3035 java_lang_String *s = (java_lang_String*) string;
3036 STATS(jniinvokation();)
3038 return (jsize) u2_utflength(s->value->data, s->count);
3042 /* GetStringUTFChars ***********************************************************
3044 Returns a pointer to an array of UTF-8 characters of the
3045 string. This array is valid until it is released by
3046 ReleaseStringUTFChars().
3048 *******************************************************************************/
3050 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
3053 STATS(jniinvokation();)
3061 u = javastring_toutf((java_lang_String *) string, false);
3070 /* ReleaseStringUTFChars *******************************************************
3072 Informs the VM that the native code no longer needs access to
3073 utf. The utf argument is a pointer derived from string using
3074 GetStringUTFChars().
3076 *******************************************************************************/
3078 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
3080 STATS(jniinvokation();)
3082 /* XXX we don't release utf chars right now, perhaps that should be done
3083 later. Since there is always one reference the garbage collector will
3088 /* Array Operations ***********************************************************/
3090 /* GetArrayLength **************************************************************
3092 Returns the number of elements in the array.
3094 *******************************************************************************/
3096 jsize GetArrayLength(JNIEnv *env, jarray array)
3098 STATS(jniinvokation();)
3104 /* NewObjectArray **************************************************************
3106 Constructs a new array holding objects in class elementClass. All
3107 elements are initially set to initialElement.
3109 *******************************************************************************/
3111 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
3113 java_objectarray *oa;
3116 STATS(jniinvokation();)
3119 *exceptionptr = new_negativearraysizeexception();
3123 oa = builtin_anewarray(length, elementClass);
3128 /* set all elements to initialElement */
3130 for (i = 0; i < length; i++)
3131 oa->data[i] = initialElement;
3133 return (jobjectArray) NewLocalRef(env, (jobject) oa);
3137 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
3141 STATS(jniinvokation();)
3143 if (index >= array->header.size) {
3145 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3149 o = array->data[index];
3151 return NewLocalRef(env, o);
3155 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3157 STATS(jniinvokation();)
3158 if (index >= array->header.size)
3159 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3162 /* check if the class of value is a subclass of the element class of the array */
3163 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
3164 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3167 array->data[index] = val;
3172 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3174 java_booleanarray *ba;
3176 STATS(jniinvokation();)
3179 *exceptionptr = new_negativearraysizeexception();
3183 ba = builtin_newarray_boolean(len);
3185 return (jbooleanArray) NewLocalRef(env, (jobject) ba);
3189 jbyteArray NewByteArray(JNIEnv *env, jsize len)
3193 STATS(jniinvokation();)
3196 *exceptionptr = new_negativearraysizeexception();
3200 ba = builtin_newarray_byte(len);
3202 return (jbyteArray) NewLocalRef(env, (jobject) ba);
3206 jcharArray NewCharArray(JNIEnv *env, jsize len)
3210 STATS(jniinvokation();)
3213 *exceptionptr = new_negativearraysizeexception();
3217 ca = builtin_newarray_char(len);
3219 return (jcharArray) NewLocalRef(env, (jobject) ca);
3223 jshortArray NewShortArray(JNIEnv *env, jsize len)
3225 java_shortarray *sa;
3227 STATS(jniinvokation();)
3230 *exceptionptr = new_negativearraysizeexception();
3234 sa = builtin_newarray_short(len);
3236 return (jshortArray) NewLocalRef(env, (jobject) sa);
3240 jintArray NewIntArray(JNIEnv *env, jsize len)
3244 STATS(jniinvokation();)
3247 *exceptionptr = new_negativearraysizeexception();
3251 ia = builtin_newarray_int(len);
3253 return (jintArray) NewLocalRef(env, (jobject) ia);
3257 jlongArray NewLongArray(JNIEnv *env, jsize len)
3261 STATS(jniinvokation();)
3264 *exceptionptr = new_negativearraysizeexception();
3268 la = builtin_newarray_long(len);
3270 return (jlongArray) NewLocalRef(env, (jobject) la);
3274 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3276 java_floatarray *fa;
3278 STATS(jniinvokation();)
3281 *exceptionptr = new_negativearraysizeexception();
3285 fa = builtin_newarray_float(len);
3287 return (jfloatArray) NewLocalRef(env, (jobject) fa);
3291 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3293 java_doublearray *da;
3295 STATS(jniinvokation();)
3298 *exceptionptr = new_negativearraysizeexception();
3302 da = builtin_newarray_double(len);
3304 return (jdoubleArray) NewLocalRef(env, (jobject) da);
3308 /* Get<PrimitiveType>ArrayElements *********************************************
3310 A family of functions that returns the body of the primitive array.
3312 *******************************************************************************/
3314 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3317 STATS(jniinvokation();)
3320 *isCopy = JNI_FALSE;
3326 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3328 STATS(jniinvokation();)
3331 *isCopy = JNI_FALSE;
3337 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3339 STATS(jniinvokation();)
3342 *isCopy = JNI_FALSE;
3348 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3350 STATS(jniinvokation();)
3353 *isCopy = JNI_FALSE;
3359 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3361 STATS(jniinvokation();)
3364 *isCopy = JNI_FALSE;
3370 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3372 STATS(jniinvokation();)
3375 *isCopy = JNI_FALSE;
3381 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3383 STATS(jniinvokation();)
3386 *isCopy = JNI_FALSE;
3392 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3395 STATS(jniinvokation();)
3398 *isCopy = JNI_FALSE;
3404 /* Release<PrimitiveType>ArrayElements *****************************************
3406 A family of functions that informs the VM that the native code no
3407 longer needs access to elems. The elems argument is a pointer
3408 derived from array using the corresponding
3409 Get<PrimitiveType>ArrayElements() function. If necessary, this
3410 function copies back all changes made to elems to the original
3413 *******************************************************************************/
3415 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3416 jboolean *elems, jint mode)
3418 STATS(jniinvokation();)
3420 if (elems != array->data) {
3423 MCOPY(array->data, elems, jboolean, array->header.size);
3426 MCOPY(array->data, elems, jboolean, array->header.size);
3427 /* XXX TWISTI how should it be freed? */
3430 /* XXX TWISTI how should it be freed? */
3437 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
3440 STATS(jniinvokation();)
3442 if (elems != array->data) {
3445 MCOPY(array->data, elems, jboolean, array->header.size);
3448 MCOPY(array->data, elems, jboolean, array->header.size);
3449 /* XXX TWISTI how should it be freed? */
3452 /* XXX TWISTI how should it be freed? */
3459 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
3462 STATS(jniinvokation();)
3464 if (elems != array->data) {
3467 MCOPY(array->data, elems, jboolean, array->header.size);
3470 MCOPY(array->data, elems, jboolean, array->header.size);
3471 /* XXX TWISTI how should it be freed? */
3474 /* XXX TWISTI how should it be freed? */
3481 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
3484 STATS(jniinvokation();)
3486 if (elems != array->data) {
3489 MCOPY(array->data, elems, jboolean, array->header.size);
3492 MCOPY(array->data, elems, jboolean, array->header.size);
3493 /* XXX TWISTI how should it be freed? */
3496 /* XXX TWISTI how should it be freed? */
3503 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
3506 STATS(jniinvokation();)
3508 if (elems != array->data) {
3511 MCOPY(array->data, elems, jboolean, array->header.size);
3514 MCOPY(array->data, elems, jboolean, array->header.size);
3515 /* XXX TWISTI how should it be freed? */
3518 /* XXX TWISTI how should it be freed? */
3525 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
3528 STATS(jniinvokation();)
3530 if (elems != array->data) {
3533 MCOPY(array->data, elems, jboolean, array->header.size);
3536 MCOPY(array->data, elems, jboolean, array->header.size);
3537 /* XXX TWISTI how should it be freed? */
3540 /* XXX TWISTI how should it be freed? */
3547 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
3550 STATS(jniinvokation();)
3552 if (elems != array->data) {
3555 MCOPY(array->data, elems, jboolean, array->header.size);
3558 MCOPY(array->data, elems, jboolean, array->header.size);
3559 /* XXX TWISTI how should it be freed? */
3562 /* XXX TWISTI how should it be freed? */
3569 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3570 jdouble *elems, jint mode)
3572 STATS(jniinvokation();)
3574 if (elems != array->data) {
3577 MCOPY(array->data, elems, jboolean, array->header.size);
3580 MCOPY(array->data, elems, jboolean, array->header.size);
3581 /* XXX TWISTI how should it be freed? */
3584 /* XXX TWISTI how should it be freed? */
3591 /* Get<PrimitiveType>ArrayRegion **********************************************
3593 A family of functions that copies a region of a primitive array
3596 *******************************************************************************/
3598 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3599 jsize len, jboolean *buf)
3601 STATS(jniinvokation();)
3603 if (start < 0 || len < 0 || start + len > array->header.size)
3605 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3608 MCOPY(buf, &array->data[start], jboolean, len);
3612 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3615 STATS(jniinvokation();)
3617 if (start < 0 || len < 0 || start + len > array->header.size)
3619 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3622 MCOPY(buf, &array->data[start], jbyte, len);
3626 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3629 STATS(jniinvokation();)
3631 if (start < 0 || len < 0 || start + len > array->header.size)
3633 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3636 MCOPY(buf, &array->data[start], jchar, len);
3640 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3641 jsize len, jshort *buf)
3643 STATS(jniinvokation();)
3645 if (start < 0 || len < 0 || start + len > array->header.size)
3647 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3650 MCOPY(buf, &array->data[start], jshort, len);
3654 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3657 STATS(jniinvokation();)
3659 if (start < 0 || len < 0 || start + len > array->header.size)
3661 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3664 MCOPY(buf, &array->data[start], jint, len);
3668 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
3671 STATS(jniinvokation();)
3673 if (start < 0 || len < 0 || start + len > array->header.size)
3675 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3678 MCOPY(buf, &array->data[start], jlong, len);
3682 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3683 jsize len, jfloat *buf)
3685 STATS(jniinvokation();)
3687 if (start < 0 || len < 0 || start + len > array->header.size)
3689 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3692 MCOPY(buf, &array->data[start], jfloat, len);
3696 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3697 jsize len, jdouble *buf)
3699 STATS(jniinvokation();)
3701 if (start < 0 || len < 0 || start+len>array->header.size)
3703 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3706 MCOPY(buf, &array->data[start], jdouble, len);
3710 /* Set<PrimitiveType>ArrayRegion **********************************************
3712 A family of functions that copies back a region of a primitive
3713 array from a buffer.
3715 *******************************************************************************/
3717 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3718 jsize len, jboolean *buf)
3720 STATS(jniinvokation();)
3722 if (start < 0 || len < 0 || start + len > array->header.size)
3724 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3727 MCOPY(&array->data[start], buf, jboolean, len);
3731 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3734 STATS(jniinvokation();)
3736 if (start < 0 || len < 0 || start + len > array->header.size)
3738 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3741 MCOPY(&array->data[start], buf, jbyte, len);
3745 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3748 STATS(jniinvokation();)
3750 if (start < 0 || len < 0 || start + len > array->header.size)
3752 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3755 MCOPY(&array->data[start], buf, jchar, len);
3760 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3761 jsize len, jshort *buf)
3763 STATS(jniinvokation();)
3765 if (start < 0 || len < 0 || start + len > array->header.size)
3767 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3770 MCOPY(&array->data[start], buf, jshort, len);
3774 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3777 STATS(jniinvokation();)
3779 if (start < 0 || len < 0 || start + len > array->header.size)
3781 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3784 MCOPY(&array->data[start], buf, jint, len);
3789 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
3792 STATS(jniinvokation();)
3794 if (start < 0 || len < 0 || start + len > array->header.size)
3796 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3799 MCOPY(&array->data[start], buf, jlong, len);
3804 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3805 jsize len, jfloat *buf)
3807 STATS(jniinvokation();)
3809 if (start < 0 || len < 0 || start + len > array->header.size)
3811 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3814 MCOPY(&array->data[start], buf, jfloat, len);
3819 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3820 jsize len, jdouble *buf)
3822 STATS(jniinvokation();)
3824 if (start < 0 || len < 0 || start + len > array->header.size)
3826 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3829 MCOPY(&array->data[start], buf, jdouble, len);
3833 /* Registering Native Methods *************************************************/
3835 /* RegisterNatives *************************************************************
3837 Registers native methods with the class specified by the clazz
3838 argument. The methods parameter specifies an array of
3839 JNINativeMethod structures that contain the names, signatures, and
3840 function pointers of the native methods. The nMethods parameter
3841 specifies the number of native methods in the array.
3843 *******************************************************************************/
3845 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
3848 STATS(jniinvokation();)
3850 log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
3856 /* UnregisterNatives ***********************************************************
3858 Unregisters native methods of a class. The class goes back to the
3859 state before it was linked or registered with its native method
3862 This function should not be used in normal native code. Instead, it
3863 provides special programs a way to reload and relink native
3866 *******************************************************************************/
3868 jint UnregisterNatives(JNIEnv *env, jclass clazz)
3870 STATS(jniinvokation();)
3872 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3874 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3880 /* Monitor Operations *********************************************************/
3882 /* MonitorEnter ****************************************************************
3884 Enters the monitor associated with the underlying Java object
3887 *******************************************************************************/
3889 jint MonitorEnter(JNIEnv *env, jobject obj)
3891 STATS(jniinvokation();)
3894 *exceptionptr = new_nullpointerexception();
3898 #if defined(USE_THREADS)
3899 builtin_monitorenter(obj);
3906 /* MonitorExit *****************************************************************
3908 The current thread must be the owner of the monitor associated with
3909 the underlying Java object referred to by obj. The thread
3910 decrements the counter indicating the number of times it has
3911 entered this monitor. If the value of the counter becomes zero, the
3912 current thread releases the monitor.
3914 *******************************************************************************/
3916 jint MonitorExit(JNIEnv *env, jobject obj)
3918 STATS(jniinvokation();)
3920 *exceptionptr = new_nullpointerexception();
3924 #if defined(USE_THREADS)
3925 builtin_monitorexit(obj);
3932 /* JavaVM Interface ***********************************************************/
3934 /* GetJavaVM *******************************************************************
3936 Returns the Java VM interface (used in the Invocation API)
3937 associated with the current thread. The result is placed at the
3938 location pointed to by the second argument, vm.
3940 *******************************************************************************/
3942 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
3944 STATS(jniinvokation();)
3951 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3953 STATS(jniinvokation();)
3954 log_text("JNI-Call: GetStringRegion");
3958 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3960 STATS(jniinvokation();)
3961 log_text("JNI-Call: GetStringUTFRegion");
3965 /* GetPrimitiveArrayCritical ***************************************************
3967 Obtain a direct pointer to array elements.
3969 *******************************************************************************/
3971 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3973 /* do the same as Kaffe does */
3975 return GetByteArrayElements(env, (jbyteArray) array, isCopy);
3979 /* ReleasePrimitiveArrayCritical ***********************************************
3981 No specific documentation.
3983 *******************************************************************************/
3985 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
3988 STATS(jniinvokation();)
3990 /* do the same as Kaffe does */
3992 ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
3996 /* GetStringCritical ***********************************************************
3998 The semantics of these two functions are similar to the existing
3999 Get/ReleaseStringChars functions.
4001 *******************************************************************************/
4003 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
4005 STATS(jniinvokation();)
4007 return GetStringChars(env, string, isCopy);
4011 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
4013 STATS(jniinvokation();)
4015 ReleaseStringChars(env, string, cstring);
4019 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
4021 STATS(jniinvokation();)
4022 log_text("JNI-Call: NewWeakGlobalRef");
4028 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
4030 STATS(jniinvokation();)
4031 log_text("JNI-Call: DeleteWeakGlobalRef");
4037 /* NewGlobalRef ****************************************************************
4039 Creates a new global reference to the object referred to by the obj
4042 *******************************************************************************/
4044 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4046 java_lang_Integer *refcount;
4047 java_objectheader *newval;
4049 STATS(jniinvokation();)
4051 #if defined(USE_THREADS)
4052 builtin_monitorenter(*global_ref_table);
4055 refcount = (java_lang_Integer *)
4056 asm_calljavafunction(getmid, *global_ref_table, lobj, NULL, NULL);
4058 if (refcount == NULL) {
4059 newval = native_new_and_init_int(class_java_lang_Integer, 1);
4061 if (newval == NULL) {
4062 #if defined(USE_THREADS)
4063 builtin_monitorexit(*global_ref_table);
4068 asm_calljavafunction(putmid, *global_ref_table, lobj, newval, NULL);
4071 /* we can access the object itself, as we are in a
4072 synchronized section */
4077 #if defined(USE_THREADS)
4078 builtin_monitorexit(*global_ref_table);
4085 /* DeleteGlobalRef *************************************************************
4087 Deletes the global reference pointed to by globalRef.
4089 *******************************************************************************/
4091 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
4093 java_lang_Integer *refcount;
4096 STATS(jniinvokation();)
4098 #if defined(USE_THREADS)
4099 builtin_monitorenter(*global_ref_table);
4102 refcount = (java_lang_Integer *)
4103 asm_calljavafunction(getmid, *global_ref_table, globalRef, NULL, NULL);
4105 if (refcount == NULL) {
4106 log_text("JNI-DeleteGlobalRef: unable to find global reference");
4110 /* we can access the object itself, as we are in a synchronized
4113 val = refcount->value - 1;
4116 asm_calljavafunction(removemid, *global_ref_table, refcount, NULL,
4120 /* we do not create a new object, but set the new value into
4123 refcount->value = val;
4126 #if defined(USE_THREADS)
4127 builtin_monitorexit(*global_ref_table);
4132 /* ExceptionCheck **************************************************************
4134 Returns JNI_TRUE when there is a pending exception; otherwise,
4137 *******************************************************************************/
4139 jboolean ExceptionCheck(JNIEnv *env)
4141 STATS(jniinvokation();)
4142 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
4146 /* New JNI 1.4 functions ******************************************************/
4148 /* NewDirectByteBuffer *********************************************************
4150 Allocates and returns a direct java.nio.ByteBuffer referring to the
4151 block of memory starting at the memory address address and
4152 extending capacity bytes.
4154 *******************************************************************************/
4156 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
4158 java_nio_DirectByteBufferImpl *nbuf;
4159 #if SIZEOF_VOID_P == 8
4160 gnu_classpath_Pointer64 *paddress;
4162 gnu_classpath_Pointer32 *paddress;
4165 STATS(jniinvokation();)
4167 log_text("JNI-NewDirectByteBuffer: called");
4169 /* allocate a java.nio.DirectByteBufferImpl object */
4171 if (!(nbuf = (java_nio_DirectByteBufferImpl *) builtin_new(class_java_nio_DirectByteBufferImpl)))
4174 /* alocate a gnu.classpath.Pointer{32,64} object */
4176 #if SIZEOF_VOID_P == 8
4177 if (!(paddress = (gnu_classpath_Pointer64 *) builtin_new(class_gnu_classpath_Pointer64)))
4179 if (!(paddress = (gnu_classpath_Pointer32 *) builtin_new(class_gnu_classpath_Pointer32)))
4183 /* fill gnu.classpath.Pointer{32,64} with address */
4185 paddress->data = (ptrint) address;
4187 /* fill java.nio.Buffer object */
4189 nbuf->cap = (s4) capacity;
4190 nbuf->limit = (s4) capacity;
4192 nbuf->address = (gnu_classpath_Pointer *) paddress;
4194 /* add local reference and return the value */
4196 return NewLocalRef(env, (jobject) nbuf);
4200 /* GetDirectBufferAddress ******************************************************
4202 Fetches and returns the starting address of the memory region
4203 referenced by the given direct java.nio.Buffer.
4205 *******************************************************************************/
4207 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
4209 java_nio_DirectByteBufferImpl *nbuf;
4210 #if SIZEOF_VOID_P == 8
4211 gnu_classpath_Pointer64 *address;
4213 gnu_classpath_Pointer32 *address;
4216 STATS(jniinvokation();)
4219 if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
4223 nbuf = (java_nio_DirectByteBufferImpl *) buf;
4225 #if SIZEOF_VOID_P == 8
4226 address = (gnu_classpath_Pointer64 *) nbuf->address;
4228 address = (gnu_classpath_Pointer32 *) nbuf->address;
4231 return (void *) address->data;
4235 /* GetDirectBufferCapacity *****************************************************
4237 Fetches and returns the capacity in bytes of the memory region
4238 referenced by the given direct java.nio.Buffer.
4240 *******************************************************************************/
4242 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
4244 java_nio_Buffer *nbuf;
4246 STATS(jniinvokation();)
4251 nbuf = (java_nio_Buffer *) buf;
4253 return (jlong) nbuf->cap;
4257 jint DestroyJavaVM(JavaVM *vm)
4259 STATS(jniinvokation();)
4260 log_text("DestroyJavaVM called");
4266 /* AttachCurrentThread *********************************************************
4268 Attaches the current thread to a Java VM. Returns a JNI interface
4269 pointer in the JNIEnv argument.
4271 Trying to attach a thread that is already attached is a no-op.
4273 A native thread cannot be attached simultaneously to two Java VMs.
4275 When a thread is attached to the VM, the context class loader is
4276 the bootstrap loader.
4278 *******************************************************************************/
4280 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
4282 STATS(jniinvokation();)
4284 log_text("AttachCurrentThread called");
4286 #if !defined(HAVE___THREAD)
4287 /* cacao_thread_attach();*/
4289 #error "No idea how to implement that. Perhaps Stefan knows"
4298 jint DetachCurrentThread(JavaVM *vm)
4300 STATS(jniinvokation();)
4301 log_text("DetachCurrentThread called");
4307 /* GetEnv **********************************************************************
4309 If the current thread is not attached to the VM, sets *env to NULL,
4310 and returns JNI_EDETACHED. If the specified version is not
4311 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
4312 sets *env to the appropriate interface, and returns JNI_OK.
4314 *******************************************************************************/
4316 jint GetEnv(JavaVM *vm, void **env, jint version)
4318 STATS(jniinvokation();)
4320 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4321 if (thread_getself() == NULL) {
4324 return JNI_EDETACHED;
4328 if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
4329 (version == JNI_VERSION_1_4)) {
4335 #if defined(ENABLE_JVMTI)
4336 if (version == JVMTI_VERSION_1_0) {
4337 *env = (void *) new_jvmtienv();
4346 return JNI_EVERSION;
4351 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4353 STATS(jniinvokation();)
4354 log_text("AttachCurrentThreadAsDaemon called");
4360 /* JNI invocation table *******************************************************/
4362 const struct JNIInvokeInterface JNI_JavaVMTable = {
4368 AttachCurrentThread,
4369 DetachCurrentThread,
4371 AttachCurrentThreadAsDaemon
4375 /* JNI function table *********************************************************/
4377 struct JNINativeInterface JNI_JNIEnvTable = {
4386 &FromReflectedMethod,
4387 &FromReflectedField,
4407 &EnsureLocalCapacity,
4423 &CallBooleanMethodV,
4424 &CallBooleanMethodA,
4450 &CallNonvirtualObjectMethod,
4451 &CallNonvirtualObjectMethodV,
4452 &CallNonvirtualObjectMethodA,
4453 &CallNonvirtualBooleanMethod,
4454 &CallNonvirtualBooleanMethodV,
4455 &CallNonvirtualBooleanMethodA,
4456 &CallNonvirtualByteMethod,
4457 &CallNonvirtualByteMethodV,
4458 &CallNonvirtualByteMethodA,
4459 &CallNonvirtualCharMethod,
4460 &CallNonvirtualCharMethodV,
4461 &CallNonvirtualCharMethodA,
4462 &CallNonvirtualShortMethod,
4463 &CallNonvirtualShortMethodV,
4464 &CallNonvirtualShortMethodA,
4465 &CallNonvirtualIntMethod,
4466 &CallNonvirtualIntMethodV,
4467 &CallNonvirtualIntMethodA,
4468 &CallNonvirtualLongMethod,
4469 &CallNonvirtualLongMethodV,
4470 &CallNonvirtualLongMethodA,
4471 &CallNonvirtualFloatMethod,
4472 &CallNonvirtualFloatMethodV,
4473 &CallNonvirtualFloatMethodA,
4474 &CallNonvirtualDoubleMethod,
4475 &CallNonvirtualDoubleMethodV,
4476 &CallNonvirtualDoubleMethodA,
4477 &CallNonvirtualVoidMethod,
4478 &CallNonvirtualVoidMethodV,
4479 &CallNonvirtualVoidMethodA,
4504 &CallStaticObjectMethod,
4505 &CallStaticObjectMethodV,
4506 &CallStaticObjectMethodA,
4507 &CallStaticBooleanMethod,
4508 &CallStaticBooleanMethodV,
4509 &CallStaticBooleanMethodA,
4510 &CallStaticByteMethod,
4511 &CallStaticByteMethodV,
4512 &CallStaticByteMethodA,
4513 &CallStaticCharMethod,
4514 &CallStaticCharMethodV,
4515 &CallStaticCharMethodA,
4516 &CallStaticShortMethod,
4517 &CallStaticShortMethodV,
4518 &CallStaticShortMethodA,
4519 &CallStaticIntMethod,
4520 &CallStaticIntMethodV,
4521 &CallStaticIntMethodA,
4522 &CallStaticLongMethod,
4523 &CallStaticLongMethodV,
4524 &CallStaticLongMethodA,
4525 &CallStaticFloatMethod,
4526 &CallStaticFloatMethodV,
4527 &CallStaticFloatMethodA,
4528 &CallStaticDoubleMethod,
4529 &CallStaticDoubleMethodV,
4530 &CallStaticDoubleMethodA,
4531 &CallStaticVoidMethod,
4532 &CallStaticVoidMethodV,
4533 &CallStaticVoidMethodA,
4537 &GetStaticObjectField,
4538 &GetStaticBooleanField,
4539 &GetStaticByteField,
4540 &GetStaticCharField,
4541 &GetStaticShortField,
4543 &GetStaticLongField,
4544 &GetStaticFloatField,
4545 &GetStaticDoubleField,
4546 &SetStaticObjectField,
4547 &SetStaticBooleanField,
4548 &SetStaticByteField,
4549 &SetStaticCharField,
4550 &SetStaticShortField,
4552 &SetStaticLongField,
4553 &SetStaticFloatField,
4554 &SetStaticDoubleField,
4559 &ReleaseStringChars,
4562 &GetStringUTFLength,
4564 &ReleaseStringUTFChars,
4569 &GetObjectArrayElement,
4570 &SetObjectArrayElement,
4581 &GetBooleanArrayElements,
4582 &GetByteArrayElements,
4583 &GetCharArrayElements,
4584 &GetShortArrayElements,
4585 &GetIntArrayElements,
4586 &GetLongArrayElements,
4587 &GetFloatArrayElements,
4588 &GetDoubleArrayElements,
4590 &ReleaseBooleanArrayElements,
4591 &ReleaseByteArrayElements,
4592 &ReleaseCharArrayElements,
4593 &ReleaseShortArrayElements,
4594 &ReleaseIntArrayElements,
4595 &ReleaseLongArrayElements,
4596 &ReleaseFloatArrayElements,
4597 &ReleaseDoubleArrayElements,
4599 &GetBooleanArrayRegion,
4600 &GetByteArrayRegion,
4601 &GetCharArrayRegion,
4602 &GetShortArrayRegion,
4604 &GetLongArrayRegion,
4605 &GetFloatArrayRegion,
4606 &GetDoubleArrayRegion,
4607 &SetBooleanArrayRegion,
4608 &SetByteArrayRegion,
4609 &SetCharArrayRegion,
4610 &SetShortArrayRegion,
4612 &SetLongArrayRegion,
4613 &SetFloatArrayRegion,
4614 &SetDoubleArrayRegion,
4624 /* new JNI 1.2 functions */
4627 &GetStringUTFRegion,
4629 &GetPrimitiveArrayCritical,
4630 &ReleasePrimitiveArrayCritical,
4633 &ReleaseStringCritical,
4636 &DeleteWeakGlobalRef,
4640 /* new JNI 1.4 functions */
4642 &NewDirectByteBuffer,
4643 &GetDirectBufferAddress,
4644 &GetDirectBufferCapacity
4648 /* Invocation API Functions ***************************************************/
4650 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4652 Returns a default configuration for the Java VM.
4654 *******************************************************************************/
4656 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4658 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4660 /* GNU classpath currently supports JNI 1.2 */
4662 _vm_args->version = JNI_VERSION_1_2;
4668 /* JNI_GetCreatedJavaVMs *******************************************************
4670 Returns all Java VMs that have been created. Pointers to VMs are written in
4671 the buffer vmBuf in the order they are created. At most bufLen number of
4672 entries will be written. The total number of created VMs is returned in
4675 *******************************************************************************/
4677 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4679 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4685 /* JNI_CreateJavaVM ************************************************************
4687 Loads and initializes a Java VM. The current thread becomes the main thread.
4688 Sets the env argument to the JNI interface pointer of the main thread.
4690 *******************************************************************************/
4692 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4694 const struct JNIInvokeInterface *vm;
4695 struct JNINativeInterface *env;
4697 vm = &JNI_JavaVMTable;
4698 env = &JNI_JNIEnvTable;
4700 *p_vm = (JavaVM *) vm;
4701 *p_env = (JNIEnv *) env;
4707 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4708 jobject obj, java_objectarray *params)
4715 if (methodID == 0) {
4716 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
4720 argcount = methodID->parseddesc->paramcount;
4721 paramcount = argcount;
4723 /* if method is non-static, remove the `this' pointer */
4725 if (!(methodID->flags & ACC_STATIC))
4728 /* the method is an instance method the obj has to be an instance of the
4729 class the method belongs to. For static methods the obj parameter
4732 if (!(methodID->flags & ACC_STATIC) && obj &&
4733 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4735 new_exception_message(string_java_lang_IllegalArgumentException,
4736 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4740 if (((params == NULL) && (paramcount != 0)) ||
4741 (params && (params->header.size != paramcount))) {
4743 new_exception(string_java_lang_IllegalArgumentException);
4748 if (!(methodID->flags & ACC_STATIC) && !obj) {
4750 new_exception_message(string_java_lang_NullPointerException,
4751 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4755 if ((methodID->flags & ACC_STATIC) && (obj))
4759 if ((methodID->flags & ACC_ABSTRACT) ||
4760 (methodID->class->flags & ACC_INTERFACE)) {
4761 methodID = get_virtual(obj, methodID);
4765 blk = MNEW(jni_callblock, argcount);
4767 if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4771 switch (methodID->parseddesc->returntype.decltype) {
4773 (void) asm_calljavafunction2(methodID, argcount,
4774 argcount * sizeof(jni_callblock),
4776 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4779 case PRIMITIVETYPE_INT: {
4781 i = asm_calljavafunction2int(methodID, argcount,
4782 argcount * sizeof(jni_callblock),
4785 o = native_new_and_init_int(class_java_lang_Integer, i);
4789 case PRIMITIVETYPE_BYTE: {
4791 i = asm_calljavafunction2int(methodID, argcount,
4792 argcount * sizeof(jni_callblock),
4795 /* o = native_new_and_init_int(class_java_lang_Byte, i); */
4796 o = builtin_new(class_java_lang_Byte);
4799 class_resolvemethod(o->vftbl->class,
4806 case PRIMITIVETYPE_CHAR: {
4808 intVal = asm_calljavafunction2int(methodID,
4810 argcount * sizeof(jni_callblock),
4812 o = builtin_new(class_java_lang_Character);
4815 class_resolvemethod(o->vftbl->class,
4822 case PRIMITIVETYPE_SHORT: {
4824 intVal = asm_calljavafunction2int(methodID,
4826 argcount * sizeof(jni_callblock),
4828 o = builtin_new(class_java_lang_Short);
4831 class_resolvemethod(o->vftbl->class,
4838 case PRIMITIVETYPE_BOOLEAN: {
4840 intVal = asm_calljavafunction2int(methodID,
4842 argcount * sizeof(jni_callblock),
4844 o = builtin_new(class_java_lang_Boolean);
4847 class_resolvemethod(o->vftbl->class,
4854 case PRIMITIVETYPE_LONG: {
4856 longVal = asm_calljavafunction2long(methodID,
4858 argcount * sizeof(jni_callblock),
4860 o = builtin_new(class_java_lang_Long);
4863 class_resolvemethod(o->vftbl->class,
4870 case PRIMITIVETYPE_FLOAT: {
4872 floatVal = asm_calljavafunction2float(methodID,
4874 argcount * sizeof(jni_callblock),
4876 o = builtin_new(class_java_lang_Float);
4879 class_resolvemethod(o->vftbl->class,
4886 case PRIMITIVETYPE_DOUBLE: {
4888 doubleVal = asm_calljavafunction2double(methodID,
4890 argcount * sizeof(jni_callblock),
4892 o = builtin_new(class_java_lang_Double);
4895 class_resolvemethod(o->vftbl->class,
4903 o = asm_calljavafunction2(methodID, argcount,
4904 argcount * sizeof(jni_callblock), blk);
4908 /* if this happens the exception has already been set by */
4909 /* fill_callblock_from_objectarray */
4911 MFREE(blk, jni_callblock, argcount);
4912 return (jobject *) 0;
4915 MFREE(blk, jni_callblock, argcount);
4917 if (*exceptionptr) {
4918 java_objectheader *cause;
4920 cause = *exceptionptr;
4922 /* clear exception pointer, we are calling JIT code again */
4924 *exceptionptr = NULL;
4927 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
4928 (java_lang_Throwable *) cause);
4931 return (jobject *) o;
4936 * These are local overrides for various environment variables in Emacs.
4937 * Please do not remove this and leave it at the end of the file, where
4938 * Emacs will automagically detect them.
4939 * ---------------------------------------------------------------------
4942 * indent-tabs-mode: t