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 3434 2005-10-13 16:10:12Z twisti $
45 #include "mm/memory.h"
46 #include "native/jni.h"
47 #include "native/native.h"
49 #include "native/include/gnu_classpath_Pointer.h"
51 #if SIZEOF_VOID_P == 8
52 # include "native/include/gnu_classpath_Pointer64.h"
54 # include "native/include/gnu_classpath_Pointer32.h"
57 #include "native/include/java_lang_Object.h"
58 #include "native/include/java_lang_Byte.h"
59 #include "native/include/java_lang_Character.h"
60 #include "native/include/java_lang_Short.h"
61 #include "native/include/java_lang_Integer.h"
62 #include "native/include/java_lang_Boolean.h"
63 #include "native/include/java_lang_Long.h"
64 #include "native/include/java_lang_Float.h"
65 #include "native/include/java_lang_Double.h"
66 #include "native/include/java_lang_Throwable.h"
67 #include "native/include/java_lang_reflect_Method.h"
68 #include "native/include/java_lang_reflect_Constructor.h"
69 #include "native/include/java_lang_reflect_Field.h"
71 #include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
72 #include "native/include/java_lang_VMClass.h"
73 #include "native/include/java_lang_VMClassLoader.h"
74 #include "native/include/java_nio_Buffer.h"
75 #include "native/include/java_nio_DirectByteBufferImpl.h"
77 #if defined(ENABLE_JVMTI)
78 # include "native/jvmti/jvmti.h"
81 #if defined(USE_THREADS)
82 # if defined(NATIVE_THREADS)
83 # include "threads/native/threads.h"
85 # include "threads/green/threads.h"
89 #include "toolbox/logging.h"
90 #include "vm/builtin.h"
91 #include "vm/exceptions.h"
92 #include "vm/global.h"
93 #include "vm/initialize.h"
94 #include "vm/loader.h"
95 #include "vm/options.h"
96 #include "vm/resolve.h"
97 #include "vm/statistics.h"
98 #include "vm/stringlocal.h"
99 #include "vm/tables.h"
100 #include "vm/jit/asmpart.h"
101 #include "vm/jit/jit.h"
102 #include "vm/statistics.h"
105 /* XXX TWISTI hack: define it extern so they can be found in this file */
107 extern const struct JNIInvokeInterface JNI_JavaVMTable;
108 extern struct JNINativeInterface JNI_JNIEnvTable;
110 /* pointers to VM and the environment needed by GetJavaVM and GetEnv */
112 static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
113 void *ptr_env = (void*) &JNI_JNIEnvTable;
116 #define PTR_TO_ITEM(ptr) ((u8)(size_t)(ptr))
118 /* global variables ***********************************************************/
120 /* global reference table *****************************************************/
122 static java_objectheader **global_ref_table;
124 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
125 static classinfo *ihmclass = NULL;
126 static methodinfo *putmid = NULL;
127 static methodinfo *getmid = NULL;
128 static methodinfo *removemid = NULL;
131 /* direct buffer stuff ********************************************************/
133 static utf *utf_java_nio_DirectByteBufferImpl;
134 #if SIZEOF_VOID_P == 8
135 static utf *utf_gnu_classpath_Pointer64;
137 static utf *utf_gnu_classpath_Pointer32;
140 static classinfo *class_java_nio_DirectByteBufferImpl;
141 #if SIZEOF_VOID_P == 8
142 static classinfo *class_gnu_classpath_Pointer64;
144 static classinfo *class_gnu_classpath_Pointer32;
148 /* local reference table ******************************************************/
150 #if defined(USE_THREADS)
151 #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 */
1186 /* keep compiler happy */
1192 /* EnsureLocalCapacity *********************************************************
1194 Ensures that at least a given number of local references can be
1195 created in the current thread
1197 *******************************************************************************/
1199 jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
1201 localref_table *lrt;
1203 STATS(jniinvokation();)
1205 /* get local reference table (thread specific) */
1207 lrt = LOCALREFTABLE;
1209 /* check if capacity elements are available in the local references table */
1211 if ((lrt->used + capacity) > lrt->capacity) {
1212 *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
1220 /* AllocObject *****************************************************************
1222 Allocates a new Java object without invoking any of the
1223 constructors for the object. Returns a reference to the object.
1225 *******************************************************************************/
1227 jobject AllocObject(JNIEnv *env, jclass clazz)
1229 java_objectheader *o;
1231 STATS(jniinvokation();)
1233 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1235 new_exception_utfmessage(string_java_lang_InstantiationException,
1240 o = builtin_new(clazz);
1242 return NewLocalRef(env, o);
1246 /* NewObject *******************************************************************
1248 Programmers place all arguments that are to be passed to the
1249 constructor immediately following the methodID
1250 argument. NewObject() accepts these arguments and passes them to
1251 the Java method that the programmer wishes to invoke.
1253 *******************************************************************************/
1255 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1257 java_objectheader *o;
1260 STATS(jniinvokation();)
1264 o = builtin_new(clazz);
1269 /* call constructor */
1271 va_start(ap, methodID);
1272 cacao_jni_CallVoidMethod(o, methodID, ap);
1275 return NewLocalRef(env, o);
1279 /***********************************************************************************
1281 Constructs a new Java object
1282 arguments that are to be passed to the constructor are placed in va_list args
1284 ***********************************************************************************/
1286 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1288 STATS(jniinvokation();)
1290 log_text("JNI-Call: NewObjectV: IMPLEMENT ME!");
1292 return NewLocalRef(env, NULL);
1296 /***********************************************************************************
1298 Constructs a new Java object
1299 arguments that are to be passed to the constructor are placed in
1300 args array of jvalues
1302 ***********************************************************************************/
1304 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1306 STATS(jniinvokation();)
1308 log_text("JNI-Call: NewObjectA: IMPLEMENT ME!");
1310 return NewLocalRef(env, NULL);
1314 /* GetObjectClass **************************************************************
1316 Returns the class of an object.
1318 *******************************************************************************/
1320 jclass GetObjectClass(JNIEnv *env, jobject obj)
1323 STATS(jniinvokation();)
1325 if (!obj || !obj->vftbl)
1328 c = obj->vftbl->class;
1329 use_class_as_object(c);
1334 /* IsInstanceOf ****************************************************************
1336 Tests whether an object is an instance of a class.
1338 *******************************************************************************/
1340 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1342 STATS(jniinvokation();)
1344 return Java_java_lang_VMClass_isInstance(env,
1346 (java_lang_Class *) clazz,
1347 (java_lang_Object *) obj);
1351 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1353 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1355 java_lang_reflect_Field *f;
1357 jfieldID fid; /* the JNI-fieldid of the wrapping object */
1358 STATS(jniinvokation();)
1359 /*log_text("JNI-Call: FromReflectedField");*/
1361 f=(java_lang_reflect_Field *)field;
1363 c=(classinfo*)(f->declaringClass);
1364 if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1365 /*this usually means a severe internal cacao error or somebody
1366 tempered around with the reflected method*/
1367 log_text("error illegal slot for field in class(FromReflectedField)");
1370 fid=&(c->fields[f->slot]);
1375 /**********************************************************************************
1377 converts a method ID to a java.lang.reflect.Method or
1378 java.lang.reflect.Constructor object
1380 **********************************************************************************/
1382 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1384 log_text("JNI-Call: ToReflectedMethod");
1385 STATS(jniinvokation();)
1391 /* GetMethodID *****************************************************************
1393 returns the method ID for an instance method
1395 *******************************************************************************/
1397 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1401 STATS(jniinvokation();)
1403 m = class_resolvemethod(clazz,
1404 utf_new_char((char *) name),
1405 utf_new_char((char *) sig));
1407 if (!m || (m->flags & ACC_STATIC)) {
1409 new_exception_message(string_java_lang_NoSuchMethodError, name);
1418 /******************** JNI-functions for calling instance methods ******************/
1420 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1422 java_objectheader* ret;
1425 STATS(jniinvokation();)
1427 va_start(vaargs, methodID);
1428 ret = callObjectMethod(obj, methodID, vaargs);
1431 return NewLocalRef(env, ret);
1435 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1437 java_objectheader* ret;
1439 STATS(jniinvokation();)
1441 ret = callObjectMethod(obj, methodID, args);
1443 return NewLocalRef(env, ret);
1447 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1449 STATS(jniinvokation();)
1451 log_text("JNI-Call: CallObjectMethodA: IMPLEMENT ME!");
1453 return NewLocalRef(env, NULL);
1459 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1463 STATS(jniinvokation();)
1465 /* log_text("JNI-Call: CallBooleanMethod");*/
1467 va_start(vaargs,methodID);
1468 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1474 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1476 STATS(jniinvokation();)
1478 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
1482 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1484 STATS(jniinvokation();)
1485 log_text("JNI-Call: CallBooleanMethodA");
1490 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1494 STATS(jniinvokation();)
1496 /* log_text("JNI-Call: CallVyteMethod");*/
1498 va_start(vaargs,methodID);
1499 ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
1505 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1507 /* log_text("JNI-Call: CallByteMethodV");*/
1508 STATS(jniinvokation();)
1510 return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
1514 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1516 log_text("JNI-Call: CallByteMethodA");
1517 STATS(jniinvokation();)
1523 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1527 STATS(jniinvokation();)
1529 /* log_text("JNI-Call: CallCharMethod");*/
1531 va_start(vaargs,methodID);
1532 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
1539 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1541 STATS(jniinvokation();)
1543 /* log_text("JNI-Call: CallCharMethodV");*/
1544 return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
1548 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1550 STATS(jniinvokation();)
1552 log_text("JNI-Call: CallCharMethodA");
1558 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1562 STATS(jniinvokation();)
1564 /* log_text("JNI-Call: CallShortMethod");*/
1566 va_start(vaargs, methodID);
1567 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
1574 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1576 STATS(jniinvokation();)
1577 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
1581 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1583 STATS(jniinvokation();)
1584 log_text("JNI-Call: CallShortMethodA");
1591 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1595 STATS(jniinvokation();)
1597 va_start(vaargs,methodID);
1598 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
1605 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1607 STATS(jniinvokation();)
1608 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
1612 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1614 STATS(jniinvokation();)
1615 log_text("JNI-Call: CallIntMethodA");
1622 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1626 STATS(jniinvokation();)
1628 va_start(vaargs,methodID);
1629 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1636 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1638 STATS(jniinvokation();)
1639 return callLongMethod(obj,get_virtual(obj, methodID),args);
1643 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1645 STATS(jniinvokation();)
1646 log_text("JNI-Call: CallLongMethodA");
1653 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1658 STATS(jniinvokation();)
1659 /* log_text("JNI-Call: CallFloatMethod");*/
1661 va_start(vaargs,methodID);
1662 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
1669 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1671 STATS(jniinvokation();)
1672 log_text("JNI-Call: CallFloatMethodV");
1673 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
1677 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1679 STATS(jniinvokation();)
1680 log_text("JNI-Call: CallFloatMethodA");
1687 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1691 STATS(jniinvokation();)
1693 /* log_text("JNI-Call: CallDoubleMethod");*/
1695 va_start(vaargs,methodID);
1696 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
1703 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1705 STATS(jniinvokation();)
1706 log_text("JNI-Call: CallDoubleMethodV");
1707 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
1711 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1713 STATS(jniinvokation();)
1714 log_text("JNI-Call: CallDoubleMethodA");
1720 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1723 STATS(jniinvokation();)
1725 va_start(vaargs,methodID);
1726 (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
1731 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1733 log_text("JNI-Call: CallVoidMethodV");
1734 STATS(jniinvokation();)
1735 (void)callIntegerMethod(obj,get_virtual(obj,methodID),TYPE_VOID,args);
1739 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1741 STATS(jniinvokation();)
1742 log_text("JNI-Call: CallVoidMethodA");
1747 jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1749 STATS(jniinvokation();)
1751 log_text("JNI-Call: CallNonvirtualObjectMethod: IMPLEMENT ME!");
1753 return NewLocalRef(env, NULL);
1757 jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1759 STATS(jniinvokation();)
1761 log_text("JNI-Call: CallNonvirtualObjectMethodV: IMPLEMENT ME!");
1763 return NewLocalRef(env, NULL);
1767 jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1769 STATS(jniinvokation();)
1771 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1773 return NewLocalRef(env, NULL);
1778 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1782 STATS(jniinvokation();)
1784 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1786 va_start(vaargs,methodID);
1787 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1794 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1796 STATS(jniinvokation();)
1797 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1798 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
1802 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1804 STATS(jniinvokation();)
1805 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1812 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1817 STATS(jniinvokation();)
1818 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1820 va_start(vaargs,methodID);
1821 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
1827 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1829 STATS(jniinvokation();)
1830 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1831 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
1836 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1838 STATS(jniinvokation();)
1839 log_text("JNI-Call: CallNonvirtualByteMethodA");
1846 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1851 STATS(jniinvokation();)
1852 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1854 va_start(vaargs,methodID);
1855 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
1861 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1863 STATS(jniinvokation();)
1864 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1865 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
1869 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1871 STATS(jniinvokation();)
1872 log_text("JNI-Call: CallNonvirtualCharMethodA");
1879 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1883 STATS(jniinvokation();)
1885 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1887 va_start(vaargs,methodID);
1888 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
1894 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1896 STATS(jniinvokation();)
1897 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1898 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
1902 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1904 STATS(jniinvokation();)
1905 log_text("JNI-Call: CallNonvirtualShortMethodA");
1912 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1917 STATS(jniinvokation();)
1919 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1921 va_start(vaargs,methodID);
1922 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
1928 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1930 STATS(jniinvokation();)
1931 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1932 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
1936 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1938 STATS(jniinvokation();)
1939 log_text("JNI-Call: CallNonvirtualIntMethodA");
1946 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1948 STATS(jniinvokation();)
1949 log_text("JNI-Call: CallNonvirtualLongMethod");
1955 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1957 STATS(jniinvokation();)
1958 log_text("JNI-Call: CallNonvirtualLongMethodV");
1964 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1966 STATS(jniinvokation();)
1967 log_text("JNI-Call: CallNonvirtualLongMethodA");
1974 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1978 STATS(jniinvokation();)
1980 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1983 va_start(vaargs,methodID);
1984 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
1991 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1993 STATS(jniinvokation();)
1994 log_text("JNI-Call: CallNonvirtualFloatMethodV");
1995 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
1999 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2001 STATS(jniinvokation();)
2002 log_text("JNI-Call: CallNonvirtualFloatMethodA");
2009 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2013 STATS(jniinvokation();)
2014 log_text("JNI-Call: CallNonvirtualDoubleMethod");
2016 va_start(vaargs,methodID);
2017 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
2024 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2026 STATS(jniinvokation();)
2027 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
2028 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
2032 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2034 STATS(jniinvokation();)
2035 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
2042 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2045 STATS(jniinvokation();)
2047 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
2049 va_start(vaargs,methodID);
2050 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
2056 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2058 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
2059 STATS(jniinvokation();)
2061 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
2066 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
2068 STATS(jniinvokation();)
2069 log_text("JNI-Call: CallNonvirtualVoidMethodA");
2072 /************************* JNI-functions for accessing fields ************************/
2074 jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2078 STATS(jniinvokation();)
2080 f = class_findfield(clazz, utf_new_char((char *) name), utf_new_char((char *) sig));
2083 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2088 /*************************** retrieve fieldid, abort on error ************************/
2090 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
2092 jfieldID id = GetFieldID(env, clazz, name, sig);
2093 STATS(jniinvokation();)
2097 utf_display(clazz->name);
2098 log_text("\nfield:");
2103 log_text("setfield_critical failed");
2109 jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2111 java_objectheader *o;
2113 STATS(jniinvokation();)
2115 o = getField(obj, java_objectheader*, fieldID);
2117 return NewLocalRef(env, o);
2120 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
2122 STATS(jniinvokation();)
2123 return getField(obj,jboolean,fieldID);
2127 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
2129 STATS(jniinvokation();)
2130 return getField(obj,jbyte,fieldID);
2134 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
2136 STATS(jniinvokation();)
2137 return getField(obj,jchar,fieldID);
2141 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
2143 STATS(jniinvokation();)
2144 return getField(obj,jshort,fieldID);
2148 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
2150 STATS(jniinvokation();)
2151 return getField(obj,jint,fieldID);
2155 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
2157 STATS(jniinvokation();)
2158 return getField(obj,jlong,fieldID);
2162 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
2164 STATS(jniinvokation();)
2165 return getField(obj,jfloat,fieldID);
2169 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
2171 STATS(jniinvokation();)
2172 return getField(obj,jdouble,fieldID);
2175 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
2177 STATS(jniinvokation();)
2178 setField(obj,jobject,fieldID,val);
2182 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
2184 STATS(jniinvokation();)
2185 setField(obj,jboolean,fieldID,val);
2189 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
2191 STATS(jniinvokation();)
2192 setField(obj,jbyte,fieldID,val);
2196 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
2198 STATS(jniinvokation();)
2199 setField(obj,jchar,fieldID,val);
2203 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
2205 STATS(jniinvokation();)
2206 setField(obj,jshort,fieldID,val);
2210 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
2212 STATS(jniinvokation();)
2213 setField(obj,jint,fieldID,val);
2217 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
2219 STATS(jniinvokation();)
2220 setField(obj,jlong,fieldID,val);
2224 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
2226 STATS(jniinvokation();)
2227 setField(obj,jfloat,fieldID,val);
2231 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
2233 STATS(jniinvokation();)
2234 setField(obj,jdouble,fieldID,val);
2238 /**************** JNI-functions for calling static methods **********************/
2240 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2243 STATS(jniinvokation();)
2245 m = class_resolvemethod(clazz,
2246 utf_new_char((char *) name),
2247 utf_new_char((char *) sig));
2249 if (!m || !(m->flags & ACC_STATIC)) {
2251 new_exception_message(string_java_lang_NoSuchMethodError, name);
2260 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2262 java_objectheader *ret;
2265 STATS(jniinvokation();)
2267 va_start(vaargs, methodID);
2268 ret = callObjectMethod(0, methodID, vaargs);
2271 return NewLocalRef(env, ret);
2275 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2277 java_objectheader *ret;
2279 STATS(jniinvokation();)
2281 ret = callObjectMethod(0, methodID, args);
2283 return NewLocalRef(env, ret);
2287 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2289 STATS(jniinvokation();)
2291 log_text("JNI-Call: CallStaticObjectMethodA: IMPLEMENT ME!");
2293 return NewLocalRef(env, NULL);
2297 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2301 STATS(jniinvokation();)
2303 va_start(vaargs, methodID);
2304 ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
2311 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2313 STATS(jniinvokation();)
2314 return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
2318 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2320 STATS(jniinvokation();)
2321 log_text("JNI-Call: CallStaticBooleanMethodA");
2327 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2331 STATS(jniinvokation();)
2333 /* log_text("JNI-Call: CallStaticByteMethod");*/
2335 va_start(vaargs, methodID);
2336 ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
2343 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2345 STATS(jniinvokation();)
2346 return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
2350 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2352 STATS(jniinvokation();)
2353 log_text("JNI-Call: CallStaticByteMethodA");
2359 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2363 STATS(jniinvokation();)
2365 /* log_text("JNI-Call: CallStaticByteMethod");*/
2367 va_start(vaargs, methodID);
2368 ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
2375 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2377 STATS(jniinvokation();)
2378 return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
2382 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2384 STATS(jniinvokation();)
2385 log_text("JNI-Call: CallStaticCharMethodA");
2392 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2396 STATS(jniinvokation();)
2398 /* log_text("JNI-Call: CallStaticByteMethod");*/
2400 va_start(vaargs, methodID);
2401 ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
2408 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2410 STATS(jniinvokation();)
2411 /*log_text("JNI-Call: CallStaticShortMethodV");*/
2412 return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
2416 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2418 STATS(jniinvokation();)
2419 log_text("JNI-Call: CallStaticShortMethodA");
2426 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2430 STATS(jniinvokation();)
2432 /* log_text("JNI-Call: CallStaticIntMethod");*/
2434 va_start(vaargs, methodID);
2435 ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
2442 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2444 STATS(jniinvokation();)
2445 log_text("JNI-Call: CallStaticIntMethodV");
2447 return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
2451 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2453 STATS(jniinvokation();)
2454 log_text("JNI-Call: CallStaticIntMethodA");
2461 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2465 STATS(jniinvokation();)
2467 /* log_text("JNI-Call: CallStaticLongMethod");*/
2469 va_start(vaargs, methodID);
2470 ret = callLongMethod(0, methodID, vaargs);
2477 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
2480 STATS(jniinvokation();)
2482 return callLongMethod(0, methodID, args);
2486 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2488 STATS(jniinvokation();)
2490 log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!!!");
2497 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2501 STATS(jniinvokation();)
2503 /* log_text("JNI-Call: CallStaticLongMethod");*/
2505 va_start(vaargs, methodID);
2506 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
2513 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2515 STATS(jniinvokation();)
2517 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
2522 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2524 STATS(jniinvokation();)
2525 log_text("JNI-Call: CallStaticFloatMethodA");
2532 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2536 STATS(jniinvokation();)
2538 /* log_text("JNI-Call: CallStaticDoubleMethod");*/
2540 va_start(vaargs,methodID);
2541 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
2548 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2550 STATS(jniinvokation();)
2551 log_text("JNI-Call: CallStaticDoubleMethodV");
2553 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
2557 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2559 STATS(jniinvokation();)
2560 log_text("JNI-Call: CallStaticDoubleMethodA");
2566 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2569 STATS(jniinvokation();)
2571 va_start(vaargs, methodID);
2572 (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
2577 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2579 log_text("JNI-Call: CallStaticVoidMethodV");
2580 STATS(jniinvokation();)
2581 (void)callIntegerMethod(0, methodID, TYPE_VOID, args);
2585 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2587 STATS(jniinvokation();)
2588 log_text("JNI-Call: CallStaticVoidMethodA");
2592 /* Accessing Static Fields ****************************************************/
2594 /* GetStaticFieldID ************************************************************
2596 Returns the field ID for a static field of a class. The field is
2597 specified by its name and signature. The GetStatic<type>Field and
2598 SetStatic<type>Field families of accessor functions use field IDs
2599 to retrieve static fields.
2601 *******************************************************************************/
2603 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2606 STATS(jniinvokation();)
2608 f = class_findfield(clazz,
2609 utf_new_char((char *) name),
2610 utf_new_char((char *) sig));
2613 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2619 /* GetStatic<type>Field ********************************************************
2621 This family of accessor routines returns the value of a static
2624 *******************************************************************************/
2626 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2628 STATS(jniinvokation();)
2630 if (!clazz->initialized)
2631 if (!initialize_class(clazz))
2634 return NewLocalRef(env, fieldID->value.a);
2638 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2640 STATS(jniinvokation();)
2642 if (!clazz->initialized)
2643 if (!initialize_class(clazz))
2646 return fieldID->value.i;
2650 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2652 STATS(jniinvokation();)
2654 if (!clazz->initialized)
2655 if (!initialize_class(clazz))
2658 return fieldID->value.i;
2662 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2664 STATS(jniinvokation();)
2666 if (!clazz->initialized)
2667 if (!initialize_class(clazz))
2670 return fieldID->value.i;
2674 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2676 STATS(jniinvokation();)
2678 if (!clazz->initialized)
2679 if (!initialize_class(clazz))
2682 return fieldID->value.i;
2686 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2688 STATS(jniinvokation();)
2690 if (!clazz->initialized)
2691 if (!initialize_class(clazz))
2694 return fieldID->value.i;
2698 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2700 STATS(jniinvokation();)
2702 if (!clazz->initialized)
2703 if (!initialize_class(clazz))
2706 return fieldID->value.l;
2710 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2712 STATS(jniinvokation();)
2714 if (!clazz->initialized)
2715 if (!initialize_class(clazz))
2718 return fieldID->value.f;
2722 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2724 STATS(jniinvokation();)
2726 if (!clazz->initialized)
2727 if (!initialize_class(clazz))
2730 return fieldID->value.d;
2734 /* SetStatic<type>Field *******************************************************
2736 This family of accessor routines sets the value of a static field
2739 *******************************************************************************/
2741 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2743 STATS(jniinvokation();)
2745 if (!clazz->initialized)
2746 if (!initialize_class(clazz))
2749 fieldID->value.a = value;
2753 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2755 STATS(jniinvokation();)
2757 if (!clazz->initialized)
2758 if (!initialize_class(clazz))
2761 fieldID->value.i = value;
2765 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2767 STATS(jniinvokation();)
2769 if (!clazz->initialized)
2770 if (!initialize_class(clazz))
2773 fieldID->value.i = value;
2777 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2779 STATS(jniinvokation();)
2781 if (!clazz->initialized)
2782 if (!initialize_class(clazz))
2785 fieldID->value.i = value;
2789 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2791 STATS(jniinvokation();)
2793 if (!clazz->initialized)
2794 if (!initialize_class(clazz))
2797 fieldID->value.i = value;
2801 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2803 STATS(jniinvokation();)
2805 if (!clazz->initialized)
2806 if (!initialize_class(clazz))
2809 fieldID->value.i = value;
2813 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2815 STATS(jniinvokation();)
2817 if (!clazz->initialized)
2818 if (!initialize_class(clazz))
2821 fieldID->value.l = value;
2825 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2827 STATS(jniinvokation();)
2829 if (!clazz->initialized)
2830 if (!initialize_class(clazz))
2833 fieldID->value.f = value;
2837 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2839 STATS(jniinvokation();)
2841 if (!clazz->initialized)
2842 if (!initialize_class(clazz))
2845 fieldID->value.d = value;
2849 /* String Operations **********************************************************/
2851 /* NewString *******************************************************************
2853 Create new java.lang.String object from an array of Unicode
2856 *******************************************************************************/
2858 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
2860 java_lang_String *s;
2864 STATS(jniinvokation();)
2866 s = (java_lang_String *) builtin_new(class_java_lang_String);
2867 a = builtin_newarray_char(len);
2869 /* javastring or characterarray could not be created */
2874 for (i = 0; i < len; i++)
2875 a->data[i] = buf[i];
2881 return (jstring) NewLocalRef(env, (jobject) s);
2885 static jchar emptyStringJ[]={0,0};
2887 /* GetStringLength *************************************************************
2889 Returns the length (the count of Unicode characters) of a Java
2892 *******************************************************************************/
2894 jsize GetStringLength(JNIEnv *env, jstring str)
2896 return ((java_lang_String *) str)->count;
2900 /******************** convertes javastring to u2-array ****************************/
2902 u2 *javastring_tou2(jstring so)
2904 java_lang_String *s;
2909 STATS(jniinvokation();)
2911 s = (java_lang_String *) so;
2921 /* allocate memory */
2923 stringbuffer = MNEW(u2, s->count + 1);
2927 for (i = 0; i < s->count; i++)
2928 stringbuffer[i] = a->data[s->offset + i];
2930 /* terminate string */
2932 stringbuffer[i] = '\0';
2934 return stringbuffer;
2938 /* GetStringChars **************************************************************
2940 Returns a pointer to the array of Unicode characters of the
2941 string. This pointer is valid until ReleaseStringchars() is called.
2943 *******************************************************************************/
2945 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2949 STATS(jniinvokation();)
2951 jc = javastring_tou2(str);
2963 return emptyStringJ;
2967 /* ReleaseStringChars **********************************************************
2969 Informs the VM that the native code no longer needs access to
2970 chars. The chars argument is a pointer obtained from string using
2973 *******************************************************************************/
2975 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2977 STATS(jniinvokation();)
2979 if (chars == emptyStringJ)
2982 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
2986 /* NewStringUTF ****************************************************************
2988 Constructs a new java.lang.String object from an array of UTF-8 characters.
2990 *******************************************************************************/
2992 jstring NewStringUTF(JNIEnv *env, const char *bytes)
2994 java_lang_String *s;
2996 STATS(jniinvokation();)
2998 s = javastring_new(utf_new_char(bytes));
3000 return (jstring) NewLocalRef(env, (jobject) s);
3004 /****************** returns the utf8 length in bytes of a string *******************/
3006 jsize GetStringUTFLength (JNIEnv *env, jstring string)
3008 java_lang_String *s = (java_lang_String*) string;
3009 STATS(jniinvokation();)
3011 return (jsize) u2_utflength(s->value->data, s->count);
3015 /* GetStringUTFChars ***********************************************************
3017 Returns a pointer to an array of UTF-8 characters of the
3018 string. This array is valid until it is released by
3019 ReleaseStringUTFChars().
3021 *******************************************************************************/
3023 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
3026 STATS(jniinvokation();)
3034 u = javastring_toutf((java_lang_String *) string, false);
3043 /* ReleaseStringUTFChars *******************************************************
3045 Informs the VM that the native code no longer needs access to
3046 utf. The utf argument is a pointer derived from string using
3047 GetStringUTFChars().
3049 *******************************************************************************/
3051 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
3053 STATS(jniinvokation();)
3055 /* XXX we don't release utf chars right now, perhaps that should be done
3056 later. Since there is always one reference the garbage collector will
3061 /* Array Operations ***********************************************************/
3063 /* GetArrayLength **************************************************************
3065 Returns the number of elements in the array.
3067 *******************************************************************************/
3069 jsize GetArrayLength(JNIEnv *env, jarray array)
3071 STATS(jniinvokation();)
3077 /* NewObjectArray **************************************************************
3079 Constructs a new array holding objects in class elementClass. All
3080 elements are initially set to initialElement.
3082 *******************************************************************************/
3084 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
3086 java_objectarray *oa;
3089 STATS(jniinvokation();)
3092 *exceptionptr = new_negativearraysizeexception();
3096 oa = builtin_anewarray(length, elementClass);
3101 /* set all elements to initialElement */
3103 for (i = 0; i < length; i++)
3104 oa->data[i] = initialElement;
3106 return (jobjectArray) NewLocalRef(env, (jobject) oa);
3110 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
3114 STATS(jniinvokation();)
3116 if (index >= array->header.size) {
3118 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3122 o = array->data[index];
3124 return NewLocalRef(env, o);
3128 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3130 STATS(jniinvokation();)
3131 if (index >= array->header.size)
3132 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3135 /* check if the class of value is a subclass of the element class of the array */
3136 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
3137 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3140 array->data[index] = val;
3145 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3147 java_booleanarray *ba;
3149 STATS(jniinvokation();)
3152 *exceptionptr = new_negativearraysizeexception();
3156 ba = builtin_newarray_boolean(len);
3158 return (jbooleanArray) NewLocalRef(env, (jobject) ba);
3162 jbyteArray NewByteArray(JNIEnv *env, jsize len)
3166 STATS(jniinvokation();)
3169 *exceptionptr = new_negativearraysizeexception();
3173 ba = builtin_newarray_byte(len);
3175 return (jbyteArray) NewLocalRef(env, (jobject) ba);
3179 jcharArray NewCharArray(JNIEnv *env, jsize len)
3183 STATS(jniinvokation();)
3186 *exceptionptr = new_negativearraysizeexception();
3190 ca = builtin_newarray_char(len);
3192 return (jcharArray) NewLocalRef(env, (jobject) ca);
3196 jshortArray NewShortArray(JNIEnv *env, jsize len)
3198 java_shortarray *sa;
3200 STATS(jniinvokation();)
3203 *exceptionptr = new_negativearraysizeexception();
3207 sa = builtin_newarray_short(len);
3209 return (jshortArray) NewLocalRef(env, (jobject) sa);
3213 jintArray NewIntArray(JNIEnv *env, jsize len)
3217 STATS(jniinvokation();)
3220 *exceptionptr = new_negativearraysizeexception();
3224 ia = builtin_newarray_int(len);
3226 return (jintArray) NewLocalRef(env, (jobject) ia);
3230 jlongArray NewLongArray(JNIEnv *env, jsize len)
3234 STATS(jniinvokation();)
3237 *exceptionptr = new_negativearraysizeexception();
3241 la = builtin_newarray_long(len);
3243 return (jlongArray) NewLocalRef(env, (jobject) la);
3247 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3249 java_floatarray *fa;
3251 STATS(jniinvokation();)
3254 *exceptionptr = new_negativearraysizeexception();
3258 fa = builtin_newarray_float(len);
3260 return (jfloatArray) NewLocalRef(env, (jobject) fa);
3264 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3266 java_doublearray *da;
3268 STATS(jniinvokation();)
3271 *exceptionptr = new_negativearraysizeexception();
3275 da = builtin_newarray_double(len);
3277 return (jdoubleArray) NewLocalRef(env, (jobject) da);
3281 /* Get<PrimitiveType>ArrayElements *********************************************
3283 A family of functions that returns the body of the primitive array.
3285 *******************************************************************************/
3287 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3290 STATS(jniinvokation();)
3293 *isCopy = JNI_FALSE;
3299 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3301 STATS(jniinvokation();)
3304 *isCopy = JNI_FALSE;
3310 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3312 STATS(jniinvokation();)
3315 *isCopy = JNI_FALSE;
3321 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3323 STATS(jniinvokation();)
3326 *isCopy = JNI_FALSE;
3332 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3334 STATS(jniinvokation();)
3337 *isCopy = JNI_FALSE;
3343 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3345 STATS(jniinvokation();)
3348 *isCopy = JNI_FALSE;
3354 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3356 STATS(jniinvokation();)
3359 *isCopy = JNI_FALSE;
3365 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3368 STATS(jniinvokation();)
3371 *isCopy = JNI_FALSE;
3377 /* Release<PrimitiveType>ArrayElements *****************************************
3379 A family of functions that informs the VM that the native code no
3380 longer needs access to elems. The elems argument is a pointer
3381 derived from array using the corresponding
3382 Get<PrimitiveType>ArrayElements() function. If necessary, this
3383 function copies back all changes made to elems to the original
3386 *******************************************************************************/
3388 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3389 jboolean *elems, jint mode)
3391 STATS(jniinvokation();)
3393 if (elems != array->data) {
3396 MCOPY(array->data, elems, jboolean, array->header.size);
3399 MCOPY(array->data, elems, jboolean, array->header.size);
3400 /* XXX TWISTI how should it be freed? */
3403 /* XXX TWISTI how should it be freed? */
3410 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
3413 STATS(jniinvokation();)
3415 if (elems != array->data) {
3418 MCOPY(array->data, elems, jboolean, array->header.size);
3421 MCOPY(array->data, elems, jboolean, array->header.size);
3422 /* XXX TWISTI how should it be freed? */
3425 /* XXX TWISTI how should it be freed? */
3432 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
3435 STATS(jniinvokation();)
3437 if (elems != array->data) {
3440 MCOPY(array->data, elems, jboolean, array->header.size);
3443 MCOPY(array->data, elems, jboolean, array->header.size);
3444 /* XXX TWISTI how should it be freed? */
3447 /* XXX TWISTI how should it be freed? */
3454 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
3457 STATS(jniinvokation();)
3459 if (elems != array->data) {
3462 MCOPY(array->data, elems, jboolean, array->header.size);
3465 MCOPY(array->data, elems, jboolean, array->header.size);
3466 /* XXX TWISTI how should it be freed? */
3469 /* XXX TWISTI how should it be freed? */
3476 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
3479 STATS(jniinvokation();)
3481 if (elems != array->data) {
3484 MCOPY(array->data, elems, jboolean, array->header.size);
3487 MCOPY(array->data, elems, jboolean, array->header.size);
3488 /* XXX TWISTI how should it be freed? */
3491 /* XXX TWISTI how should it be freed? */
3498 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
3501 STATS(jniinvokation();)
3503 if (elems != array->data) {
3506 MCOPY(array->data, elems, jboolean, array->header.size);
3509 MCOPY(array->data, elems, jboolean, array->header.size);
3510 /* XXX TWISTI how should it be freed? */
3513 /* XXX TWISTI how should it be freed? */
3520 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
3523 STATS(jniinvokation();)
3525 if (elems != array->data) {
3528 MCOPY(array->data, elems, jboolean, array->header.size);
3531 MCOPY(array->data, elems, jboolean, array->header.size);
3532 /* XXX TWISTI how should it be freed? */
3535 /* XXX TWISTI how should it be freed? */
3542 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3543 jdouble *elems, jint mode)
3545 STATS(jniinvokation();)
3547 if (elems != array->data) {
3550 MCOPY(array->data, elems, jboolean, array->header.size);
3553 MCOPY(array->data, elems, jboolean, array->header.size);
3554 /* XXX TWISTI how should it be freed? */
3557 /* XXX TWISTI how should it be freed? */
3564 /* Get<PrimitiveType>ArrayRegion **********************************************
3566 A family of functions that copies a region of a primitive array
3569 *******************************************************************************/
3571 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3572 jsize len, jboolean *buf)
3574 STATS(jniinvokation();)
3576 if (start < 0 || len < 0 || start + len > array->header.size)
3578 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3581 MCOPY(buf, &array->data[start], jboolean, len);
3585 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3588 STATS(jniinvokation();)
3590 if (start < 0 || len < 0 || start + len > array->header.size)
3592 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3595 MCOPY(buf, &array->data[start], jbyte, len);
3599 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3602 STATS(jniinvokation();)
3604 if (start < 0 || len < 0 || start + len > array->header.size)
3606 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3609 MCOPY(buf, &array->data[start], jchar, len);
3613 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3614 jsize len, jshort *buf)
3616 STATS(jniinvokation();)
3618 if (start < 0 || len < 0 || start + len > array->header.size)
3620 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3623 MCOPY(buf, &array->data[start], jshort, len);
3627 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3630 STATS(jniinvokation();)
3632 if (start < 0 || len < 0 || start + len > array->header.size)
3634 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3637 MCOPY(buf, &array->data[start], jint, len);
3641 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
3644 STATS(jniinvokation();)
3646 if (start < 0 || len < 0 || start + len > array->header.size)
3648 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3651 MCOPY(buf, &array->data[start], jlong, len);
3655 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3656 jsize len, jfloat *buf)
3658 STATS(jniinvokation();)
3660 if (start < 0 || len < 0 || start + len > array->header.size)
3662 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3665 MCOPY(buf, &array->data[start], jfloat, len);
3669 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3670 jsize len, jdouble *buf)
3672 STATS(jniinvokation();)
3674 if (start < 0 || len < 0 || start+len>array->header.size)
3676 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3679 MCOPY(buf, &array->data[start], jdouble, len);
3683 /* Set<PrimitiveType>ArrayRegion **********************************************
3685 A family of functions that copies back a region of a primitive
3686 array from a buffer.
3688 *******************************************************************************/
3690 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3691 jsize len, jboolean *buf)
3693 STATS(jniinvokation();)
3695 if (start < 0 || len < 0 || start + len > array->header.size)
3697 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3700 MCOPY(&array->data[start], buf, jboolean, len);
3704 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3707 STATS(jniinvokation();)
3709 if (start < 0 || len < 0 || start + len > array->header.size)
3711 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3714 MCOPY(&array->data[start], buf, jbyte, len);
3718 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3721 STATS(jniinvokation();)
3723 if (start < 0 || len < 0 || start + len > array->header.size)
3725 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3728 MCOPY(&array->data[start], buf, jchar, len);
3733 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3734 jsize len, jshort *buf)
3736 STATS(jniinvokation();)
3738 if (start < 0 || len < 0 || start + len > array->header.size)
3740 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3743 MCOPY(&array->data[start], buf, jshort, len);
3747 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3750 STATS(jniinvokation();)
3752 if (start < 0 || len < 0 || start + len > array->header.size)
3754 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3757 MCOPY(&array->data[start], buf, jint, len);
3762 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
3765 STATS(jniinvokation();)
3767 if (start < 0 || len < 0 || start + len > array->header.size)
3769 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3772 MCOPY(&array->data[start], buf, jlong, len);
3777 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3778 jsize len, jfloat *buf)
3780 STATS(jniinvokation();)
3782 if (start < 0 || len < 0 || start + len > array->header.size)
3784 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3787 MCOPY(&array->data[start], buf, jfloat, len);
3792 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3793 jsize len, jdouble *buf)
3795 STATS(jniinvokation();)
3797 if (start < 0 || len < 0 || start + len > array->header.size)
3799 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3802 MCOPY(&array->data[start], buf, jdouble, len);
3806 /* Registering Native Methods *************************************************/
3808 /* RegisterNatives *************************************************************
3810 Registers native methods with the class specified by the clazz
3811 argument. The methods parameter specifies an array of
3812 JNINativeMethod structures that contain the names, signatures, and
3813 function pointers of the native methods. The nMethods parameter
3814 specifies the number of native methods in the array.
3816 *******************************************************************************/
3818 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
3821 STATS(jniinvokation();)
3823 log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
3829 /* UnregisterNatives ***********************************************************
3831 Unregisters native methods of a class. The class goes back to the
3832 state before it was linked or registered with its native method
3835 This function should not be used in normal native code. Instead, it
3836 provides special programs a way to reload and relink native
3839 *******************************************************************************/
3841 jint UnregisterNatives(JNIEnv *env, jclass clazz)
3843 STATS(jniinvokation();)
3845 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3847 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3853 /* Monitor Operations *********************************************************/
3855 /* MonitorEnter ****************************************************************
3857 Enters the monitor associated with the underlying Java object
3860 *******************************************************************************/
3862 jint MonitorEnter(JNIEnv *env, jobject obj)
3864 STATS(jniinvokation();)
3867 *exceptionptr = new_nullpointerexception();
3871 #if defined(USE_THREADS)
3872 builtin_monitorenter(obj);
3879 /* MonitorExit *****************************************************************
3881 The current thread must be the owner of the monitor associated with
3882 the underlying Java object referred to by obj. The thread
3883 decrements the counter indicating the number of times it has
3884 entered this monitor. If the value of the counter becomes zero, the
3885 current thread releases the monitor.
3887 *******************************************************************************/
3889 jint MonitorExit(JNIEnv *env, jobject obj)
3891 STATS(jniinvokation();)
3893 *exceptionptr = new_nullpointerexception();
3897 #if defined(USE_THREADS)
3898 builtin_monitorexit(obj);
3905 /* JavaVM Interface ***********************************************************/
3907 /* GetJavaVM *******************************************************************
3909 Returns the Java VM interface (used in the Invocation API)
3910 associated with the current thread. The result is placed at the
3911 location pointed to by the second argument, vm.
3913 *******************************************************************************/
3915 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
3917 STATS(jniinvokation();)
3924 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3926 STATS(jniinvokation();)
3927 log_text("JNI-Call: GetStringRegion");
3931 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3933 STATS(jniinvokation();)
3934 log_text("JNI-Call: GetStringUTFRegion");
3938 /* GetPrimitiveArrayCritical ***************************************************
3940 Obtain a direct pointer to array elements.
3942 *******************************************************************************/
3944 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3946 /* do the same as Kaffe does */
3948 return GetByteArrayElements(env, (jbyteArray) array, isCopy);
3952 /* ReleasePrimitiveArrayCritical ***********************************************
3954 No specific documentation.
3956 *******************************************************************************/
3958 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
3961 STATS(jniinvokation();)
3963 /* do the same as Kaffe does */
3965 ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
3969 /* GetStringCritical ***********************************************************
3971 The semantics of these two functions are similar to the existing
3972 Get/ReleaseStringChars functions.
3974 *******************************************************************************/
3976 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
3978 STATS(jniinvokation();)
3980 return GetStringChars(env, string, isCopy);
3984 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
3986 STATS(jniinvokation();)
3988 ReleaseStringChars(env, string, cstring);
3992 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3994 STATS(jniinvokation();)
3995 log_text("JNI-Call: NewWeakGlobalRef");
4001 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
4003 STATS(jniinvokation();)
4004 log_text("JNI-Call: DeleteWeakGlobalRef");
4010 /* NewGlobalRef ****************************************************************
4012 Creates a new global reference to the object referred to by the obj
4015 *******************************************************************************/
4017 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4019 java_lang_Integer *refcount;
4020 java_objectheader *newval;
4022 STATS(jniinvokation();)
4024 #if defined(USE_THREADS)
4025 builtin_monitorenter(*global_ref_table);
4028 refcount = (java_lang_Integer *)
4029 asm_calljavafunction(getmid, *global_ref_table, lobj, NULL, NULL);
4031 if (refcount == NULL) {
4032 newval = native_new_and_init_int(class_java_lang_Integer, 1);
4034 if (newval == NULL) {
4035 #if defined(USE_THREADS)
4036 builtin_monitorexit(*global_ref_table);
4041 asm_calljavafunction(putmid, *global_ref_table, lobj, newval, NULL);
4044 /* we can access the object itself, as we are in a
4045 synchronized section */
4050 #if defined(USE_THREADS)
4051 builtin_monitorexit(*global_ref_table);
4058 /* DeleteGlobalRef *************************************************************
4060 Deletes the global reference pointed to by globalRef.
4062 *******************************************************************************/
4064 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
4066 java_lang_Integer *refcount;
4069 STATS(jniinvokation();)
4071 #if defined(USE_THREADS)
4072 builtin_monitorenter(*global_ref_table);
4075 refcount = (java_lang_Integer *)
4076 asm_calljavafunction(getmid, *global_ref_table, globalRef, NULL, NULL);
4078 if (refcount == NULL) {
4079 log_text("JNI-DeleteGlobalRef: unable to find global reference");
4083 /* we can access the object itself, as we are in a synchronized
4086 val = refcount->value - 1;
4089 asm_calljavafunction(removemid, *global_ref_table, refcount, NULL,
4093 /* we do not create a new object, but set the new value into
4096 refcount->value = val;
4099 #if defined(USE_THREADS)
4100 builtin_monitorexit(*global_ref_table);
4105 /* ExceptionCheck **************************************************************
4107 Returns JNI_TRUE when there is a pending exception; otherwise,
4110 *******************************************************************************/
4112 jboolean ExceptionCheck(JNIEnv *env)
4114 STATS(jniinvokation();)
4115 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
4119 /* New JNI 1.4 functions ******************************************************/
4121 /* NewDirectByteBuffer *********************************************************
4123 Allocates and returns a direct java.nio.ByteBuffer referring to the
4124 block of memory starting at the memory address address and
4125 extending capacity bytes.
4127 *******************************************************************************/
4129 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
4131 java_nio_DirectByteBufferImpl *nbuf;
4132 #if SIZEOF_VOID_P == 8
4133 gnu_classpath_Pointer64 *paddress;
4135 gnu_classpath_Pointer32 *paddress;
4138 STATS(jniinvokation();)
4140 log_text("JNI-NewDirectByteBuffer: called");
4142 /* allocate a java.nio.DirectByteBufferImpl object */
4144 if (!(nbuf = (java_nio_DirectByteBufferImpl *) builtin_new(class_java_nio_DirectByteBufferImpl)))
4147 /* alocate a gnu.classpath.Pointer{32,64} object */
4149 #if SIZEOF_VOID_P == 8
4150 if (!(paddress = (gnu_classpath_Pointer64 *) builtin_new(class_gnu_classpath_Pointer64)))
4152 if (!(paddress = (gnu_classpath_Pointer32 *) builtin_new(class_gnu_classpath_Pointer32)))
4156 /* fill gnu.classpath.Pointer{32,64} with address */
4158 paddress->data = (ptrint) address;
4160 /* fill java.nio.Buffer object */
4162 nbuf->cap = (s4) capacity;
4163 nbuf->limit = (s4) capacity;
4165 nbuf->address = (gnu_classpath_Pointer *) paddress;
4167 /* add local reference and return the value */
4169 return NewLocalRef(env, (jobject) nbuf);
4173 /* GetDirectBufferAddress ******************************************************
4175 Fetches and returns the starting address of the memory region
4176 referenced by the given direct java.nio.Buffer.
4178 *******************************************************************************/
4180 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
4182 java_nio_DirectByteBufferImpl *nbuf;
4183 #if SIZEOF_VOID_P == 8
4184 gnu_classpath_Pointer64 *address;
4186 gnu_classpath_Pointer32 *address;
4189 STATS(jniinvokation();)
4192 if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
4196 nbuf = (java_nio_DirectByteBufferImpl *) buf;
4198 #if SIZEOF_VOID_P == 8
4199 address = (gnu_classpath_Pointer64 *) nbuf->address;
4201 address = (gnu_classpath_Pointer32 *) nbuf->address;
4204 return (void *) address->data;
4208 /* GetDirectBufferCapacity *****************************************************
4210 Fetches and returns the capacity in bytes of the memory region
4211 referenced by the given direct java.nio.Buffer.
4213 *******************************************************************************/
4215 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
4217 java_nio_Buffer *nbuf;
4219 STATS(jniinvokation();)
4224 nbuf = (java_nio_Buffer *) buf;
4226 return (jlong) nbuf->cap;
4230 jint DestroyJavaVM(JavaVM *vm)
4232 STATS(jniinvokation();)
4233 log_text("DestroyJavaVM called");
4239 /* AttachCurrentThread *********************************************************
4241 Attaches the current thread to a Java VM. Returns a JNI interface
4242 pointer in the JNIEnv argument.
4244 Trying to attach a thread that is already attached is a no-op.
4246 A native thread cannot be attached simultaneously to two Java VMs.
4248 When a thread is attached to the VM, the context class loader is
4249 the bootstrap loader.
4251 *******************************************************************************/
4253 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
4255 STATS(jniinvokation();)
4257 log_text("AttachCurrentThread called");
4259 #if !defined(HAVE___THREAD)
4260 /* cacao_thread_attach();*/
4262 #error "No idea how to implement that. Perhaps Stefan knows"
4271 jint DetachCurrentThread(JavaVM *vm)
4273 STATS(jniinvokation();)
4274 log_text("DetachCurrentThread called");
4280 /* GetEnv **********************************************************************
4282 If the current thread is not attached to the VM, sets *env to NULL,
4283 and returns JNI_EDETACHED. If the specified version is not
4284 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
4285 sets *env to the appropriate interface, and returns JNI_OK.
4287 *******************************************************************************/
4289 jint GetEnv(JavaVM *vm, void **env, jint version)
4291 STATS(jniinvokation();)
4293 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4294 if (thread_getself() == NULL) {
4297 return JNI_EDETACHED;
4301 if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
4302 (version == JNI_VERSION_1_4)) {
4308 #if defined(ENABLE_JVMTI)
4309 if (version == JVMTI_VERSION_1_0) {
4310 *env = (void *) new_jvmtienv();
4319 return JNI_EVERSION;
4324 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4326 STATS(jniinvokation();)
4327 log_text("AttachCurrentThreadAsDaemon called");
4333 /* JNI invocation table *******************************************************/
4335 const struct JNIInvokeInterface JNI_JavaVMTable = {
4341 AttachCurrentThread,
4342 DetachCurrentThread,
4344 AttachCurrentThreadAsDaemon
4348 /* JNI function table *********************************************************/
4350 struct JNINativeInterface JNI_JNIEnvTable = {
4359 &FromReflectedMethod,
4360 &FromReflectedField,
4380 &EnsureLocalCapacity,
4396 &CallBooleanMethodV,
4397 &CallBooleanMethodA,
4423 &CallNonvirtualObjectMethod,
4424 &CallNonvirtualObjectMethodV,
4425 &CallNonvirtualObjectMethodA,
4426 &CallNonvirtualBooleanMethod,
4427 &CallNonvirtualBooleanMethodV,
4428 &CallNonvirtualBooleanMethodA,
4429 &CallNonvirtualByteMethod,
4430 &CallNonvirtualByteMethodV,
4431 &CallNonvirtualByteMethodA,
4432 &CallNonvirtualCharMethod,
4433 &CallNonvirtualCharMethodV,
4434 &CallNonvirtualCharMethodA,
4435 &CallNonvirtualShortMethod,
4436 &CallNonvirtualShortMethodV,
4437 &CallNonvirtualShortMethodA,
4438 &CallNonvirtualIntMethod,
4439 &CallNonvirtualIntMethodV,
4440 &CallNonvirtualIntMethodA,
4441 &CallNonvirtualLongMethod,
4442 &CallNonvirtualLongMethodV,
4443 &CallNonvirtualLongMethodA,
4444 &CallNonvirtualFloatMethod,
4445 &CallNonvirtualFloatMethodV,
4446 &CallNonvirtualFloatMethodA,
4447 &CallNonvirtualDoubleMethod,
4448 &CallNonvirtualDoubleMethodV,
4449 &CallNonvirtualDoubleMethodA,
4450 &CallNonvirtualVoidMethod,
4451 &CallNonvirtualVoidMethodV,
4452 &CallNonvirtualVoidMethodA,
4477 &CallStaticObjectMethod,
4478 &CallStaticObjectMethodV,
4479 &CallStaticObjectMethodA,
4480 &CallStaticBooleanMethod,
4481 &CallStaticBooleanMethodV,
4482 &CallStaticBooleanMethodA,
4483 &CallStaticByteMethod,
4484 &CallStaticByteMethodV,
4485 &CallStaticByteMethodA,
4486 &CallStaticCharMethod,
4487 &CallStaticCharMethodV,
4488 &CallStaticCharMethodA,
4489 &CallStaticShortMethod,
4490 &CallStaticShortMethodV,
4491 &CallStaticShortMethodA,
4492 &CallStaticIntMethod,
4493 &CallStaticIntMethodV,
4494 &CallStaticIntMethodA,
4495 &CallStaticLongMethod,
4496 &CallStaticLongMethodV,
4497 &CallStaticLongMethodA,
4498 &CallStaticFloatMethod,
4499 &CallStaticFloatMethodV,
4500 &CallStaticFloatMethodA,
4501 &CallStaticDoubleMethod,
4502 &CallStaticDoubleMethodV,
4503 &CallStaticDoubleMethodA,
4504 &CallStaticVoidMethod,
4505 &CallStaticVoidMethodV,
4506 &CallStaticVoidMethodA,
4510 &GetStaticObjectField,
4511 &GetStaticBooleanField,
4512 &GetStaticByteField,
4513 &GetStaticCharField,
4514 &GetStaticShortField,
4516 &GetStaticLongField,
4517 &GetStaticFloatField,
4518 &GetStaticDoubleField,
4519 &SetStaticObjectField,
4520 &SetStaticBooleanField,
4521 &SetStaticByteField,
4522 &SetStaticCharField,
4523 &SetStaticShortField,
4525 &SetStaticLongField,
4526 &SetStaticFloatField,
4527 &SetStaticDoubleField,
4532 &ReleaseStringChars,
4535 &GetStringUTFLength,
4537 &ReleaseStringUTFChars,
4542 &GetObjectArrayElement,
4543 &SetObjectArrayElement,
4554 &GetBooleanArrayElements,
4555 &GetByteArrayElements,
4556 &GetCharArrayElements,
4557 &GetShortArrayElements,
4558 &GetIntArrayElements,
4559 &GetLongArrayElements,
4560 &GetFloatArrayElements,
4561 &GetDoubleArrayElements,
4563 &ReleaseBooleanArrayElements,
4564 &ReleaseByteArrayElements,
4565 &ReleaseCharArrayElements,
4566 &ReleaseShortArrayElements,
4567 &ReleaseIntArrayElements,
4568 &ReleaseLongArrayElements,
4569 &ReleaseFloatArrayElements,
4570 &ReleaseDoubleArrayElements,
4572 &GetBooleanArrayRegion,
4573 &GetByteArrayRegion,
4574 &GetCharArrayRegion,
4575 &GetShortArrayRegion,
4577 &GetLongArrayRegion,
4578 &GetFloatArrayRegion,
4579 &GetDoubleArrayRegion,
4580 &SetBooleanArrayRegion,
4581 &SetByteArrayRegion,
4582 &SetCharArrayRegion,
4583 &SetShortArrayRegion,
4585 &SetLongArrayRegion,
4586 &SetFloatArrayRegion,
4587 &SetDoubleArrayRegion,
4597 /* new JNI 1.2 functions */
4600 &GetStringUTFRegion,
4602 &GetPrimitiveArrayCritical,
4603 &ReleasePrimitiveArrayCritical,
4606 &ReleaseStringCritical,
4609 &DeleteWeakGlobalRef,
4613 /* new JNI 1.4 functions */
4615 &NewDirectByteBuffer,
4616 &GetDirectBufferAddress,
4617 &GetDirectBufferCapacity
4621 /* Invocation API Functions ***************************************************/
4623 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4625 Returns a default configuration for the Java VM.
4627 *******************************************************************************/
4629 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4631 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4633 /* GNU classpath currently supports JNI 1.2 */
4635 _vm_args->version = JNI_VERSION_1_2;
4641 /* JNI_GetCreatedJavaVMs *******************************************************
4643 Returns all Java VMs that have been created. Pointers to VMs are written in
4644 the buffer vmBuf in the order they are created. At most bufLen number of
4645 entries will be written. The total number of created VMs is returned in
4648 *******************************************************************************/
4650 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4652 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4658 /* JNI_CreateJavaVM ************************************************************
4660 Loads and initializes a Java VM. The current thread becomes the main thread.
4661 Sets the env argument to the JNI interface pointer of the main thread.
4663 *******************************************************************************/
4665 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4667 const struct JNIInvokeInterface *vm;
4668 struct JNINativeInterface *env;
4670 vm = &JNI_JavaVMTable;
4671 env = &JNI_JNIEnvTable;
4673 *p_vm = (JavaVM *) vm;
4674 *p_env = (JNIEnv *) env;
4680 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4681 jobject obj, java_objectarray *params)
4688 if (methodID == 0) {
4689 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
4693 argcount = methodID->parseddesc->paramcount;
4694 paramcount = argcount;
4696 /* if method is non-static, remove the `this' pointer */
4698 if (!(methodID->flags & ACC_STATIC))
4701 /* the method is an instance method the obj has to be an instance of the
4702 class the method belongs to. For static methods the obj parameter
4705 if (!(methodID->flags & ACC_STATIC) && obj &&
4706 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4708 new_exception_message(string_java_lang_IllegalArgumentException,
4709 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4713 if (((params == NULL) && (paramcount != 0)) ||
4714 (params && (params->header.size != paramcount))) {
4716 new_exception(string_java_lang_IllegalArgumentException);
4721 if (!(methodID->flags & ACC_STATIC) && !obj) {
4723 new_exception_message(string_java_lang_NullPointerException,
4724 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4728 if ((methodID->flags & ACC_STATIC) && (obj))
4732 if ((methodID->flags & ACC_ABSTRACT) ||
4733 (methodID->class->flags & ACC_INTERFACE)) {
4734 methodID = get_virtual(obj, methodID);
4738 blk = MNEW(jni_callblock, argcount);
4740 if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4744 switch (methodID->parseddesc->returntype.decltype) {
4746 (void) asm_calljavafunction2(methodID, argcount,
4747 argcount * sizeof(jni_callblock),
4749 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4752 case PRIMITIVETYPE_INT: {
4754 i = asm_calljavafunction2int(methodID, argcount,
4755 argcount * sizeof(jni_callblock),
4758 o = native_new_and_init_int(class_java_lang_Integer, i);
4762 case PRIMITIVETYPE_BYTE: {
4764 i = asm_calljavafunction2int(methodID, argcount,
4765 argcount * sizeof(jni_callblock),
4768 /* o = native_new_and_init_int(class_java_lang_Byte, i); */
4769 o = builtin_new(class_java_lang_Byte);
4772 class_resolvemethod(o->vftbl->class,
4779 case PRIMITIVETYPE_CHAR: {
4781 intVal = asm_calljavafunction2int(methodID,
4783 argcount * sizeof(jni_callblock),
4785 o = builtin_new(class_java_lang_Character);
4788 class_resolvemethod(o->vftbl->class,
4795 case PRIMITIVETYPE_SHORT: {
4797 intVal = asm_calljavafunction2int(methodID,
4799 argcount * sizeof(jni_callblock),
4801 o = builtin_new(class_java_lang_Short);
4804 class_resolvemethod(o->vftbl->class,
4811 case PRIMITIVETYPE_BOOLEAN: {
4813 intVal = asm_calljavafunction2int(methodID,
4815 argcount * sizeof(jni_callblock),
4817 o = builtin_new(class_java_lang_Boolean);
4820 class_resolvemethod(o->vftbl->class,
4827 case PRIMITIVETYPE_LONG: {
4829 longVal = asm_calljavafunction2long(methodID,
4831 argcount * sizeof(jni_callblock),
4833 o = builtin_new(class_java_lang_Long);
4836 class_resolvemethod(o->vftbl->class,
4843 case PRIMITIVETYPE_FLOAT: {
4845 floatVal = asm_calljavafunction2float(methodID,
4847 argcount * sizeof(jni_callblock),
4849 o = builtin_new(class_java_lang_Float);
4852 class_resolvemethod(o->vftbl->class,
4859 case PRIMITIVETYPE_DOUBLE: {
4861 doubleVal = asm_calljavafunction2double(methodID,
4863 argcount * sizeof(jni_callblock),
4865 o = builtin_new(class_java_lang_Double);
4868 class_resolvemethod(o->vftbl->class,
4876 o = asm_calljavafunction2(methodID, argcount,
4877 argcount * sizeof(jni_callblock), blk);
4881 /* if this happens the exception has already been set by */
4882 /* fill_callblock_from_objectarray */
4884 MFREE(blk, jni_callblock, argcount);
4885 return (jobject *) 0;
4888 MFREE(blk, jni_callblock, argcount);
4890 if (*exceptionptr) {
4891 java_objectheader *cause;
4893 cause = *exceptionptr;
4895 /* clear exception pointer, we are calling JIT code again */
4897 *exceptionptr = NULL;
4900 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
4901 (java_lang_Throwable *) cause);
4904 return (jobject *) o;
4909 * These are local overrides for various environment variables in Emacs.
4910 * Please do not remove this and leave it at the end of the file, where
4911 * Emacs will automagically detect them.
4912 * ---------------------------------------------------------------------
4915 * indent-tabs-mode: t