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 3429 2005-10-13 13:48:21Z edwin $
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 #define LOCALREFTABLE (THREADINFO->_localref_table)
153 #define LOCALREFTABLE (_no_threads_localref_table)
156 #if !defined(USE_THREADS)
157 static localref_table *_no_threads_localref_table;
161 /********************* accessing instance-fields **********************************/
163 #define setField(obj,typ,var,val) *((typ*) ((long int) obj + (long int) var->offset))=val;
164 #define getField(obj,typ,var) *((typ*) ((long int) obj + (long int) var->offset))
165 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) \
166 setField(obj, jdatatype, getFieldID_critical(env,clazz,name,sig), val);
169 /* some forward declarations **************************************************/
171 jobject NewLocalRef(JNIEnv *env, jobject ref);
174 /* jni_init ********************************************************************
176 Initialize the JNI subsystem.
178 *******************************************************************************/
182 /* initalize global reference table */
185 load_class_bootstrap(utf_new_char("java/util/IdentityHashMap"))))
188 global_ref_table = GCNEW(jobject, 1);
190 if (!(*global_ref_table = native_new_and_init(ihmclass)))
193 if (!(getmid = class_resolvemethod(ihmclass, utf_get,
194 utf_java_lang_Object__java_lang_Object)))
197 if (!(putmid = class_resolvemethod(ihmclass, utf_put,
198 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))))
202 class_resolvemethod(ihmclass, utf_remove,
203 utf_java_lang_Object__java_lang_Object)))
207 /* direct buffer stuff */
209 utf_java_nio_DirectByteBufferImpl =
210 utf_new_char("java/nio/DirectByteBufferImpl");
212 if (!(class_java_nio_DirectByteBufferImpl =
213 load_class_bootstrap(utf_java_nio_DirectByteBufferImpl)))
216 if (!link_class(class_java_nio_DirectByteBufferImpl))
219 #if SIZEOF_VOID_P == 8
220 utf_gnu_classpath_Pointer64 = utf_new_char("gnu/classpath/Pointer64");
222 if (!(class_gnu_classpath_Pointer64 =
223 load_class_bootstrap(utf_gnu_classpath_Pointer64)))
226 if (!link_class(class_gnu_classpath_Pointer64))
229 utf_gnu_classpath_Pointer32 = utf_new_char("gnu/classpath/Pointer32");
231 if (!(class_gnu_classpath_Pointer32 =
232 load_class_bootstrap(utf_gnu_classpath_Pointer32)))
235 if (!link_class(class_gnu_classpath_Pointer32))
243 static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
244 jni_callblock blk[], va_list data,
247 typedesc *paramtypes;
250 paramtypes = descr->paramtypes;
252 /* if method is non-static fill first block and skip `this' pointer */
257 /* the `this' pointer */
258 blk[0].itemtype = TYPE_ADR;
259 blk[0].item = PTR_TO_ITEM(obj);
265 for (; i < descr->paramcount; i++, paramtypes++) {
266 switch (paramtypes->decltype) {
267 /* primitive types */
268 case PRIMITIVETYPE_BYTE:
269 case PRIMITIVETYPE_CHAR:
270 case PRIMITIVETYPE_SHORT:
271 case PRIMITIVETYPE_BOOLEAN:
272 blk[i].itemtype = TYPE_INT;
273 blk[i].item = (s8) va_arg(data, s4);
276 case PRIMITIVETYPE_INT:
277 blk[i].itemtype = TYPE_INT;
278 blk[i].item = (s8) va_arg(data, s4);
281 case PRIMITIVETYPE_LONG:
282 blk[i].itemtype = TYPE_LNG;
283 blk[i].item = (s8) va_arg(data, s8);
286 case PRIMITIVETYPE_FLOAT:
287 blk[i].itemtype = TYPE_FLT;
288 #if defined(__ALPHA__)
289 /* this keeps the assembler function much simpler */
291 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
293 *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
297 case PRIMITIVETYPE_DOUBLE:
298 blk[i].itemtype = TYPE_DBL;
299 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
303 blk[i].itemtype = TYPE_ADR;
304 blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
309 /* The standard doesn't say anything about return value checking, but it */
310 /* appears to be useful. */
312 if (rettype != descr->returntype.decltype)
313 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
317 /* XXX it could be considered if we should do typechecking here in the future */
319 static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
321 java_objectarray *params)
325 typedesc *paramtypes;
330 paramcount = descr->paramcount;
331 paramtypes = descr->paramtypes;
333 /* if method is non-static fill first block and skip `this' pointer */
339 blk[0].itemtype = TYPE_ADR;
340 blk[0].item = PTR_TO_ITEM(obj);
347 for (j = 0; j < paramcount; i++, j++, paramtypes++) {
348 switch (paramtypes->type) {
349 /* primitive types */
354 param = params->data[j];
358 /* internally used data type */
359 blk[i].itemtype = paramtypes->type;
361 /* convert the value according to its declared type */
363 c = param->vftbl->class;
365 switch (paramtypes->decltype) {
366 case PRIMITIVETYPE_BOOLEAN:
367 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
368 blk[i].item = (s8) ((java_lang_Boolean *) param)->value;
373 case PRIMITIVETYPE_BYTE:
374 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
375 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
380 case PRIMITIVETYPE_CHAR:
381 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
382 blk[i].item = (s8) ((java_lang_Character *) param)->value;
387 case PRIMITIVETYPE_SHORT:
388 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
389 blk[i].item = (s8) ((java_lang_Short *) param)->value;
390 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
391 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
396 case PRIMITIVETYPE_INT:
397 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
398 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
399 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
400 blk[i].item = (s8) ((java_lang_Short *) param)->value;
401 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
402 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
407 case PRIMITIVETYPE_LONG:
408 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
409 blk[i].item = (s8) ((java_lang_Long *) param)->value;
410 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
411 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
412 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
413 blk[i].item = (s8) ((java_lang_Short *) param)->value;
414 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
415 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
420 case PRIMITIVETYPE_FLOAT:
421 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
422 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
427 case PRIMITIVETYPE_DOUBLE:
428 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
429 *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Float *) param)->value;
430 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
431 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
438 } /* end declared type switch */
442 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
445 if (params->data[j] != 0) {
446 if (paramtypes->arraydim > 0) {
447 if (!builtin_arrayinstanceof(params->data[j], c->vftbl))
451 if (!builtin_instanceof(params->data[j], c))
455 blk[i].itemtype = TYPE_ADR;
456 blk[i].item = PTR_TO_ITEM(params->data[j]);
461 } /* end param type switch */
463 } /* end param loop */
466 /* *rettype = descr->returntype.decltype; */
471 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
476 static jmethodID get_virtual(jobject obj, jmethodID methodID)
478 if (obj->vftbl->class == methodID->class)
481 return class_resolvemethod(obj->vftbl->class, methodID->name,
482 methodID->descriptor);
486 static jmethodID get_nonvirtual(jclass clazz, jmethodID methodID)
488 if (clazz == methodID->class)
491 /* class_resolvemethod -> classfindmethod? (JOWENN) */
492 return class_resolvemethod(clazz, methodID->name, methodID->descriptor);
496 static jobject callObjectMethod(jobject obj, jmethodID methodID, va_list args)
503 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
507 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
508 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
509 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
513 if (obj && !builtin_instanceof(obj, methodID->class)) {
514 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
518 argcount = methodID->parseddesc->paramcount;
520 blk = MNEW(jni_callblock, argcount);
522 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_ADR);
524 STATS(jnicallXmethodnvokation();)
526 ret = asm_calljavafunction2(methodID,
528 argcount * sizeof(jni_callblock),
531 MFREE(blk, jni_callblock, argcount);
538 core function for integer class methods (bool, byte, short, integer)
539 This is basically needed for i386
541 static jint callIntegerMethod(jobject obj, jmethodID methodID, int retType, va_list args)
547 STATS(jniinvokation();)
550 log_text("JNI-Call: CallObjectMethodV");
551 utf_display(methodID->name);
552 utf_display(methodID->descriptor);
553 printf("\nParmaeter count: %d\n",argcount);
554 utf_display(obj->vftbl->class->name);
558 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
562 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
563 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
564 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
568 if (obj && !builtin_instanceof(obj, methodID->class)) {
569 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
573 argcount = methodID->parseddesc->paramcount;
575 blk = MNEW(jni_callblock, argcount);
577 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
579 STATS(jnicallXmethodnvokation();)
581 ret = asm_calljavafunction2int(methodID,
583 argcount * sizeof(jni_callblock),
586 MFREE(blk, jni_callblock, argcount);
592 /* callLongMethod **************************************************************
594 Core function for long class functions.
596 *******************************************************************************/
598 static jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
604 STATS(jniinvokation();)
607 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
611 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
612 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
613 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
617 if (obj && !builtin_instanceof(obj, methodID->class)) {
618 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
622 argcount = methodID->parseddesc->paramcount;
624 blk = MNEW(jni_callblock, argcount);
626 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_LNG);
628 STATS(jnicallXmethodnvokation();)
630 ret = asm_calljavafunction2long(methodID,
632 argcount * sizeof(jni_callblock),
635 MFREE(blk, jni_callblock, argcount);
641 /*core function for float class methods (float,double)*/
642 static jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,int retType)
644 int argcount = methodID->parseddesc->paramcount;
648 STATS(jniinvokation();)
653 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
654 log_text("Too many arguments. CallObjectMethod does not support that");
658 blk = MNEW(jni_callblock, /*4 */ argcount+2);
660 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
662 /* printf("parameter: obj: %p",blk[0].item); */
663 STATS(jnicallXmethodnvokation();)
664 ret = asm_calljavafunction2double(methodID,
666 (argcount + 1) * sizeof(jni_callblock),
669 MFREE(blk, jni_callblock, argcount + 1);
670 /* printf("(CallObjectMethodV)-->%p\n",ret); */
676 static void cacao_jni_CallVoidMethod(jobject obj, jmethodID m, va_list ap)
682 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
686 if (!( ((m->flags & ACC_STATIC) && (obj == 0)) ||
687 ((!(m->flags & ACC_STATIC)) && (obj != 0)) )) {
688 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
692 if (obj && !builtin_instanceof(obj, m->class)) {
693 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
697 paramcount = m->parseddesc->paramcount;
699 if (!(m->flags & ACC_STATIC))
702 blk = MNEW(jni_callblock, paramcount);
704 fill_callblock_from_vargs(obj, m->parseddesc, blk, ap, TYPE_VOID);
706 STATS(jnicallXmethodnvokation();)
708 (void) asm_calljavafunction2(m,
710 paramcount * sizeof(jni_callblock),
713 MFREE(blk, jni_callblock, paramcount);
719 /* GetVersion ******************************************************************
721 Returns the major version number in the higher 16 bits and the
722 minor version number in the lower 16 bits.
724 *******************************************************************************/
726 jint GetVersion(JNIEnv *env)
728 STATS(jniinvokation();)
730 /* we support JNI 1.4 */
732 return JNI_VERSION_1_4;
736 /* Class Operations ***********************************************************/
738 /* DefineClass *****************************************************************
740 Loads a class from a buffer of raw class data. The buffer
741 containing the raw class data is not referenced by the VM after the
742 DefineClass call returns, and it may be discarded if desired.
744 *******************************************************************************/
746 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
747 const jbyte *buf, jsize bufLen)
749 java_lang_ClassLoader *cl;
754 STATS(jniinvokation();)
756 cl = (java_lang_ClassLoader *) loader;
757 s = javastring_new_char(name);
758 ba = (java_bytearray *) buf;
760 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
767 /* FindClass *******************************************************************
769 This function loads a locally-defined class. It searches the
770 directories and zip files specified by the CLASSPATH environment
771 variable for the class with the specified name.
773 *******************************************************************************/
775 jclass FindClass(JNIEnv *env, const char *name)
779 java_objectheader *cl;
781 STATS(jniinvokation();)
783 u = utf_new_char_classname((char *) name);
785 /* check stacktrace for classloader, if one found use it, otherwise use */
786 /* the system classloader */
788 #if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__)
789 /* these JITs support stacktraces, and so does the interpreter */
791 cl = cacao_currentClassLoader();
793 # if defined(ENABLE_INTRP)
794 /* the interpreter supports stacktraces, even if the JIT does not */
797 cl = cacao_currentClassLoader();
803 if (!(c = load_class_from_classloader(u, cl)))
809 if (!use_class_as_object(c))
812 return (jclass) NewLocalRef(env, (jobject) c);
816 /* FromReflectedMethod *********************************************************
818 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
819 object to a method ID.
821 *******************************************************************************/
823 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
829 STATS(jniinvokation();)
834 if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
835 java_lang_reflect_Method *rm;
837 rm = (java_lang_reflect_Method *) method;
838 c = (classinfo *) (rm->declaringClass);
841 } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
842 java_lang_reflect_Constructor *rc;
844 rc = (java_lang_reflect_Constructor *) method;
845 c = (classinfo *) (rc->clazz);
851 if ((slot < 0) || (slot >= c->methodscount)) {
852 /* this usually means a severe internal cacao error or somebody
853 tempered around with the reflected method */
854 log_text("error illegal slot for method in class(FromReflectedMethod)");
858 mi = &(c->methods[slot]);
864 /* GetSuperclass ***************************************************************
866 If clazz represents any class other than the class Object, then
867 this function returns the object that represents the superclass of
868 the class specified by clazz.
870 *******************************************************************************/
872 jclass GetSuperclass(JNIEnv *env, jclass sub)
875 STATS(jniinvokation();)
877 c = ((classinfo *) sub)->super.cls;
882 use_class_as_object(c);
888 /* IsAssignableFrom ************************************************************
890 Determines whether an object of sub can be safely cast to sup.
892 *******************************************************************************/
894 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
896 STATS(jniinvokation();)
897 return Java_java_lang_VMClass_isAssignableFrom(env,
899 (java_lang_Class *) sup,
900 (java_lang_Class *) sub);
904 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
906 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
908 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!!!");
909 STATS(jniinvokation();)
914 /* Throw ***********************************************************************
916 Causes a java.lang.Throwable object to be thrown.
918 *******************************************************************************/
920 jint Throw(JNIEnv *env, jthrowable obj)
922 *exceptionptr = (java_objectheader *) obj;
923 STATS(jniinvokation();)
929 /* ThrowNew ********************************************************************
931 Constructs an exception object from the specified class with the
932 message specified by message and causes that exception to be
935 *******************************************************************************/
937 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
939 java_lang_Throwable *o;
941 STATS(jniinvokation();)
943 s = (java_lang_String *) javastring_new_char(msg);
945 /* instantiate exception object */
947 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
953 *exceptionptr = (java_objectheader *) o;
959 /* ExceptionOccurred ***********************************************************
961 Determines if an exception is being thrown. The exception stays
962 being thrown until either the native code calls ExceptionClear(),
963 or the Java code handles the exception.
965 *******************************************************************************/
967 jthrowable ExceptionOccurred(JNIEnv *env)
969 java_objectheader *e;
971 STATS(jniinvokation();)
975 return NewLocalRef(env, (jthrowable) e);
979 /* ExceptionDescribe ***********************************************************
981 Prints an exception and a backtrace of the stack to a system
982 error-reporting channel, such as stderr. This is a convenience
983 routine provided for debugging.
985 *******************************************************************************/
987 void ExceptionDescribe(JNIEnv *env)
989 java_objectheader *e;
991 STATS(jniinvokation();)
996 /* clear exception, because we are calling jit code again */
998 *exceptionptr = NULL;
1000 /* get printStackTrace method from exception class */
1002 m = class_resolveclassmethod(e->vftbl->class,
1003 utf_printStackTrace,
1009 /* XXX what should we do? */
1012 /* print the stacktrace */
1014 asm_calljavafunction(m, e, NULL, NULL, NULL);
1019 /* ExceptionClear **************************************************************
1021 Clears any exception that is currently being thrown. If no
1022 exception is currently being thrown, this routine has no effect.
1024 *******************************************************************************/
1026 void ExceptionClear(JNIEnv *env)
1028 STATS(jniinvokation();)
1030 *exceptionptr = NULL;
1034 /* FatalError ******************************************************************
1036 Raises a fatal error and does not expect the VM to recover. This
1037 function does not return.
1039 *******************************************************************************/
1041 void FatalError(JNIEnv *env, const char *msg)
1043 STATS(jniinvokation();)
1045 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
1049 /* PushLocalFrame **************************************************************
1051 Creates a new local reference frame, in which at least a given
1052 number of local references can be created.
1054 *******************************************************************************/
1056 jint PushLocalFrame(JNIEnv* env, jint capacity)
1058 STATS(jniinvokation();)
1060 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
1067 /* PopLocalFrame ***************************************************************
1069 Pops off the current local reference frame, frees all the local
1070 references, and returns a local reference in the previous local
1071 reference frame for the given result object.
1073 *******************************************************************************/
1075 jobject PopLocalFrame(JNIEnv* env, jobject result)
1077 STATS(jniinvokation();)
1079 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
1083 /* add local reference and return the value */
1085 return NewLocalRef(env, NULL);
1089 /* DeleteLocalRef **************************************************************
1091 Deletes the local reference pointed to by localRef.
1093 *******************************************************************************/
1095 void DeleteLocalRef(JNIEnv *env, jobject localRef)
1097 java_objectheader *o;
1098 localref_table *lrt;
1101 STATS(jniinvokation();)
1103 o = (java_objectheader *) localRef;
1105 /* get local reference table (thread specific) */
1107 lrt = LOCALREFTABLE;
1109 /* remove the reference */
1111 for (i = 0; i < lrt->capacity; i++) {
1112 if (lrt->refs[i] == o) {
1113 lrt->refs[i] = NULL;
1120 /* this should not happen */
1122 /* if (opt_checkjni) */
1123 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1124 log_text("JNI-DeleteLocalRef: Bad global or local ref passed to JNI");
1128 /* IsSameObject ****************************************************************
1130 Tests whether two references refer to the same Java object.
1132 *******************************************************************************/
1134 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1136 STATS(jniinvokation();)
1145 /* NewLocalRef *****************************************************************
1147 Creates a new local reference that refers to the same object as ref.
1149 *******************************************************************************/
1151 jobject NewLocalRef(JNIEnv *env, jobject ref)
1153 localref_table *lrt;
1156 STATS(jniinvokation();)
1161 /* get local reference table (thread specific) */
1163 lrt = LOCALREFTABLE;
1165 /* check if we have space for the requested reference */
1167 if (lrt->used == lrt->capacity)
1168 throw_cacao_exception_exit(string_java_lang_InternalError,
1169 "Too many local references");
1171 /* insert the reference */
1173 for (i = 0; i < lrt->capacity; i++) {
1174 if (lrt->refs[i] == NULL) {
1175 lrt->refs[i] = (java_objectheader *) ref;
1182 /* should not happen, just to be sure */
1188 /* EnsureLocalCapacity *********************************************************
1190 Ensures that at least a given number of local references can be
1191 created in the current thread
1193 *******************************************************************************/
1195 jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
1197 localref_table *lrt;
1199 STATS(jniinvokation();)
1201 /* get local reference table (thread specific) */
1203 lrt = LOCALREFTABLE;
1205 /* check if capacity elements are available in the local references table */
1207 if ((lrt->used + capacity) > lrt->capacity) {
1208 *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
1216 /* AllocObject *****************************************************************
1218 Allocates a new Java object without invoking any of the
1219 constructors for the object. Returns a reference to the object.
1221 *******************************************************************************/
1223 jobject AllocObject(JNIEnv *env, jclass clazz)
1225 java_objectheader *o;
1227 STATS(jniinvokation();)
1229 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1231 new_exception_utfmessage(string_java_lang_InstantiationException,
1236 o = builtin_new(clazz);
1238 return NewLocalRef(env, o);
1242 /* NewObject *******************************************************************
1244 Programmers place all arguments that are to be passed to the
1245 constructor immediately following the methodID
1246 argument. NewObject() accepts these arguments and passes them to
1247 the Java method that the programmer wishes to invoke.
1249 *******************************************************************************/
1251 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1253 java_objectheader *o;
1256 STATS(jniinvokation();)
1260 o = builtin_new(clazz);
1265 /* call constructor */
1267 va_start(ap, methodID);
1268 cacao_jni_CallVoidMethod(o, methodID, ap);
1271 return NewLocalRef(env, o);
1275 /***********************************************************************************
1277 Constructs a new Java object
1278 arguments that are to be passed to the constructor are placed in va_list args
1280 ***********************************************************************************/
1282 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1284 STATS(jniinvokation();)
1286 log_text("JNI-Call: NewObjectV: IMPLEMENT ME!");
1288 return NewLocalRef(env, NULL);
1292 /***********************************************************************************
1294 Constructs a new Java object
1295 arguments that are to be passed to the constructor are placed in
1296 args array of jvalues
1298 ***********************************************************************************/
1300 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1302 STATS(jniinvokation();)
1304 log_text("JNI-Call: NewObjectA: IMPLEMENT ME!");
1306 return NewLocalRef(env, NULL);
1310 /* GetObjectClass **************************************************************
1312 Returns the class of an object.
1314 *******************************************************************************/
1316 jclass GetObjectClass(JNIEnv *env, jobject obj)
1319 STATS(jniinvokation();)
1321 if (!obj || !obj->vftbl)
1324 c = obj->vftbl->class;
1325 use_class_as_object(c);
1330 /* IsInstanceOf ****************************************************************
1332 Tests whether an object is an instance of a class.
1334 *******************************************************************************/
1336 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1338 STATS(jniinvokation();)
1340 return Java_java_lang_VMClass_isInstance(env,
1342 (java_lang_Class *) clazz,
1343 (java_lang_Object *) obj);
1347 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1349 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1351 java_lang_reflect_Field *f;
1353 jfieldID fid; /* the JNI-fieldid of the wrapping object */
1354 STATS(jniinvokation();)
1355 /*log_text("JNI-Call: FromReflectedField");*/
1357 f=(java_lang_reflect_Field *)field;
1359 c=(classinfo*)(f->declaringClass);
1360 if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1361 /*this usually means a severe internal cacao error or somebody
1362 tempered around with the reflected method*/
1363 log_text("error illegal slot for field in class(FromReflectedField)");
1366 fid=&(c->fields[f->slot]);
1371 /**********************************************************************************
1373 converts a method ID to a java.lang.reflect.Method or
1374 java.lang.reflect.Constructor object
1376 **********************************************************************************/
1378 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1380 log_text("JNI-Call: ToReflectedMethod");
1381 STATS(jniinvokation();)
1387 /* GetMethodID *****************************************************************
1389 returns the method ID for an instance method
1391 *******************************************************************************/
1393 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1397 STATS(jniinvokation();)
1399 m = class_resolvemethod(clazz,
1400 utf_new_char((char *) name),
1401 utf_new_char((char *) sig));
1403 if (!m || (m->flags & ACC_STATIC)) {
1405 new_exception_message(string_java_lang_NoSuchMethodError, name);
1414 /******************** JNI-functions for calling instance methods ******************/
1416 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1418 java_objectheader* ret;
1421 STATS(jniinvokation();)
1423 va_start(vaargs, methodID);
1424 ret = callObjectMethod(obj, methodID, vaargs);
1427 return NewLocalRef(env, ret);
1431 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1433 java_objectheader* ret;
1435 STATS(jniinvokation();)
1437 ret = callObjectMethod(obj, methodID, args);
1439 return NewLocalRef(env, ret);
1443 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1445 STATS(jniinvokation();)
1447 log_text("JNI-Call: CallObjectMethodA: IMPLEMENT ME!");
1449 return NewLocalRef(env, NULL);
1455 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1459 STATS(jniinvokation();)
1461 /* log_text("JNI-Call: CallBooleanMethod");*/
1463 va_start(vaargs,methodID);
1464 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1470 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1472 STATS(jniinvokation();)
1474 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
1478 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1480 STATS(jniinvokation();)
1481 log_text("JNI-Call: CallBooleanMethodA");
1486 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1490 STATS(jniinvokation();)
1492 /* log_text("JNI-Call: CallVyteMethod");*/
1494 va_start(vaargs,methodID);
1495 ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
1501 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1503 /* log_text("JNI-Call: CallByteMethodV");*/
1504 STATS(jniinvokation();)
1506 return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
1510 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1512 log_text("JNI-Call: CallByteMethodA");
1513 STATS(jniinvokation();)
1519 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1523 STATS(jniinvokation();)
1525 /* log_text("JNI-Call: CallCharMethod");*/
1527 va_start(vaargs,methodID);
1528 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
1535 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1537 STATS(jniinvokation();)
1539 /* log_text("JNI-Call: CallCharMethodV");*/
1540 return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
1544 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1546 STATS(jniinvokation();)
1548 log_text("JNI-Call: CallCharMethodA");
1554 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1558 STATS(jniinvokation();)
1560 /* log_text("JNI-Call: CallShortMethod");*/
1562 va_start(vaargs, methodID);
1563 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
1570 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1572 STATS(jniinvokation();)
1573 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
1577 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1579 STATS(jniinvokation();)
1580 log_text("JNI-Call: CallShortMethodA");
1587 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1591 STATS(jniinvokation();)
1593 va_start(vaargs,methodID);
1594 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
1601 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1603 STATS(jniinvokation();)
1604 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
1608 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1610 STATS(jniinvokation();)
1611 log_text("JNI-Call: CallIntMethodA");
1618 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1622 STATS(jniinvokation();)
1624 va_start(vaargs,methodID);
1625 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1632 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1634 STATS(jniinvokation();)
1635 return callLongMethod(obj,get_virtual(obj, methodID),args);
1639 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1641 STATS(jniinvokation();)
1642 log_text("JNI-Call: CallLongMethodA");
1649 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1654 STATS(jniinvokation();)
1655 /* log_text("JNI-Call: CallFloatMethod");*/
1657 va_start(vaargs,methodID);
1658 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
1665 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1667 STATS(jniinvokation();)
1668 log_text("JNI-Call: CallFloatMethodV");
1669 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
1673 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1675 STATS(jniinvokation();)
1676 log_text("JNI-Call: CallFloatMethodA");
1683 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1687 STATS(jniinvokation();)
1689 /* log_text("JNI-Call: CallDoubleMethod");*/
1691 va_start(vaargs,methodID);
1692 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
1699 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1701 STATS(jniinvokation();)
1702 log_text("JNI-Call: CallDoubleMethodV");
1703 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
1707 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1709 STATS(jniinvokation();)
1710 log_text("JNI-Call: CallDoubleMethodA");
1716 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1719 STATS(jniinvokation();)
1721 va_start(vaargs,methodID);
1722 (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
1727 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1729 log_text("JNI-Call: CallVoidMethodV");
1730 STATS(jniinvokation();)
1731 (void)callIntegerMethod(obj,get_virtual(obj,methodID),TYPE_VOID,args);
1735 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1737 STATS(jniinvokation();)
1738 log_text("JNI-Call: CallVoidMethodA");
1743 jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1745 STATS(jniinvokation();)
1747 log_text("JNI-Call: CallNonvirtualObjectMethod: IMPLEMENT ME!");
1749 return NewLocalRef(env, NULL);
1753 jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1755 STATS(jniinvokation();)
1757 log_text("JNI-Call: CallNonvirtualObjectMethodV: IMPLEMENT ME!");
1759 return NewLocalRef(env, NULL);
1763 jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1765 STATS(jniinvokation();)
1767 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1769 return NewLocalRef(env, NULL);
1774 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1778 STATS(jniinvokation();)
1780 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1782 va_start(vaargs,methodID);
1783 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1790 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1792 STATS(jniinvokation();)
1793 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1794 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
1798 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1800 STATS(jniinvokation();)
1801 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1808 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1813 STATS(jniinvokation();)
1814 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1816 va_start(vaargs,methodID);
1817 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
1823 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1825 STATS(jniinvokation();)
1826 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1827 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
1832 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1834 STATS(jniinvokation();)
1835 log_text("JNI-Call: CallNonvirtualByteMethodA");
1842 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1847 STATS(jniinvokation();)
1848 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1850 va_start(vaargs,methodID);
1851 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
1857 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1859 STATS(jniinvokation();)
1860 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1861 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
1865 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1867 STATS(jniinvokation();)
1868 log_text("JNI-Call: CallNonvirtualCharMethodA");
1875 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1879 STATS(jniinvokation();)
1881 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1883 va_start(vaargs,methodID);
1884 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
1890 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1892 STATS(jniinvokation();)
1893 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1894 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
1898 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1900 STATS(jniinvokation();)
1901 log_text("JNI-Call: CallNonvirtualShortMethodA");
1908 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1913 STATS(jniinvokation();)
1915 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1917 va_start(vaargs,methodID);
1918 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
1924 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1926 STATS(jniinvokation();)
1927 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1928 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
1932 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1934 STATS(jniinvokation();)
1935 log_text("JNI-Call: CallNonvirtualIntMethodA");
1942 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1944 STATS(jniinvokation();)
1945 log_text("JNI-Call: CallNonvirtualLongMethod");
1951 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1953 STATS(jniinvokation();)
1954 log_text("JNI-Call: CallNonvirtualLongMethodV");
1960 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1962 STATS(jniinvokation();)
1963 log_text("JNI-Call: CallNonvirtualLongMethodA");
1970 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1974 STATS(jniinvokation();)
1976 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1979 va_start(vaargs,methodID);
1980 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
1987 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1989 STATS(jniinvokation();)
1990 log_text("JNI-Call: CallNonvirtualFloatMethodV");
1991 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
1995 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1997 STATS(jniinvokation();)
1998 log_text("JNI-Call: CallNonvirtualFloatMethodA");
2005 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2009 STATS(jniinvokation();)
2010 log_text("JNI-Call: CallNonvirtualDoubleMethod");
2012 va_start(vaargs,methodID);
2013 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
2020 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2022 STATS(jniinvokation();)
2023 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
2024 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
2028 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2030 STATS(jniinvokation();)
2031 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
2038 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2041 STATS(jniinvokation();)
2043 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
2045 va_start(vaargs,methodID);
2046 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
2052 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2054 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
2055 STATS(jniinvokation();)
2057 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
2062 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
2064 STATS(jniinvokation();)
2065 log_text("JNI-Call: CallNonvirtualVoidMethodA");
2068 /************************* JNI-functions for accessing fields ************************/
2070 jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2074 STATS(jniinvokation();)
2076 f = class_findfield(clazz, utf_new_char((char *) name), utf_new_char((char *) sig));
2079 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2084 /*************************** retrieve fieldid, abort on error ************************/
2086 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
2088 jfieldID id = GetFieldID(env, clazz, name, sig);
2089 STATS(jniinvokation();)
2093 utf_display(clazz->name);
2094 log_text("\nfield:");
2099 log_text("setfield_critical failed");
2105 jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2107 java_objectheader *o;
2109 STATS(jniinvokation();)
2111 o = getField(obj, java_objectheader*, fieldID);
2113 return NewLocalRef(env, o);
2116 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
2118 STATS(jniinvokation();)
2119 return getField(obj,jboolean,fieldID);
2123 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
2125 STATS(jniinvokation();)
2126 return getField(obj,jbyte,fieldID);
2130 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
2132 STATS(jniinvokation();)
2133 return getField(obj,jchar,fieldID);
2137 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
2139 STATS(jniinvokation();)
2140 return getField(obj,jshort,fieldID);
2144 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
2146 STATS(jniinvokation();)
2147 return getField(obj,jint,fieldID);
2151 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
2153 STATS(jniinvokation();)
2154 return getField(obj,jlong,fieldID);
2158 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
2160 STATS(jniinvokation();)
2161 return getField(obj,jfloat,fieldID);
2165 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
2167 STATS(jniinvokation();)
2168 return getField(obj,jdouble,fieldID);
2171 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
2173 STATS(jniinvokation();)
2174 setField(obj,jobject,fieldID,val);
2178 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
2180 STATS(jniinvokation();)
2181 setField(obj,jboolean,fieldID,val);
2185 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
2187 STATS(jniinvokation();)
2188 setField(obj,jbyte,fieldID,val);
2192 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
2194 STATS(jniinvokation();)
2195 setField(obj,jchar,fieldID,val);
2199 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
2201 STATS(jniinvokation();)
2202 setField(obj,jshort,fieldID,val);
2206 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
2208 STATS(jniinvokation();)
2209 setField(obj,jint,fieldID,val);
2213 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
2215 STATS(jniinvokation();)
2216 setField(obj,jlong,fieldID,val);
2220 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
2222 STATS(jniinvokation();)
2223 setField(obj,jfloat,fieldID,val);
2227 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
2229 STATS(jniinvokation();)
2230 setField(obj,jdouble,fieldID,val);
2234 /**************** JNI-functions for calling static methods **********************/
2236 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2239 STATS(jniinvokation();)
2241 m = class_resolvemethod(clazz,
2242 utf_new_char((char *) name),
2243 utf_new_char((char *) sig));
2245 if (!m || !(m->flags & ACC_STATIC)) {
2247 new_exception_message(string_java_lang_NoSuchMethodError, name);
2256 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2258 java_objectheader *ret;
2261 STATS(jniinvokation();)
2263 va_start(vaargs, methodID);
2264 ret = callObjectMethod(0, methodID, vaargs);
2267 return NewLocalRef(env, ret);
2271 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2273 java_objectheader *ret;
2275 STATS(jniinvokation();)
2277 ret = callObjectMethod(0, methodID, args);
2279 return NewLocalRef(env, ret);
2283 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2285 STATS(jniinvokation();)
2287 log_text("JNI-Call: CallStaticObjectMethodA: IMPLEMENT ME!");
2289 return NewLocalRef(env, NULL);
2293 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2297 STATS(jniinvokation();)
2299 va_start(vaargs, methodID);
2300 ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
2307 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2309 STATS(jniinvokation();)
2310 return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
2314 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2316 STATS(jniinvokation();)
2317 log_text("JNI-Call: CallStaticBooleanMethodA");
2323 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2327 STATS(jniinvokation();)
2329 /* log_text("JNI-Call: CallStaticByteMethod");*/
2331 va_start(vaargs, methodID);
2332 ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
2339 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2341 STATS(jniinvokation();)
2342 return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
2346 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2348 STATS(jniinvokation();)
2349 log_text("JNI-Call: CallStaticByteMethodA");
2355 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2359 STATS(jniinvokation();)
2361 /* log_text("JNI-Call: CallStaticByteMethod");*/
2363 va_start(vaargs, methodID);
2364 ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
2371 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2373 STATS(jniinvokation();)
2374 return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
2378 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2380 STATS(jniinvokation();)
2381 log_text("JNI-Call: CallStaticCharMethodA");
2388 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2392 STATS(jniinvokation();)
2394 /* log_text("JNI-Call: CallStaticByteMethod");*/
2396 va_start(vaargs, methodID);
2397 ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
2404 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2406 STATS(jniinvokation();)
2407 /*log_text("JNI-Call: CallStaticShortMethodV");*/
2408 return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
2412 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2414 STATS(jniinvokation();)
2415 log_text("JNI-Call: CallStaticShortMethodA");
2422 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2426 STATS(jniinvokation();)
2428 /* log_text("JNI-Call: CallStaticIntMethod");*/
2430 va_start(vaargs, methodID);
2431 ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
2438 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2440 STATS(jniinvokation();)
2441 log_text("JNI-Call: CallStaticIntMethodV");
2443 return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
2447 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2449 STATS(jniinvokation();)
2450 log_text("JNI-Call: CallStaticIntMethodA");
2457 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2461 STATS(jniinvokation();)
2463 /* log_text("JNI-Call: CallStaticLongMethod");*/
2465 va_start(vaargs, methodID);
2466 ret = callLongMethod(0, methodID, vaargs);
2473 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
2476 STATS(jniinvokation();)
2478 return callLongMethod(0, methodID, args);
2482 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2484 STATS(jniinvokation();)
2486 log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!!!");
2493 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2497 STATS(jniinvokation();)
2499 /* log_text("JNI-Call: CallStaticLongMethod");*/
2501 va_start(vaargs, methodID);
2502 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
2509 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2511 STATS(jniinvokation();)
2513 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
2518 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2520 STATS(jniinvokation();)
2521 log_text("JNI-Call: CallStaticFloatMethodA");
2528 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2532 STATS(jniinvokation();)
2534 /* log_text("JNI-Call: CallStaticDoubleMethod");*/
2536 va_start(vaargs,methodID);
2537 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
2544 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2546 STATS(jniinvokation();)
2547 log_text("JNI-Call: CallStaticDoubleMethodV");
2549 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
2553 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2555 STATS(jniinvokation();)
2556 log_text("JNI-Call: CallStaticDoubleMethodA");
2562 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2565 STATS(jniinvokation();)
2567 va_start(vaargs, methodID);
2568 (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
2573 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2575 log_text("JNI-Call: CallStaticVoidMethodV");
2576 STATS(jniinvokation();)
2577 (void)callIntegerMethod(0, methodID, TYPE_VOID, args);
2581 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2583 STATS(jniinvokation();)
2584 log_text("JNI-Call: CallStaticVoidMethodA");
2588 /* Accessing Static Fields ****************************************************/
2590 /* GetStaticFieldID ************************************************************
2592 Returns the field ID for a static field of a class. The field is
2593 specified by its name and signature. The GetStatic<type>Field and
2594 SetStatic<type>Field families of accessor functions use field IDs
2595 to retrieve static fields.
2597 *******************************************************************************/
2599 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2602 STATS(jniinvokation();)
2604 f = class_findfield(clazz,
2605 utf_new_char((char *) name),
2606 utf_new_char((char *) sig));
2609 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2615 /* GetStatic<type>Field ********************************************************
2617 This family of accessor routines returns the value of a static
2620 *******************************************************************************/
2622 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2624 STATS(jniinvokation();)
2626 if (!clazz->initialized)
2627 if (!initialize_class(clazz))
2630 return NewLocalRef(env, fieldID->value.a);
2634 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2636 STATS(jniinvokation();)
2638 if (!clazz->initialized)
2639 if (!initialize_class(clazz))
2642 return fieldID->value.i;
2646 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2648 STATS(jniinvokation();)
2650 if (!clazz->initialized)
2651 if (!initialize_class(clazz))
2654 return fieldID->value.i;
2658 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2660 STATS(jniinvokation();)
2662 if (!clazz->initialized)
2663 if (!initialize_class(clazz))
2666 return fieldID->value.i;
2670 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2672 STATS(jniinvokation();)
2674 if (!clazz->initialized)
2675 if (!initialize_class(clazz))
2678 return fieldID->value.i;
2682 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2684 STATS(jniinvokation();)
2686 if (!clazz->initialized)
2687 if (!initialize_class(clazz))
2690 return fieldID->value.i;
2694 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2696 STATS(jniinvokation();)
2698 if (!clazz->initialized)
2699 if (!initialize_class(clazz))
2702 return fieldID->value.l;
2706 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2708 STATS(jniinvokation();)
2710 if (!clazz->initialized)
2711 if (!initialize_class(clazz))
2714 return fieldID->value.f;
2718 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2720 STATS(jniinvokation();)
2722 if (!clazz->initialized)
2723 if (!initialize_class(clazz))
2726 return fieldID->value.d;
2730 /* SetStatic<type>Field *******************************************************
2732 This family of accessor routines sets the value of a static field
2735 *******************************************************************************/
2737 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2739 STATS(jniinvokation();)
2741 if (!clazz->initialized)
2742 if (!initialize_class(clazz))
2745 fieldID->value.a = value;
2749 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2751 STATS(jniinvokation();)
2753 if (!clazz->initialized)
2754 if (!initialize_class(clazz))
2757 fieldID->value.i = value;
2761 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2763 STATS(jniinvokation();)
2765 if (!clazz->initialized)
2766 if (!initialize_class(clazz))
2769 fieldID->value.i = value;
2773 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2775 STATS(jniinvokation();)
2777 if (!clazz->initialized)
2778 if (!initialize_class(clazz))
2781 fieldID->value.i = value;
2785 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2787 STATS(jniinvokation();)
2789 if (!clazz->initialized)
2790 if (!initialize_class(clazz))
2793 fieldID->value.i = value;
2797 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2799 STATS(jniinvokation();)
2801 if (!clazz->initialized)
2802 if (!initialize_class(clazz))
2805 fieldID->value.i = value;
2809 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2811 STATS(jniinvokation();)
2813 if (!clazz->initialized)
2814 if (!initialize_class(clazz))
2817 fieldID->value.l = value;
2821 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2823 STATS(jniinvokation();)
2825 if (!clazz->initialized)
2826 if (!initialize_class(clazz))
2829 fieldID->value.f = value;
2833 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2835 STATS(jniinvokation();)
2837 if (!clazz->initialized)
2838 if (!initialize_class(clazz))
2841 fieldID->value.d = value;
2845 /* String Operations **********************************************************/
2847 /* NewString *******************************************************************
2849 Create new java.lang.String object from an array of Unicode
2852 *******************************************************************************/
2854 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
2856 java_lang_String *s;
2860 STATS(jniinvokation();)
2862 s = (java_lang_String *) builtin_new(class_java_lang_String);
2863 a = builtin_newarray_char(len);
2865 /* javastring or characterarray could not be created */
2870 for (i = 0; i < len; i++)
2871 a->data[i] = buf[i];
2877 return (jstring) NewLocalRef(env, (jobject) s);
2881 static jchar emptyStringJ[]={0,0};
2883 /* GetStringLength *************************************************************
2885 Returns the length (the count of Unicode characters) of a Java
2888 *******************************************************************************/
2890 jsize GetStringLength(JNIEnv *env, jstring str)
2892 return ((java_lang_String *) str)->count;
2896 /******************** convertes javastring to u2-array ****************************/
2898 u2 *javastring_tou2(jstring so)
2900 java_lang_String *s;
2905 STATS(jniinvokation();)
2907 s = (java_lang_String *) so;
2917 /* allocate memory */
2919 stringbuffer = MNEW(u2, s->count + 1);
2923 for (i = 0; i < s->count; i++)
2924 stringbuffer[i] = a->data[s->offset + i];
2926 /* terminate string */
2928 stringbuffer[i] = '\0';
2930 return stringbuffer;
2934 /* GetStringChars **************************************************************
2936 Returns a pointer to the array of Unicode characters of the
2937 string. This pointer is valid until ReleaseStringchars() is called.
2939 *******************************************************************************/
2941 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2945 STATS(jniinvokation();)
2947 jc = javastring_tou2(str);
2959 return emptyStringJ;
2963 /* ReleaseStringChars **********************************************************
2965 Informs the VM that the native code no longer needs access to
2966 chars. The chars argument is a pointer obtained from string using
2969 *******************************************************************************/
2971 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2973 STATS(jniinvokation();)
2975 if (chars == emptyStringJ)
2978 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
2982 /* NewStringUTF ****************************************************************
2984 Constructs a new java.lang.String object from an array of UTF-8 characters.
2986 *******************************************************************************/
2988 jstring NewStringUTF(JNIEnv *env, const char *bytes)
2990 java_lang_String *s;
2992 STATS(jniinvokation();)
2994 s = javastring_new(utf_new_char(bytes));
2996 return (jstring) NewLocalRef(env, (jobject) s);
3000 /****************** returns the utf8 length in bytes of a string *******************/
3002 jsize GetStringUTFLength (JNIEnv *env, jstring string)
3004 java_lang_String *s = (java_lang_String*) string;
3005 STATS(jniinvokation();)
3007 return (jsize) u2_utflength(s->value->data, s->count);
3011 /* GetStringUTFChars ***********************************************************
3013 Returns a pointer to an array of UTF-8 characters of the
3014 string. This array is valid until it is released by
3015 ReleaseStringUTFChars().
3017 *******************************************************************************/
3019 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
3022 STATS(jniinvokation();)
3030 u = javastring_toutf((java_lang_String *) string, false);
3039 /* ReleaseStringUTFChars *******************************************************
3041 Informs the VM that the native code no longer needs access to
3042 utf. The utf argument is a pointer derived from string using
3043 GetStringUTFChars().
3045 *******************************************************************************/
3047 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
3049 STATS(jniinvokation();)
3051 /* XXX we don't release utf chars right now, perhaps that should be done
3052 later. Since there is always one reference the garbage collector will
3057 /* Array Operations ***********************************************************/
3059 /* GetArrayLength **************************************************************
3061 Returns the number of elements in the array.
3063 *******************************************************************************/
3065 jsize GetArrayLength(JNIEnv *env, jarray array)
3067 STATS(jniinvokation();)
3073 /* NewObjectArray **************************************************************
3075 Constructs a new array holding objects in class elementClass. All
3076 elements are initially set to initialElement.
3078 *******************************************************************************/
3080 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
3082 java_objectarray *oa;
3085 STATS(jniinvokation();)
3088 *exceptionptr = new_negativearraysizeexception();
3092 oa = builtin_anewarray(length, elementClass);
3097 /* set all elements to initialElement */
3099 for (i = 0; i < length; i++)
3100 oa->data[i] = initialElement;
3102 return (jobjectArray) NewLocalRef(env, (jobject) oa);
3106 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
3110 STATS(jniinvokation();)
3112 if (index >= array->header.size) {
3114 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3118 o = array->data[index];
3120 return NewLocalRef(env, o);
3124 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3126 STATS(jniinvokation();)
3127 if (index >= array->header.size)
3128 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3131 /* check if the class of value is a subclass of the element class of the array */
3132 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
3133 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3136 array->data[index] = val;
3141 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3143 java_booleanarray *ba;
3145 STATS(jniinvokation();)
3148 *exceptionptr = new_negativearraysizeexception();
3152 ba = builtin_newarray_boolean(len);
3154 return (jbooleanArray) NewLocalRef(env, (jobject) ba);
3158 jbyteArray NewByteArray(JNIEnv *env, jsize len)
3162 STATS(jniinvokation();)
3165 *exceptionptr = new_negativearraysizeexception();
3169 ba = builtin_newarray_byte(len);
3171 return (jbyteArray) NewLocalRef(env, (jobject) ba);
3175 jcharArray NewCharArray(JNIEnv *env, jsize len)
3179 STATS(jniinvokation();)
3182 *exceptionptr = new_negativearraysizeexception();
3186 ca = builtin_newarray_char(len);
3188 return (jcharArray) NewLocalRef(env, (jobject) ca);
3192 jshortArray NewShortArray(JNIEnv *env, jsize len)
3194 java_shortarray *sa;
3196 STATS(jniinvokation();)
3199 *exceptionptr = new_negativearraysizeexception();
3203 sa = builtin_newarray_short(len);
3205 return (jshortArray) NewLocalRef(env, (jobject) sa);
3209 jintArray NewIntArray(JNIEnv *env, jsize len)
3213 STATS(jniinvokation();)
3216 *exceptionptr = new_negativearraysizeexception();
3220 ia = builtin_newarray_int(len);
3222 return (jintArray) NewLocalRef(env, (jobject) ia);
3226 jlongArray NewLongArray(JNIEnv *env, jsize len)
3230 STATS(jniinvokation();)
3233 *exceptionptr = new_negativearraysizeexception();
3237 la = builtin_newarray_long(len);
3239 return (jlongArray) NewLocalRef(env, (jobject) la);
3243 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3245 java_floatarray *fa;
3247 STATS(jniinvokation();)
3250 *exceptionptr = new_negativearraysizeexception();
3254 fa = builtin_newarray_float(len);
3256 return (jfloatArray) NewLocalRef(env, (jobject) fa);
3260 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3262 java_doublearray *da;
3264 STATS(jniinvokation();)
3267 *exceptionptr = new_negativearraysizeexception();
3271 da = builtin_newarray_double(len);
3273 return (jdoubleArray) NewLocalRef(env, (jobject) da);
3277 /* Get<PrimitiveType>ArrayElements *********************************************
3279 A family of functions that returns the body of the primitive array.
3281 *******************************************************************************/
3283 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3286 STATS(jniinvokation();)
3289 *isCopy = JNI_FALSE;
3295 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3297 STATS(jniinvokation();)
3300 *isCopy = JNI_FALSE;
3306 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3308 STATS(jniinvokation();)
3311 *isCopy = JNI_FALSE;
3317 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3319 STATS(jniinvokation();)
3322 *isCopy = JNI_FALSE;
3328 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3330 STATS(jniinvokation();)
3333 *isCopy = JNI_FALSE;
3339 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3341 STATS(jniinvokation();)
3344 *isCopy = JNI_FALSE;
3350 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3352 STATS(jniinvokation();)
3355 *isCopy = JNI_FALSE;
3361 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3364 STATS(jniinvokation();)
3367 *isCopy = JNI_FALSE;
3373 /* Release<PrimitiveType>ArrayElements *****************************************
3375 A family of functions that informs the VM that the native code no
3376 longer needs access to elems. The elems argument is a pointer
3377 derived from array using the corresponding
3378 Get<PrimitiveType>ArrayElements() function. If necessary, this
3379 function copies back all changes made to elems to the original
3382 *******************************************************************************/
3384 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3385 jboolean *elems, jint mode)
3387 STATS(jniinvokation();)
3389 if (elems != array->data) {
3392 MCOPY(array->data, elems, jboolean, array->header.size);
3395 MCOPY(array->data, elems, jboolean, array->header.size);
3396 /* XXX TWISTI how should it be freed? */
3399 /* XXX TWISTI how should it be freed? */
3406 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
3409 STATS(jniinvokation();)
3411 if (elems != array->data) {
3414 MCOPY(array->data, elems, jboolean, array->header.size);
3417 MCOPY(array->data, elems, jboolean, array->header.size);
3418 /* XXX TWISTI how should it be freed? */
3421 /* XXX TWISTI how should it be freed? */
3428 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
3431 STATS(jniinvokation();)
3433 if (elems != array->data) {
3436 MCOPY(array->data, elems, jboolean, array->header.size);
3439 MCOPY(array->data, elems, jboolean, array->header.size);
3440 /* XXX TWISTI how should it be freed? */
3443 /* XXX TWISTI how should it be freed? */
3450 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
3453 STATS(jniinvokation();)
3455 if (elems != array->data) {
3458 MCOPY(array->data, elems, jboolean, array->header.size);
3461 MCOPY(array->data, elems, jboolean, array->header.size);
3462 /* XXX TWISTI how should it be freed? */
3465 /* XXX TWISTI how should it be freed? */
3472 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
3475 STATS(jniinvokation();)
3477 if (elems != array->data) {
3480 MCOPY(array->data, elems, jboolean, array->header.size);
3483 MCOPY(array->data, elems, jboolean, array->header.size);
3484 /* XXX TWISTI how should it be freed? */
3487 /* XXX TWISTI how should it be freed? */
3494 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
3497 STATS(jniinvokation();)
3499 if (elems != array->data) {
3502 MCOPY(array->data, elems, jboolean, array->header.size);
3505 MCOPY(array->data, elems, jboolean, array->header.size);
3506 /* XXX TWISTI how should it be freed? */
3509 /* XXX TWISTI how should it be freed? */
3516 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
3519 STATS(jniinvokation();)
3521 if (elems != array->data) {
3524 MCOPY(array->data, elems, jboolean, array->header.size);
3527 MCOPY(array->data, elems, jboolean, array->header.size);
3528 /* XXX TWISTI how should it be freed? */
3531 /* XXX TWISTI how should it be freed? */
3538 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3539 jdouble *elems, jint mode)
3541 STATS(jniinvokation();)
3543 if (elems != array->data) {
3546 MCOPY(array->data, elems, jboolean, array->header.size);
3549 MCOPY(array->data, elems, jboolean, array->header.size);
3550 /* XXX TWISTI how should it be freed? */
3553 /* XXX TWISTI how should it be freed? */
3560 /* Get<PrimitiveType>ArrayRegion **********************************************
3562 A family of functions that copies a region of a primitive array
3565 *******************************************************************************/
3567 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3568 jsize len, jboolean *buf)
3570 STATS(jniinvokation();)
3572 if (start < 0 || len < 0 || start + len > array->header.size)
3574 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3577 MCOPY(buf, &array->data[start], jboolean, len);
3581 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3584 STATS(jniinvokation();)
3586 if (start < 0 || len < 0 || start + len > array->header.size)
3588 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3591 MCOPY(buf, &array->data[start], jbyte, len);
3595 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3598 STATS(jniinvokation();)
3600 if (start < 0 || len < 0 || start + len > array->header.size)
3602 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3605 MCOPY(buf, &array->data[start], jchar, len);
3609 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3610 jsize len, jshort *buf)
3612 STATS(jniinvokation();)
3614 if (start < 0 || len < 0 || start + len > array->header.size)
3616 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3619 MCOPY(buf, &array->data[start], jshort, len);
3623 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3626 STATS(jniinvokation();)
3628 if (start < 0 || len < 0 || start + len > array->header.size)
3630 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3633 MCOPY(buf, &array->data[start], jint, len);
3637 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
3640 STATS(jniinvokation();)
3642 if (start < 0 || len < 0 || start + len > array->header.size)
3644 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3647 MCOPY(buf, &array->data[start], jlong, len);
3651 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3652 jsize len, jfloat *buf)
3654 STATS(jniinvokation();)
3656 if (start < 0 || len < 0 || start + len > array->header.size)
3658 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3661 MCOPY(buf, &array->data[start], jfloat, len);
3665 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3666 jsize len, jdouble *buf)
3668 STATS(jniinvokation();)
3670 if (start < 0 || len < 0 || start+len>array->header.size)
3672 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3675 MCOPY(buf, &array->data[start], jdouble, len);
3679 /* Set<PrimitiveType>ArrayRegion **********************************************
3681 A family of functions that copies back a region of a primitive
3682 array from a buffer.
3684 *******************************************************************************/
3686 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3687 jsize len, jboolean *buf)
3689 STATS(jniinvokation();)
3691 if (start < 0 || len < 0 || start + len > array->header.size)
3693 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3696 MCOPY(&array->data[start], buf, jboolean, len);
3700 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3703 STATS(jniinvokation();)
3705 if (start < 0 || len < 0 || start + len > array->header.size)
3707 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3710 MCOPY(&array->data[start], buf, jbyte, len);
3714 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3717 STATS(jniinvokation();)
3719 if (start < 0 || len < 0 || start + len > array->header.size)
3721 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3724 MCOPY(&array->data[start], buf, jchar, len);
3729 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3730 jsize len, jshort *buf)
3732 STATS(jniinvokation();)
3734 if (start < 0 || len < 0 || start + len > array->header.size)
3736 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3739 MCOPY(&array->data[start], buf, jshort, len);
3743 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3746 STATS(jniinvokation();)
3748 if (start < 0 || len < 0 || start + len > array->header.size)
3750 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3753 MCOPY(&array->data[start], buf, jint, len);
3758 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
3761 STATS(jniinvokation();)
3763 if (start < 0 || len < 0 || start + len > array->header.size)
3765 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3768 MCOPY(&array->data[start], buf, jlong, len);
3773 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3774 jsize len, jfloat *buf)
3776 STATS(jniinvokation();)
3778 if (start < 0 || len < 0 || start + len > array->header.size)
3780 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3783 MCOPY(&array->data[start], buf, jfloat, len);
3788 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3789 jsize len, jdouble *buf)
3791 STATS(jniinvokation();)
3793 if (start < 0 || len < 0 || start + len > array->header.size)
3795 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3798 MCOPY(&array->data[start], buf, jdouble, len);
3802 /* Registering Native Methods *************************************************/
3804 /* RegisterNatives *************************************************************
3806 Registers native methods with the class specified by the clazz
3807 argument. The methods parameter specifies an array of
3808 JNINativeMethod structures that contain the names, signatures, and
3809 function pointers of the native methods. The nMethods parameter
3810 specifies the number of native methods in the array.
3812 *******************************************************************************/
3814 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
3817 STATS(jniinvokation();)
3819 log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
3825 /* UnregisterNatives ***********************************************************
3827 Unregisters native methods of a class. The class goes back to the
3828 state before it was linked or registered with its native method
3831 This function should not be used in normal native code. Instead, it
3832 provides special programs a way to reload and relink native
3835 *******************************************************************************/
3837 jint UnregisterNatives(JNIEnv *env, jclass clazz)
3839 STATS(jniinvokation();)
3841 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3843 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3849 /* Monitor Operations *********************************************************/
3851 /* MonitorEnter ****************************************************************
3853 Enters the monitor associated with the underlying Java object
3856 *******************************************************************************/
3858 jint MonitorEnter(JNIEnv *env, jobject obj)
3860 STATS(jniinvokation();)
3863 *exceptionptr = new_nullpointerexception();
3867 #if defined(USE_THREADS)
3868 builtin_monitorenter(obj);
3875 /* MonitorExit *****************************************************************
3877 The current thread must be the owner of the monitor associated with
3878 the underlying Java object referred to by obj. The thread
3879 decrements the counter indicating the number of times it has
3880 entered this monitor. If the value of the counter becomes zero, the
3881 current thread releases the monitor.
3883 *******************************************************************************/
3885 jint MonitorExit(JNIEnv *env, jobject obj)
3887 STATS(jniinvokation();)
3889 *exceptionptr = new_nullpointerexception();
3893 #if defined(USE_THREADS)
3894 builtin_monitorexit(obj);
3901 /* JavaVM Interface ***********************************************************/
3903 /* GetJavaVM *******************************************************************
3905 Returns the Java VM interface (used in the Invocation API)
3906 associated with the current thread. The result is placed at the
3907 location pointed to by the second argument, vm.
3909 *******************************************************************************/
3911 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
3913 STATS(jniinvokation();)
3920 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3922 STATS(jniinvokation();)
3923 log_text("JNI-Call: GetStringRegion");
3927 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3929 STATS(jniinvokation();)
3930 log_text("JNI-Call: GetStringUTFRegion");
3934 /* GetPrimitiveArrayCritical ***************************************************
3936 Obtain a direct pointer to array elements.
3938 *******************************************************************************/
3940 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3942 /* do the same as Kaffe does */
3944 return GetByteArrayElements(env, (jbyteArray) array, isCopy);
3948 /* ReleasePrimitiveArrayCritical ***********************************************
3950 No specific documentation.
3952 *******************************************************************************/
3954 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
3957 STATS(jniinvokation();)
3959 /* do the same as Kaffe does */
3961 ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
3965 /* GetStringCritical ***********************************************************
3967 The semantics of these two functions are similar to the existing
3968 Get/ReleaseStringChars functions.
3970 *******************************************************************************/
3972 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
3974 STATS(jniinvokation();)
3976 return GetStringChars(env, string, isCopy);
3980 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
3982 STATS(jniinvokation();)
3984 ReleaseStringChars(env, string, cstring);
3988 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3990 STATS(jniinvokation();)
3991 log_text("JNI-Call: NewWeakGlobalRef");
3997 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
3999 STATS(jniinvokation();)
4000 log_text("JNI-Call: DeleteWeakGlobalRef");
4006 /* NewGlobalRef ****************************************************************
4008 Creates a new global reference to the object referred to by the obj
4011 *******************************************************************************/
4013 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4015 java_lang_Integer *refcount;
4016 java_objectheader *newval;
4018 STATS(jniinvokation();)
4020 #if defined(USE_THREADS)
4021 builtin_monitorenter(*global_ref_table);
4024 refcount = (java_lang_Integer *)
4025 asm_calljavafunction(getmid, *global_ref_table, lobj, NULL, NULL);
4027 if (refcount == NULL) {
4028 newval = native_new_and_init_int(class_java_lang_Integer, 1);
4030 if (newval == NULL) {
4031 #if defined(USE_THREADS)
4032 builtin_monitorexit(*global_ref_table);
4037 asm_calljavafunction(putmid, *global_ref_table, lobj, newval, NULL);
4040 /* we can access the object itself, as we are in a
4041 synchronized section */
4046 #if defined(USE_THREADS)
4047 builtin_monitorexit(*global_ref_table);
4054 /* DeleteGlobalRef *************************************************************
4056 Deletes the global reference pointed to by globalRef.
4058 *******************************************************************************/
4060 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
4062 java_lang_Integer *refcount;
4065 STATS(jniinvokation();)
4067 #if defined(USE_THREADS)
4068 builtin_monitorenter(*global_ref_table);
4071 refcount = (java_lang_Integer *)
4072 asm_calljavafunction(getmid, *global_ref_table, globalRef, NULL, NULL);
4074 if (refcount == NULL) {
4075 log_text("JNI-DeleteGlobalRef: unable to find global reference");
4079 /* we can access the object itself, as we are in a synchronized
4082 val = refcount->value - 1;
4085 asm_calljavafunction(removemid, *global_ref_table, refcount, NULL,
4089 /* we do not create a new object, but set the new value into
4092 refcount->value = val;
4095 #if defined(USE_THREADS)
4096 builtin_monitorexit(*global_ref_table);
4101 /* ExceptionCheck **************************************************************
4103 Returns JNI_TRUE when there is a pending exception; otherwise,
4106 *******************************************************************************/
4108 jboolean ExceptionCheck(JNIEnv *env)
4110 STATS(jniinvokation();)
4111 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
4115 /* New JNI 1.4 functions ******************************************************/
4117 /* NewDirectByteBuffer *********************************************************
4119 Allocates and returns a direct java.nio.ByteBuffer referring to the
4120 block of memory starting at the memory address address and
4121 extending capacity bytes.
4123 *******************************************************************************/
4125 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
4127 java_nio_DirectByteBufferImpl *nbuf;
4128 #if SIZEOF_VOID_P == 8
4129 gnu_classpath_Pointer64 *paddress;
4131 gnu_classpath_Pointer32 *paddress;
4134 STATS(jniinvokation();)
4136 log_text("JNI-NewDirectByteBuffer: called");
4138 /* allocate a java.nio.DirectByteBufferImpl object */
4140 if (!(nbuf = (java_nio_DirectByteBufferImpl *) builtin_new(class_java_nio_DirectByteBufferImpl)))
4143 /* alocate a gnu.classpath.Pointer{32,64} object */
4145 #if SIZEOF_VOID_P == 8
4146 if (!(paddress = (gnu_classpath_Pointer64 *) builtin_new(class_gnu_classpath_Pointer64)))
4148 if (!(paddress = (gnu_classpath_Pointer32 *) builtin_new(class_gnu_classpath_Pointer32)))
4152 /* fill gnu.classpath.Pointer{32,64} with address */
4154 paddress->data = (ptrint) address;
4156 /* fill java.nio.Buffer object */
4158 nbuf->cap = (s4) capacity;
4159 nbuf->limit = (s4) capacity;
4161 nbuf->address = (gnu_classpath_Pointer *) paddress;
4163 /* add local reference and return the value */
4165 return NewLocalRef(env, (jobject) nbuf);
4169 /* GetDirectBufferAddress ******************************************************
4171 Fetches and returns the starting address of the memory region
4172 referenced by the given direct java.nio.Buffer.
4174 *******************************************************************************/
4176 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
4178 java_nio_DirectByteBufferImpl *nbuf;
4179 #if SIZEOF_VOID_P == 8
4180 gnu_classpath_Pointer64 *address;
4182 gnu_classpath_Pointer32 *address;
4185 STATS(jniinvokation();)
4188 if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
4192 nbuf = (java_nio_DirectByteBufferImpl *) buf;
4194 #if SIZEOF_VOID_P == 8
4195 address = (gnu_classpath_Pointer64 *) nbuf->address;
4197 address = (gnu_classpath_Pointer32 *) nbuf->address;
4200 return (void *) address->data;
4204 /* GetDirectBufferCapacity *****************************************************
4206 Fetches and returns the capacity in bytes of the memory region
4207 referenced by the given direct java.nio.Buffer.
4209 *******************************************************************************/
4211 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
4213 java_nio_Buffer *nbuf;
4215 STATS(jniinvokation();)
4220 nbuf = (java_nio_Buffer *) buf;
4222 return (jlong) nbuf->cap;
4226 jint DestroyJavaVM(JavaVM *vm)
4228 STATS(jniinvokation();)
4229 log_text("DestroyJavaVM called");
4235 /* AttachCurrentThread *********************************************************
4237 Attaches the current thread to a Java VM. Returns a JNI interface
4238 pointer in the JNIEnv argument.
4240 Trying to attach a thread that is already attached is a no-op.
4242 A native thread cannot be attached simultaneously to two Java VMs.
4244 When a thread is attached to the VM, the context class loader is
4245 the bootstrap loader.
4247 *******************************************************************************/
4249 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
4251 STATS(jniinvokation();)
4253 log_text("AttachCurrentThread called");
4255 #if !defined(HAVE___THREAD)
4256 /* cacao_thread_attach();*/
4258 #error "No idea how to implement that. Perhaps Stefan knows"
4267 jint DetachCurrentThread(JavaVM *vm)
4269 STATS(jniinvokation();)
4270 log_text("DetachCurrentThread called");
4276 /* GetEnv **********************************************************************
4278 If the current thread is not attached to the VM, sets *env to NULL,
4279 and returns JNI_EDETACHED. If the specified version is not
4280 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
4281 sets *env to the appropriate interface, and returns JNI_OK.
4283 *******************************************************************************/
4285 jint GetEnv(JavaVM *vm, void **env, jint version)
4287 STATS(jniinvokation();)
4289 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4290 if (thread_getself() == NULL) {
4293 return JNI_EDETACHED;
4297 if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
4298 (version == JNI_VERSION_1_4)) {
4304 #if defined(ENABLE_JVMTI)
4305 if (version == JVMTI_VERSION_1_0) {
4306 *env = (void *) new_jvmtienv();
4315 return JNI_EVERSION;
4320 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4322 STATS(jniinvokation();)
4323 log_text("AttachCurrentThreadAsDaemon called");
4329 /* JNI invocation table *******************************************************/
4331 const struct JNIInvokeInterface JNI_JavaVMTable = {
4337 AttachCurrentThread,
4338 DetachCurrentThread,
4340 AttachCurrentThreadAsDaemon
4344 /* JNI function table *********************************************************/
4346 struct JNINativeInterface JNI_JNIEnvTable = {
4355 &FromReflectedMethod,
4356 &FromReflectedField,
4376 &EnsureLocalCapacity,
4392 &CallBooleanMethodV,
4393 &CallBooleanMethodA,
4419 &CallNonvirtualObjectMethod,
4420 &CallNonvirtualObjectMethodV,
4421 &CallNonvirtualObjectMethodA,
4422 &CallNonvirtualBooleanMethod,
4423 &CallNonvirtualBooleanMethodV,
4424 &CallNonvirtualBooleanMethodA,
4425 &CallNonvirtualByteMethod,
4426 &CallNonvirtualByteMethodV,
4427 &CallNonvirtualByteMethodA,
4428 &CallNonvirtualCharMethod,
4429 &CallNonvirtualCharMethodV,
4430 &CallNonvirtualCharMethodA,
4431 &CallNonvirtualShortMethod,
4432 &CallNonvirtualShortMethodV,
4433 &CallNonvirtualShortMethodA,
4434 &CallNonvirtualIntMethod,
4435 &CallNonvirtualIntMethodV,
4436 &CallNonvirtualIntMethodA,
4437 &CallNonvirtualLongMethod,
4438 &CallNonvirtualLongMethodV,
4439 &CallNonvirtualLongMethodA,
4440 &CallNonvirtualFloatMethod,
4441 &CallNonvirtualFloatMethodV,
4442 &CallNonvirtualFloatMethodA,
4443 &CallNonvirtualDoubleMethod,
4444 &CallNonvirtualDoubleMethodV,
4445 &CallNonvirtualDoubleMethodA,
4446 &CallNonvirtualVoidMethod,
4447 &CallNonvirtualVoidMethodV,
4448 &CallNonvirtualVoidMethodA,
4473 &CallStaticObjectMethod,
4474 &CallStaticObjectMethodV,
4475 &CallStaticObjectMethodA,
4476 &CallStaticBooleanMethod,
4477 &CallStaticBooleanMethodV,
4478 &CallStaticBooleanMethodA,
4479 &CallStaticByteMethod,
4480 &CallStaticByteMethodV,
4481 &CallStaticByteMethodA,
4482 &CallStaticCharMethod,
4483 &CallStaticCharMethodV,
4484 &CallStaticCharMethodA,
4485 &CallStaticShortMethod,
4486 &CallStaticShortMethodV,
4487 &CallStaticShortMethodA,
4488 &CallStaticIntMethod,
4489 &CallStaticIntMethodV,
4490 &CallStaticIntMethodA,
4491 &CallStaticLongMethod,
4492 &CallStaticLongMethodV,
4493 &CallStaticLongMethodA,
4494 &CallStaticFloatMethod,
4495 &CallStaticFloatMethodV,
4496 &CallStaticFloatMethodA,
4497 &CallStaticDoubleMethod,
4498 &CallStaticDoubleMethodV,
4499 &CallStaticDoubleMethodA,
4500 &CallStaticVoidMethod,
4501 &CallStaticVoidMethodV,
4502 &CallStaticVoidMethodA,
4506 &GetStaticObjectField,
4507 &GetStaticBooleanField,
4508 &GetStaticByteField,
4509 &GetStaticCharField,
4510 &GetStaticShortField,
4512 &GetStaticLongField,
4513 &GetStaticFloatField,
4514 &GetStaticDoubleField,
4515 &SetStaticObjectField,
4516 &SetStaticBooleanField,
4517 &SetStaticByteField,
4518 &SetStaticCharField,
4519 &SetStaticShortField,
4521 &SetStaticLongField,
4522 &SetStaticFloatField,
4523 &SetStaticDoubleField,
4528 &ReleaseStringChars,
4531 &GetStringUTFLength,
4533 &ReleaseStringUTFChars,
4538 &GetObjectArrayElement,
4539 &SetObjectArrayElement,
4550 &GetBooleanArrayElements,
4551 &GetByteArrayElements,
4552 &GetCharArrayElements,
4553 &GetShortArrayElements,
4554 &GetIntArrayElements,
4555 &GetLongArrayElements,
4556 &GetFloatArrayElements,
4557 &GetDoubleArrayElements,
4559 &ReleaseBooleanArrayElements,
4560 &ReleaseByteArrayElements,
4561 &ReleaseCharArrayElements,
4562 &ReleaseShortArrayElements,
4563 &ReleaseIntArrayElements,
4564 &ReleaseLongArrayElements,
4565 &ReleaseFloatArrayElements,
4566 &ReleaseDoubleArrayElements,
4568 &GetBooleanArrayRegion,
4569 &GetByteArrayRegion,
4570 &GetCharArrayRegion,
4571 &GetShortArrayRegion,
4573 &GetLongArrayRegion,
4574 &GetFloatArrayRegion,
4575 &GetDoubleArrayRegion,
4576 &SetBooleanArrayRegion,
4577 &SetByteArrayRegion,
4578 &SetCharArrayRegion,
4579 &SetShortArrayRegion,
4581 &SetLongArrayRegion,
4582 &SetFloatArrayRegion,
4583 &SetDoubleArrayRegion,
4593 /* new JNI 1.2 functions */
4596 &GetStringUTFRegion,
4598 &GetPrimitiveArrayCritical,
4599 &ReleasePrimitiveArrayCritical,
4602 &ReleaseStringCritical,
4605 &DeleteWeakGlobalRef,
4609 /* new JNI 1.4 functions */
4611 &NewDirectByteBuffer,
4612 &GetDirectBufferAddress,
4613 &GetDirectBufferCapacity
4617 /* Invocation API Functions ***************************************************/
4619 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4621 Returns a default configuration for the Java VM.
4623 *******************************************************************************/
4625 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4627 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4629 /* GNU classpath currently supports JNI 1.2 */
4631 _vm_args->version = JNI_VERSION_1_2;
4637 /* JNI_GetCreatedJavaVMs *******************************************************
4639 Returns all Java VMs that have been created. Pointers to VMs are written in
4640 the buffer vmBuf in the order they are created. At most bufLen number of
4641 entries will be written. The total number of created VMs is returned in
4644 *******************************************************************************/
4646 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4648 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4654 /* JNI_CreateJavaVM ************************************************************
4656 Loads and initializes a Java VM. The current thread becomes the main thread.
4657 Sets the env argument to the JNI interface pointer of the main thread.
4659 *******************************************************************************/
4661 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4663 const struct JNIInvokeInterface *vm;
4664 struct JNINativeInterface *env;
4666 vm = &JNI_JavaVMTable;
4667 env = &JNI_JNIEnvTable;
4669 *p_vm = (JavaVM *) vm;
4670 *p_env = (JNIEnv *) env;
4676 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4677 jobject obj, java_objectarray *params)
4684 if (methodID == 0) {
4685 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
4689 argcount = methodID->parseddesc->paramcount;
4690 paramcount = argcount;
4692 /* if method is non-static, remove the `this' pointer */
4694 if (!(methodID->flags & ACC_STATIC))
4697 /* the method is an instance method the obj has to be an instance of the
4698 class the method belongs to. For static methods the obj parameter
4701 if (!(methodID->flags & ACC_STATIC) && obj &&
4702 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4704 new_exception_message(string_java_lang_IllegalArgumentException,
4705 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4709 if (((params == NULL) && (paramcount != 0)) ||
4710 (params && (params->header.size != paramcount))) {
4712 new_exception(string_java_lang_IllegalArgumentException);
4717 if (!(methodID->flags & ACC_STATIC) && !obj) {
4719 new_exception_message(string_java_lang_NullPointerException,
4720 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4724 if ((methodID->flags & ACC_STATIC) && (obj))
4728 if ((methodID->flags & ACC_ABSTRACT) ||
4729 (methodID->class->flags & ACC_INTERFACE)) {
4730 methodID = get_virtual(obj, methodID);
4734 blk = MNEW(jni_callblock, argcount);
4736 if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4740 switch (methodID->parseddesc->returntype.decltype) {
4742 (void) asm_calljavafunction2(methodID, argcount,
4743 argcount * sizeof(jni_callblock),
4745 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4748 case PRIMITIVETYPE_INT: {
4750 i = asm_calljavafunction2int(methodID, argcount,
4751 argcount * sizeof(jni_callblock),
4754 o = native_new_and_init_int(class_java_lang_Integer, i);
4758 case PRIMITIVETYPE_BYTE: {
4760 i = asm_calljavafunction2int(methodID, argcount,
4761 argcount * sizeof(jni_callblock),
4764 /* o = native_new_and_init_int(class_java_lang_Byte, i); */
4765 o = builtin_new(class_java_lang_Byte);
4768 class_resolvemethod(o->vftbl->class,
4775 case PRIMITIVETYPE_CHAR: {
4777 intVal = asm_calljavafunction2int(methodID,
4779 argcount * sizeof(jni_callblock),
4781 o = builtin_new(class_java_lang_Character);
4784 class_resolvemethod(o->vftbl->class,
4791 case PRIMITIVETYPE_SHORT: {
4793 intVal = asm_calljavafunction2int(methodID,
4795 argcount * sizeof(jni_callblock),
4797 o = builtin_new(class_java_lang_Short);
4800 class_resolvemethod(o->vftbl->class,
4807 case PRIMITIVETYPE_BOOLEAN: {
4809 intVal = asm_calljavafunction2int(methodID,
4811 argcount * sizeof(jni_callblock),
4813 o = builtin_new(class_java_lang_Boolean);
4816 class_resolvemethod(o->vftbl->class,
4823 case PRIMITIVETYPE_LONG: {
4825 longVal = asm_calljavafunction2long(methodID,
4827 argcount * sizeof(jni_callblock),
4829 o = builtin_new(class_java_lang_Long);
4832 class_resolvemethod(o->vftbl->class,
4839 case PRIMITIVETYPE_FLOAT: {
4841 floatVal = asm_calljavafunction2float(methodID,
4843 argcount * sizeof(jni_callblock),
4845 o = builtin_new(class_java_lang_Float);
4848 class_resolvemethod(o->vftbl->class,
4855 case PRIMITIVETYPE_DOUBLE: {
4857 doubleVal = asm_calljavafunction2double(methodID,
4859 argcount * sizeof(jni_callblock),
4861 o = builtin_new(class_java_lang_Double);
4864 class_resolvemethod(o->vftbl->class,
4872 o = asm_calljavafunction2(methodID, argcount,
4873 argcount * sizeof(jni_callblock), blk);
4877 /* if this happens the exception has already been set by */
4878 /* fill_callblock_from_objectarray */
4880 MFREE(blk, jni_callblock, argcount);
4881 return (jobject *) 0;
4884 MFREE(blk, jni_callblock, argcount);
4886 if (*exceptionptr) {
4887 java_objectheader *cause;
4889 cause = *exceptionptr;
4891 /* clear exception pointer, we are calling JIT code again */
4893 *exceptionptr = NULL;
4896 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
4897 (java_lang_Throwable *) cause);
4900 return (jobject *) o;
4905 * These are local overrides for various environment variables in Emacs.
4906 * Please do not remove this and leave it at the end of the file, where
4907 * Emacs will automagically detect them.
4908 * ---------------------------------------------------------------------
4911 * indent-tabs-mode: t