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 3558 2005-11-03 23:07:30Z twisti $
45 #include "mm/memory.h"
46 #include "native/jni.h"
47 #include "native/native.h"
49 #include "native/include/gnu_classpath_Pointer.h"
51 #if SIZEOF_VOID_P == 8
52 # include "native/include/gnu_classpath_Pointer64.h"
54 # include "native/include/gnu_classpath_Pointer32.h"
57 #include "native/include/java_lang_Object.h"
58 #include "native/include/java_lang_Byte.h"
59 #include "native/include/java_lang_Character.h"
60 #include "native/include/java_lang_Short.h"
61 #include "native/include/java_lang_Integer.h"
62 #include "native/include/java_lang_Boolean.h"
63 #include "native/include/java_lang_Long.h"
64 #include "native/include/java_lang_Float.h"
65 #include "native/include/java_lang_Double.h"
66 #include "native/include/java_lang_Throwable.h"
67 #include "native/include/java_lang_reflect_Method.h"
68 #include "native/include/java_lang_reflect_Constructor.h"
69 #include "native/include/java_lang_reflect_Field.h"
71 #include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
72 #include "native/include/java_lang_VMClass.h"
73 #include "native/include/java_lang_VMClassLoader.h"
74 #include "native/include/java_nio_Buffer.h"
75 #include "native/include/java_nio_DirectByteBufferImpl.h"
77 #if defined(ENABLE_JVMTI)
78 # include "native/jvmti/jvmti.h"
81 #if defined(USE_THREADS)
82 # if defined(NATIVE_THREADS)
83 # include "threads/native/threads.h"
85 # include "threads/green/threads.h"
89 #include "toolbox/logging.h"
90 #include "vm/builtin.h"
91 #include "vm/exceptions.h"
92 #include "vm/global.h"
93 #include "vm/initialize.h"
94 #include "vm/loader.h"
95 #include "vm/options.h"
96 #include "vm/resolve.h"
97 #include "vm/statistics.h"
98 #include "vm/stringlocal.h"
99 #include "vm/tables.h"
100 #include "vm/jit/asmpart.h"
101 #include "vm/jit/jit.h"
102 #include "vm/statistics.h"
105 /* XXX TWISTI hack: define it extern so they can be found in this file */
107 extern const struct JNIInvokeInterface JNI_JavaVMTable;
108 extern struct JNINativeInterface JNI_JNIEnvTable;
110 /* pointers to VM and the environment needed by GetJavaVM and GetEnv */
112 static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
113 void *ptr_env = (void*) &JNI_JNIEnvTable;
116 #define PTR_TO_ITEM(ptr) ((u8)(size_t)(ptr))
118 /* global variables ***********************************************************/
120 /* global reference table *****************************************************/
122 static java_objectheader **global_ref_table;
124 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
125 static classinfo *ihmclass = NULL;
126 static methodinfo *putmid = NULL;
127 static methodinfo *getmid = NULL;
128 static methodinfo *removemid = NULL;
131 /* direct buffer stuff ********************************************************/
133 static utf *utf_java_nio_DirectByteBufferImpl;
134 #if SIZEOF_VOID_P == 8
135 static utf *utf_gnu_classpath_Pointer64;
137 static utf *utf_gnu_classpath_Pointer32;
140 static classinfo *class_java_nio_DirectByteBufferImpl;
141 #if SIZEOF_VOID_P == 8
142 static classinfo *class_gnu_classpath_Pointer64;
144 static classinfo *class_gnu_classpath_Pointer32;
148 /* local reference table ******************************************************/
150 #if !defined(USE_THREADS)
151 localref_table *_no_threads_localref_table;
155 /********************* accessing instance-fields **********************************/
157 #define setField(obj,typ,var,val) *((typ*) ((long int) obj + (long int) var->offset))=val;
158 #define getField(obj,typ,var) *((typ*) ((long int) obj + (long int) var->offset))
159 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) \
160 setField(obj, jdatatype, getFieldID_critical(env,clazz,name,sig), val);
163 /* some forward declarations **************************************************/
165 jobject NewLocalRef(JNIEnv *env, jobject ref);
168 /* jni_init ********************************************************************
170 Initialize the JNI subsystem.
172 *******************************************************************************/
176 /* initalize global reference table */
179 load_class_bootstrap(utf_new_char("java/util/IdentityHashMap"))))
182 global_ref_table = GCNEW(jobject, 1);
184 if (!(*global_ref_table = native_new_and_init(ihmclass)))
187 if (!(getmid = class_resolvemethod(ihmclass, utf_get,
188 utf_java_lang_Object__java_lang_Object)))
191 if (!(putmid = class_resolvemethod(ihmclass, utf_put,
192 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))))
196 class_resolvemethod(ihmclass, utf_remove,
197 utf_java_lang_Object__java_lang_Object)))
201 /* direct buffer stuff */
203 utf_java_nio_DirectByteBufferImpl =
204 utf_new_char("java/nio/DirectByteBufferImpl");
206 if (!(class_java_nio_DirectByteBufferImpl =
207 load_class_bootstrap(utf_java_nio_DirectByteBufferImpl)))
210 if (!link_class(class_java_nio_DirectByteBufferImpl))
213 #if SIZEOF_VOID_P == 8
214 utf_gnu_classpath_Pointer64 = utf_new_char("gnu/classpath/Pointer64");
216 if (!(class_gnu_classpath_Pointer64 =
217 load_class_bootstrap(utf_gnu_classpath_Pointer64)))
220 if (!link_class(class_gnu_classpath_Pointer64))
223 utf_gnu_classpath_Pointer32 = utf_new_char("gnu/classpath/Pointer32");
225 if (!(class_gnu_classpath_Pointer32 =
226 load_class_bootstrap(utf_gnu_classpath_Pointer32)))
229 if (!link_class(class_gnu_classpath_Pointer32))
237 static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
238 jni_callblock blk[], va_list data,
241 typedesc *paramtypes;
244 paramtypes = descr->paramtypes;
246 /* if method is non-static fill first block and skip `this' pointer */
251 /* the `this' pointer */
252 blk[0].itemtype = TYPE_ADR;
253 blk[0].item = PTR_TO_ITEM(obj);
259 for (; i < descr->paramcount; i++, paramtypes++) {
260 switch (paramtypes->decltype) {
261 /* primitive types */
262 case PRIMITIVETYPE_BYTE:
263 case PRIMITIVETYPE_CHAR:
264 case PRIMITIVETYPE_SHORT:
265 case PRIMITIVETYPE_BOOLEAN:
266 blk[i].itemtype = TYPE_INT;
267 blk[i].item = (s8) va_arg(data, s4);
270 case PRIMITIVETYPE_INT:
271 blk[i].itemtype = TYPE_INT;
272 blk[i].item = (s8) va_arg(data, s4);
275 case PRIMITIVETYPE_LONG:
276 blk[i].itemtype = TYPE_LNG;
277 blk[i].item = (s8) va_arg(data, s8);
280 case PRIMITIVETYPE_FLOAT:
281 blk[i].itemtype = TYPE_FLT;
282 #if defined(__ALPHA__)
283 /* this keeps the assembler function much simpler */
285 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
287 *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
291 case PRIMITIVETYPE_DOUBLE:
292 blk[i].itemtype = TYPE_DBL;
293 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
297 blk[i].itemtype = TYPE_ADR;
298 blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
303 /* The standard doesn't say anything about return value checking, but it */
304 /* appears to be useful. */
306 if (rettype != descr->returntype.decltype)
307 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
311 /* XXX it could be considered if we should do typechecking here in the future */
313 static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
315 java_objectarray *params)
319 typedesc *paramtypes;
324 paramcount = descr->paramcount;
325 paramtypes = descr->paramtypes;
327 /* if method is non-static fill first block and skip `this' pointer */
333 blk[0].itemtype = TYPE_ADR;
334 blk[0].item = PTR_TO_ITEM(obj);
341 for (j = 0; j < paramcount; i++, j++, paramtypes++) {
342 switch (paramtypes->type) {
343 /* primitive types */
348 param = params->data[j];
352 /* internally used data type */
353 blk[i].itemtype = paramtypes->type;
355 /* convert the value according to its declared type */
357 c = param->vftbl->class;
359 switch (paramtypes->decltype) {
360 case PRIMITIVETYPE_BOOLEAN:
361 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
362 blk[i].item = (s8) ((java_lang_Boolean *) param)->value;
367 case PRIMITIVETYPE_BYTE:
368 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
369 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
374 case PRIMITIVETYPE_CHAR:
375 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
376 blk[i].item = (s8) ((java_lang_Character *) param)->value;
381 case PRIMITIVETYPE_SHORT:
382 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
383 blk[i].item = (s8) ((java_lang_Short *) param)->value;
384 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
385 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
390 case PRIMITIVETYPE_INT:
391 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
392 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
393 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
394 blk[i].item = (s8) ((java_lang_Short *) param)->value;
395 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
396 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
401 case PRIMITIVETYPE_LONG:
402 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
403 blk[i].item = (s8) ((java_lang_Long *) param)->value;
404 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
405 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
406 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
407 blk[i].item = (s8) ((java_lang_Short *) param)->value;
408 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
409 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
414 case PRIMITIVETYPE_FLOAT:
415 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
416 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
421 case PRIMITIVETYPE_DOUBLE:
422 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
423 *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Float *) param)->value;
424 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
425 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
432 } /* end declared type switch */
436 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
439 if (params->data[j] != 0) {
440 if (paramtypes->arraydim > 0) {
441 if (!builtin_arrayinstanceof(params->data[j], c->vftbl))
445 if (!builtin_instanceof(params->data[j], c))
449 blk[i].itemtype = TYPE_ADR;
450 blk[i].item = PTR_TO_ITEM(params->data[j]);
455 } /* end param type switch */
457 } /* end param loop */
460 /* *rettype = descr->returntype.decltype; */
465 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
470 static jmethodID get_virtual(jobject obj, jmethodID methodID)
472 if (obj->vftbl->class == methodID->class)
475 return class_resolvemethod(obj->vftbl->class, methodID->name,
476 methodID->descriptor);
480 static jmethodID get_nonvirtual(jclass clazz, jmethodID methodID)
482 if (clazz == methodID->class)
485 /* class_resolvemethod -> classfindmethod? (JOWENN) */
486 return class_resolvemethod(clazz, methodID->name, methodID->descriptor);
490 static jobject callObjectMethod(jobject obj, jmethodID methodID, va_list args)
497 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
501 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
502 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
503 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
507 if (obj && !builtin_instanceof(obj, methodID->class)) {
508 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
512 argcount = methodID->parseddesc->paramcount;
514 blk = MNEW(jni_callblock, argcount);
516 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_ADR);
518 STATS(jnicallXmethodnvokation();)
520 ret = asm_calljavafunction2(methodID,
522 argcount * sizeof(jni_callblock),
525 MFREE(blk, jni_callblock, argcount);
532 core function for integer class methods (bool, byte, short, integer)
533 This is basically needed for i386
535 static jint callIntegerMethod(jobject obj, jmethodID methodID, int retType, va_list args)
541 STATS(jniinvokation();)
544 log_text("JNI-Call: CallObjectMethodV");
545 utf_display(methodID->name);
546 utf_display(methodID->descriptor);
547 printf("\nParmaeter count: %d\n",argcount);
548 utf_display(obj->vftbl->class->name);
552 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
556 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
557 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
558 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
562 if (obj && !builtin_instanceof(obj, methodID->class)) {
563 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
567 argcount = methodID->parseddesc->paramcount;
569 blk = MNEW(jni_callblock, argcount);
571 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
573 STATS(jnicallXmethodnvokation();)
575 ret = asm_calljavafunction2int(methodID,
577 argcount * sizeof(jni_callblock),
580 MFREE(blk, jni_callblock, argcount);
586 /* callLongMethod **************************************************************
588 Core function for long class functions.
590 *******************************************************************************/
592 static jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
598 STATS(jniinvokation();)
601 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
605 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
606 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
607 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
611 if (obj && !builtin_instanceof(obj, methodID->class)) {
612 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
616 argcount = methodID->parseddesc->paramcount;
618 blk = MNEW(jni_callblock, argcount);
620 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_LNG);
622 STATS(jnicallXmethodnvokation();)
624 ret = asm_calljavafunction2long(methodID,
626 argcount * sizeof(jni_callblock),
629 MFREE(blk, jni_callblock, argcount);
635 /*core function for float class methods (float,double)*/
636 static jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,int retType)
638 int argcount = methodID->parseddesc->paramcount;
642 STATS(jniinvokation();)
647 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
648 log_text("Too many arguments. CallObjectMethod does not support that");
652 blk = MNEW(jni_callblock, /*4 */ argcount+2);
654 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
656 /* printf("parameter: obj: %p",blk[0].item); */
657 STATS(jnicallXmethodnvokation();)
658 ret = asm_calljavafunction2double(methodID,
660 (argcount + 1) * sizeof(jni_callblock),
663 MFREE(blk, jni_callblock, argcount + 1);
664 /* printf("(CallObjectMethodV)-->%p\n",ret); */
670 static void cacao_jni_CallVoidMethod(jobject obj, jmethodID m, va_list ap)
676 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
680 if (!( ((m->flags & ACC_STATIC) && (obj == 0)) ||
681 ((!(m->flags & ACC_STATIC)) && (obj != 0)) )) {
682 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
686 if (obj && !builtin_instanceof(obj, m->class)) {
687 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
691 paramcount = m->parseddesc->paramcount;
693 /* #error XXX does not work on intrp, but on JIT */
694 if (!(m->flags & ACC_STATIC))
697 blk = MNEW(jni_callblock, paramcount);
699 fill_callblock_from_vargs(obj, m->parseddesc, blk, ap, TYPE_VOID);
701 STATS(jnicallXmethodnvokation();)
703 (void) asm_calljavafunction2(m,
705 paramcount * sizeof(jni_callblock),
708 MFREE(blk, jni_callblock, paramcount);
714 /* GetVersion ******************************************************************
716 Returns the major version number in the higher 16 bits and the
717 minor version number in the lower 16 bits.
719 *******************************************************************************/
721 jint GetVersion(JNIEnv *env)
723 STATS(jniinvokation();)
725 /* we support JNI 1.4 */
727 return JNI_VERSION_1_4;
731 /* Class Operations ***********************************************************/
733 /* DefineClass *****************************************************************
735 Loads a class from a buffer of raw class data. The buffer
736 containing the raw class data is not referenced by the VM after the
737 DefineClass call returns, and it may be discarded if desired.
739 *******************************************************************************/
741 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
742 const jbyte *buf, jsize bufLen)
744 java_lang_ClassLoader *cl;
749 STATS(jniinvokation();)
751 cl = (java_lang_ClassLoader *) loader;
752 s = javastring_new_char(name);
753 ba = (java_bytearray *) buf;
755 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
758 return (jclass) NewLocalRef(env, (jobject) c);
762 /* FindClass *******************************************************************
764 This function loads a locally-defined class. It searches the
765 directories and zip files specified by the CLASSPATH environment
766 variable for the class with the specified name.
768 *******************************************************************************/
770 jclass FindClass(JNIEnv *env, const char *name)
774 java_objectheader *cl;
776 STATS(jniinvokation();)
778 u = utf_new_char_classname((char *) name);
780 /* check stacktrace for classloader, if one found use it, otherwise use */
781 /* the system classloader */
783 #if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__)
784 /* these JITs support stacktraces, and so does the interpreter */
786 cl = cacao_currentClassLoader();
788 # if defined(ENABLE_INTRP)
789 /* the interpreter supports stacktraces, even if the JIT does not */
792 cl = cacao_currentClassLoader();
798 if (!(c = load_class_from_classloader(u, cl)))
804 if (!use_class_as_object(c))
807 return (jclass) NewLocalRef(env, (jobject) c);
811 /* FromReflectedMethod *********************************************************
813 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
814 object to a method ID.
816 *******************************************************************************/
818 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
824 STATS(jniinvokation();)
829 if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
830 java_lang_reflect_Method *rm;
832 rm = (java_lang_reflect_Method *) method;
833 c = (classinfo *) (rm->declaringClass);
836 } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
837 java_lang_reflect_Constructor *rc;
839 rc = (java_lang_reflect_Constructor *) method;
840 c = (classinfo *) (rc->clazz);
846 if ((slot < 0) || (slot >= c->methodscount)) {
847 /* this usually means a severe internal cacao error or somebody
848 tempered around with the reflected method */
849 log_text("error illegal slot for method in class(FromReflectedMethod)");
853 mi = &(c->methods[slot]);
859 /* GetSuperclass ***************************************************************
861 If clazz represents any class other than the class Object, then
862 this function returns the object that represents the superclass of
863 the class specified by clazz.
865 *******************************************************************************/
867 jclass GetSuperclass(JNIEnv *env, jclass sub)
871 STATS(jniinvokation();)
873 c = ((classinfo *) sub)->super.cls;
878 if (!use_class_as_object(c))
881 return (jclass) NewLocalRef(env, (jobject) c);
885 /* IsAssignableFrom ************************************************************
887 Determines whether an object of sub can be safely cast to sup.
889 *******************************************************************************/
891 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
893 STATS(jniinvokation();)
894 return Java_java_lang_VMClass_isAssignableFrom(env,
896 (java_lang_Class *) sup,
897 (java_lang_Class *) sub);
901 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
903 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
905 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!!!");
906 STATS(jniinvokation();)
911 /* Throw ***********************************************************************
913 Causes a java.lang.Throwable object to be thrown.
915 *******************************************************************************/
917 jint Throw(JNIEnv *env, jthrowable obj)
919 *exceptionptr = (java_objectheader *) obj;
920 STATS(jniinvokation();)
926 /* ThrowNew ********************************************************************
928 Constructs an exception object from the specified class with the
929 message specified by message and causes that exception to be
932 *******************************************************************************/
934 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
936 java_lang_Throwable *o;
938 STATS(jniinvokation();)
940 s = (java_lang_String *) javastring_new_char(msg);
942 /* instantiate exception object */
944 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
950 *exceptionptr = (java_objectheader *) o;
956 /* ExceptionOccurred ***********************************************************
958 Determines if an exception is being thrown. The exception stays
959 being thrown until either the native code calls ExceptionClear(),
960 or the Java code handles the exception.
962 *******************************************************************************/
964 jthrowable ExceptionOccurred(JNIEnv *env)
966 java_objectheader *e;
968 STATS(jniinvokation();)
972 return NewLocalRef(env, (jthrowable) e);
976 /* ExceptionDescribe ***********************************************************
978 Prints an exception and a backtrace of the stack to a system
979 error-reporting channel, such as stderr. This is a convenience
980 routine provided for debugging.
982 *******************************************************************************/
984 void ExceptionDescribe(JNIEnv *env)
986 java_objectheader *e;
988 STATS(jniinvokation();)
993 /* clear exception, because we are calling jit code again */
995 *exceptionptr = NULL;
997 /* get printStackTrace method from exception class */
999 m = class_resolveclassmethod(e->vftbl->class,
1000 utf_printStackTrace,
1006 /* XXX what should we do? */
1009 /* print the stacktrace */
1011 asm_calljavafunction(m, e, NULL, NULL, NULL);
1016 /* ExceptionClear **************************************************************
1018 Clears any exception that is currently being thrown. If no
1019 exception is currently being thrown, this routine has no effect.
1021 *******************************************************************************/
1023 void ExceptionClear(JNIEnv *env)
1025 STATS(jniinvokation();)
1027 *exceptionptr = NULL;
1031 /* FatalError ******************************************************************
1033 Raises a fatal error and does not expect the VM to recover. This
1034 function does not return.
1036 *******************************************************************************/
1038 void FatalError(JNIEnv *env, const char *msg)
1040 STATS(jniinvokation();)
1042 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
1046 /* PushLocalFrame **************************************************************
1048 Creates a new local reference frame, in which at least a given
1049 number of local references can be created.
1051 *******************************************************************************/
1053 jint PushLocalFrame(JNIEnv* env, jint capacity)
1055 STATS(jniinvokation();)
1057 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
1064 /* PopLocalFrame ***************************************************************
1066 Pops off the current local reference frame, frees all the local
1067 references, and returns a local reference in the previous local
1068 reference frame for the given result object.
1070 *******************************************************************************/
1072 jobject PopLocalFrame(JNIEnv* env, jobject result)
1074 STATS(jniinvokation();)
1076 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
1080 /* add local reference and return the value */
1082 return NewLocalRef(env, NULL);
1086 /* DeleteLocalRef **************************************************************
1088 Deletes the local reference pointed to by localRef.
1090 *******************************************************************************/
1092 void DeleteLocalRef(JNIEnv *env, jobject localRef)
1094 java_objectheader *o;
1095 localref_table *lrt;
1098 STATS(jniinvokation();)
1100 o = (java_objectheader *) localRef;
1102 /* get local reference table (thread specific) */
1104 lrt = LOCALREFTABLE;
1106 /* remove the reference */
1108 for (i = 0; i < lrt->capacity; i++) {
1109 if (lrt->refs[i] == o) {
1110 lrt->refs[i] = NULL;
1117 /* this should not happen */
1119 /* if (opt_checkjni) */
1120 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1121 log_text("JNI-DeleteLocalRef: Bad global or local ref passed to JNI");
1125 /* IsSameObject ****************************************************************
1127 Tests whether two references refer to the same Java object.
1129 *******************************************************************************/
1131 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1133 STATS(jniinvokation();)
1142 /* NewLocalRef *****************************************************************
1144 Creates a new local reference that refers to the same object as ref.
1146 *******************************************************************************/
1148 jobject NewLocalRef(JNIEnv *env, jobject ref)
1150 localref_table *lrt;
1153 STATS(jniinvokation();)
1158 /* get local reference table (thread specific) */
1160 lrt = LOCALREFTABLE;
1162 /* check if we have space for the requested reference */
1164 if (lrt->used == lrt->capacity)
1165 throw_cacao_exception_exit(string_java_lang_InternalError,
1166 "Too many local references");
1168 /* insert the reference */
1170 for (i = 0; i < lrt->capacity; i++) {
1171 if (lrt->refs[i] == NULL) {
1172 lrt->refs[i] = (java_objectheader *) ref;
1179 /* should not happen, just to be sure */
1183 /* keep compiler happy */
1189 /* EnsureLocalCapacity *********************************************************
1191 Ensures that at least a given number of local references can be
1192 created in the current thread
1194 *******************************************************************************/
1196 jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
1198 localref_table *lrt;
1200 STATS(jniinvokation();)
1202 /* get local reference table (thread specific) */
1204 lrt = LOCALREFTABLE;
1206 /* check if capacity elements are available in the local references table */
1208 if ((lrt->used + capacity) > lrt->capacity) {
1209 *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
1217 /* AllocObject *****************************************************************
1219 Allocates a new Java object without invoking any of the
1220 constructors for the object. Returns a reference to the object.
1222 *******************************************************************************/
1224 jobject AllocObject(JNIEnv *env, jclass clazz)
1226 java_objectheader *o;
1228 STATS(jniinvokation();)
1230 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1232 new_exception_utfmessage(string_java_lang_InstantiationException,
1237 o = builtin_new(clazz);
1239 return NewLocalRef(env, o);
1243 /* NewObject *******************************************************************
1245 Programmers place all arguments that are to be passed to the
1246 constructor immediately following the methodID
1247 argument. NewObject() accepts these arguments and passes them to
1248 the Java method that the programmer wishes to invoke.
1250 *******************************************************************************/
1252 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1254 java_objectheader *o;
1257 STATS(jniinvokation();)
1261 o = builtin_new(clazz);
1266 /* call constructor */
1268 va_start(ap, methodID);
1269 cacao_jni_CallVoidMethod(o, methodID, ap);
1272 return NewLocalRef(env, o);
1276 /***********************************************************************************
1278 Constructs a new Java object
1279 arguments that are to be passed to the constructor are placed in va_list args
1281 ***********************************************************************************/
1283 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1285 STATS(jniinvokation();)
1287 log_text("JNI-Call: NewObjectV: IMPLEMENT ME!");
1289 return NewLocalRef(env, NULL);
1293 /***********************************************************************************
1295 Constructs a new Java object
1296 arguments that are to be passed to the constructor are placed in
1297 args array of jvalues
1299 ***********************************************************************************/
1301 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1303 STATS(jniinvokation();)
1305 log_text("JNI-Call: NewObjectA: IMPLEMENT ME!");
1307 return NewLocalRef(env, NULL);
1311 /* GetObjectClass **************************************************************
1313 Returns the class of an object.
1315 *******************************************************************************/
1317 jclass GetObjectClass(JNIEnv *env, jobject obj)
1321 STATS(jniinvokation();)
1323 if (!obj || !obj->vftbl)
1326 c = obj->vftbl->class;
1328 if (!use_class_as_object(c))
1331 return (jclass) NewLocalRef(env, (jobject) c);
1335 /* IsInstanceOf ****************************************************************
1337 Tests whether an object is an instance of a class.
1339 *******************************************************************************/
1341 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1343 STATS(jniinvokation();)
1345 return Java_java_lang_VMClass_isInstance(env,
1347 (java_lang_Class *) clazz,
1348 (java_lang_Object *) obj);
1352 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1354 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1356 java_lang_reflect_Field *f;
1358 jfieldID fid; /* the JNI-fieldid of the wrapping object */
1359 STATS(jniinvokation();)
1360 /*log_text("JNI-Call: FromReflectedField");*/
1362 f=(java_lang_reflect_Field *)field;
1364 c=(classinfo*)(f->declaringClass);
1365 if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1366 /*this usually means a severe internal cacao error or somebody
1367 tempered around with the reflected method*/
1368 log_text("error illegal slot for field in class(FromReflectedField)");
1371 fid=&(c->fields[f->slot]);
1376 /**********************************************************************************
1378 converts a method ID to a java.lang.reflect.Method or
1379 java.lang.reflect.Constructor object
1381 **********************************************************************************/
1383 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1385 log_text("JNI-Call: ToReflectedMethod");
1386 STATS(jniinvokation();)
1392 /* Calling Instance Methods ***************************************************/
1394 /* GetMethodID *****************************************************************
1396 Returns the method ID for an instance (nonstatic) method of a class
1397 or interface. The method may be defined in one of the clazz's
1398 superclasses and inherited by clazz. The method is determined by
1399 its name and signature.
1401 GetMethodID() causes an uninitialized class to be initialized.
1403 *******************************************************************************/
1405 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1411 STATS(jniinvokation();)
1413 c = (classinfo *) clazz;
1418 if (!c->initialized)
1419 if (!initialize_class(c))
1422 /* try to get the method of the class or one of it's superclasses */
1424 m = class_resolvemethod(clazz,
1425 utf_new_char((char *) name),
1426 utf_new_char((char *) sig));
1428 if (!m || (m->flags & ACC_STATIC)) {
1430 new_exception_message(string_java_lang_NoSuchMethodError, name);
1439 /******************** JNI-functions for calling instance methods ******************/
1441 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1443 java_objectheader* ret;
1446 STATS(jniinvokation();)
1448 va_start(vaargs, methodID);
1449 ret = callObjectMethod(obj, methodID, vaargs);
1452 return NewLocalRef(env, ret);
1456 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1458 java_objectheader* ret;
1460 STATS(jniinvokation();)
1462 ret = callObjectMethod(obj, methodID, args);
1464 return NewLocalRef(env, ret);
1468 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1470 STATS(jniinvokation();)
1472 log_text("JNI-Call: CallObjectMethodA: IMPLEMENT ME!");
1474 return NewLocalRef(env, NULL);
1480 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1484 STATS(jniinvokation();)
1486 /* log_text("JNI-Call: CallBooleanMethod");*/
1488 va_start(vaargs,methodID);
1489 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1495 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1497 STATS(jniinvokation();)
1499 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
1503 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1505 STATS(jniinvokation();)
1506 log_text("JNI-Call: CallBooleanMethodA");
1511 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1515 STATS(jniinvokation();)
1517 /* log_text("JNI-Call: CallVyteMethod");*/
1519 va_start(vaargs,methodID);
1520 ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
1526 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1528 /* log_text("JNI-Call: CallByteMethodV");*/
1529 STATS(jniinvokation();)
1531 return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
1535 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1537 log_text("JNI-Call: CallByteMethodA");
1538 STATS(jniinvokation();)
1544 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1548 STATS(jniinvokation();)
1550 /* log_text("JNI-Call: CallCharMethod");*/
1552 va_start(vaargs,methodID);
1553 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
1560 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1562 STATS(jniinvokation();)
1564 /* log_text("JNI-Call: CallCharMethodV");*/
1565 return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
1569 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1571 STATS(jniinvokation();)
1573 log_text("JNI-Call: CallCharMethodA");
1579 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1583 STATS(jniinvokation();)
1585 /* log_text("JNI-Call: CallShortMethod");*/
1587 va_start(vaargs, methodID);
1588 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
1595 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1597 STATS(jniinvokation();)
1598 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
1602 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1604 STATS(jniinvokation();)
1605 log_text("JNI-Call: CallShortMethodA");
1612 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1616 STATS(jniinvokation();)
1618 va_start(vaargs,methodID);
1619 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
1626 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1628 STATS(jniinvokation();)
1629 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
1633 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1635 STATS(jniinvokation();)
1636 log_text("JNI-Call: CallIntMethodA");
1643 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1647 STATS(jniinvokation();)
1649 va_start(vaargs,methodID);
1650 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1657 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1659 STATS(jniinvokation();)
1660 return callLongMethod(obj,get_virtual(obj, methodID),args);
1664 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1666 STATS(jniinvokation();)
1667 log_text("JNI-Call: CallLongMethodA");
1674 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1679 STATS(jniinvokation();)
1680 /* log_text("JNI-Call: CallFloatMethod");*/
1682 va_start(vaargs,methodID);
1683 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
1690 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1692 STATS(jniinvokation();)
1693 log_text("JNI-Call: CallFloatMethodV");
1694 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
1698 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1700 STATS(jniinvokation();)
1701 log_text("JNI-Call: CallFloatMethodA");
1708 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1712 STATS(jniinvokation();)
1714 /* log_text("JNI-Call: CallDoubleMethod");*/
1716 va_start(vaargs,methodID);
1717 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
1724 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1726 STATS(jniinvokation();)
1727 log_text("JNI-Call: CallDoubleMethodV");
1728 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
1732 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1734 STATS(jniinvokation();)
1735 log_text("JNI-Call: CallDoubleMethodA");
1741 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1744 STATS(jniinvokation();)
1746 va_start(vaargs,methodID);
1747 (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
1752 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1754 log_text("JNI-Call: CallVoidMethodV");
1755 STATS(jniinvokation();)
1756 (void)callIntegerMethod(obj,get_virtual(obj,methodID),TYPE_VOID,args);
1760 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1762 STATS(jniinvokation();)
1763 log_text("JNI-Call: CallVoidMethodA");
1768 jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1770 STATS(jniinvokation();)
1772 log_text("JNI-Call: CallNonvirtualObjectMethod: IMPLEMENT ME!");
1774 return NewLocalRef(env, NULL);
1778 jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1780 STATS(jniinvokation();)
1782 log_text("JNI-Call: CallNonvirtualObjectMethodV: IMPLEMENT ME!");
1784 return NewLocalRef(env, NULL);
1788 jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1790 STATS(jniinvokation();)
1792 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1794 return NewLocalRef(env, NULL);
1799 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1803 STATS(jniinvokation();)
1805 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1807 va_start(vaargs,methodID);
1808 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1815 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1817 STATS(jniinvokation();)
1818 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1819 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
1823 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1825 STATS(jniinvokation();)
1826 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1833 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1838 STATS(jniinvokation();)
1839 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1841 va_start(vaargs,methodID);
1842 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
1848 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1850 STATS(jniinvokation();)
1851 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1852 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
1857 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1859 STATS(jniinvokation();)
1860 log_text("JNI-Call: CallNonvirtualByteMethodA");
1867 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1872 STATS(jniinvokation();)
1873 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1875 va_start(vaargs,methodID);
1876 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
1882 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1884 STATS(jniinvokation();)
1885 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1886 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
1890 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1892 STATS(jniinvokation();)
1893 log_text("JNI-Call: CallNonvirtualCharMethodA");
1900 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1904 STATS(jniinvokation();)
1906 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1908 va_start(vaargs,methodID);
1909 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
1915 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1917 STATS(jniinvokation();)
1918 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1919 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
1923 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1925 STATS(jniinvokation();)
1926 log_text("JNI-Call: CallNonvirtualShortMethodA");
1933 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1938 STATS(jniinvokation();)
1940 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1942 va_start(vaargs,methodID);
1943 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
1949 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1951 STATS(jniinvokation();)
1952 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1953 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
1957 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1959 STATS(jniinvokation();)
1960 log_text("JNI-Call: CallNonvirtualIntMethodA");
1967 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1969 STATS(jniinvokation();)
1970 log_text("JNI-Call: CallNonvirtualLongMethod");
1976 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1978 STATS(jniinvokation();)
1979 log_text("JNI-Call: CallNonvirtualLongMethodV");
1985 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1987 STATS(jniinvokation();)
1988 log_text("JNI-Call: CallNonvirtualLongMethodA");
1995 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1999 STATS(jniinvokation();)
2001 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
2004 va_start(vaargs,methodID);
2005 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
2012 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2014 STATS(jniinvokation();)
2015 log_text("JNI-Call: CallNonvirtualFloatMethodV");
2016 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
2020 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2022 STATS(jniinvokation();)
2023 log_text("JNI-Call: CallNonvirtualFloatMethodA");
2030 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2034 STATS(jniinvokation();)
2035 log_text("JNI-Call: CallNonvirtualDoubleMethod");
2037 va_start(vaargs,methodID);
2038 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
2045 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2047 STATS(jniinvokation();)
2048 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
2049 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
2053 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2055 STATS(jniinvokation();)
2056 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
2063 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2066 STATS(jniinvokation();)
2068 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
2070 va_start(vaargs,methodID);
2071 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
2077 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2079 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
2080 STATS(jniinvokation();)
2082 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
2087 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
2089 STATS(jniinvokation();)
2090 log_text("JNI-Call: CallNonvirtualVoidMethodA");
2093 /************************* JNI-functions for accessing fields ************************/
2095 jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2099 STATS(jniinvokation();)
2101 f = class_findfield(clazz, utf_new_char((char *) name), utf_new_char((char *) sig));
2104 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2109 /*************************** retrieve fieldid, abort on error ************************/
2111 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
2113 jfieldID id = GetFieldID(env, clazz, name, sig);
2114 STATS(jniinvokation();)
2118 utf_display(clazz->name);
2119 log_text("\nfield:");
2124 log_text("setfield_critical failed");
2130 jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2132 java_objectheader *o;
2134 STATS(jniinvokation();)
2136 o = getField(obj, java_objectheader*, fieldID);
2138 return NewLocalRef(env, o);
2141 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
2143 STATS(jniinvokation();)
2144 return getField(obj,jboolean,fieldID);
2148 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
2150 STATS(jniinvokation();)
2151 return getField(obj,jbyte,fieldID);
2155 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
2157 STATS(jniinvokation();)
2158 return getField(obj,jchar,fieldID);
2162 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
2164 STATS(jniinvokation();)
2165 return getField(obj,jshort,fieldID);
2169 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
2171 STATS(jniinvokation();)
2172 return getField(obj,jint,fieldID);
2176 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
2178 STATS(jniinvokation();)
2179 return getField(obj,jlong,fieldID);
2183 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
2185 STATS(jniinvokation();)
2186 return getField(obj,jfloat,fieldID);
2190 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
2192 STATS(jniinvokation();)
2193 return getField(obj,jdouble,fieldID);
2196 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
2198 STATS(jniinvokation();)
2199 setField(obj,jobject,fieldID,val);
2203 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
2205 STATS(jniinvokation();)
2206 setField(obj,jboolean,fieldID,val);
2210 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
2212 STATS(jniinvokation();)
2213 setField(obj,jbyte,fieldID,val);
2217 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
2219 STATS(jniinvokation();)
2220 setField(obj,jchar,fieldID,val);
2224 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
2226 STATS(jniinvokation();)
2227 setField(obj,jshort,fieldID,val);
2231 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
2233 STATS(jniinvokation();)
2234 setField(obj,jint,fieldID,val);
2238 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
2240 STATS(jniinvokation();)
2241 setField(obj,jlong,fieldID,val);
2245 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
2247 STATS(jniinvokation();)
2248 setField(obj,jfloat,fieldID,val);
2252 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
2254 STATS(jniinvokation();)
2255 setField(obj,jdouble,fieldID,val);
2259 /* Calling Static Methods *****************************************************/
2261 /* GetStaticMethodID ***********************************************************
2263 Returns the method ID for a static method of a class. The method is
2264 specified by its name and signature.
2266 GetStaticMethodID() causes an uninitialized class to be
2269 *******************************************************************************/
2271 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2277 STATS(jniinvokation();)
2279 c = (classinfo *) clazz;
2284 if (!c->initialized)
2285 if (!initialize_class(c))
2288 /* try to get the static method of the class */
2290 m = class_resolvemethod(clazz,
2291 utf_new_char((char *) name),
2292 utf_new_char((char *) sig));
2294 if (!m || !(m->flags & ACC_STATIC)) {
2296 new_exception_message(string_java_lang_NoSuchMethodError, name);
2305 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2307 java_objectheader *ret;
2310 STATS(jniinvokation();)
2312 va_start(vaargs, methodID);
2313 ret = callObjectMethod(0, methodID, vaargs);
2316 return NewLocalRef(env, ret);
2320 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2322 java_objectheader *ret;
2324 STATS(jniinvokation();)
2326 ret = callObjectMethod(0, methodID, args);
2328 return NewLocalRef(env, ret);
2332 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2334 STATS(jniinvokation();)
2336 log_text("JNI-Call: CallStaticObjectMethodA: IMPLEMENT ME!");
2338 return NewLocalRef(env, NULL);
2342 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2347 STATS(jniinvokation();)
2349 va_start(vaargs, methodID);
2350 ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
2357 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2359 STATS(jniinvokation();)
2361 return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
2365 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2367 STATS(jniinvokation();)
2369 log_text("JNI-Call: CallStaticBooleanMethodA: IMPLEMENT ME!");
2375 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2380 STATS(jniinvokation();)
2382 va_start(vaargs, methodID);
2383 ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
2390 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2392 STATS(jniinvokation();)
2393 return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
2397 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2399 STATS(jniinvokation();)
2401 log_text("JNI-Call: CallStaticByteMethodA: IMPLEMENT ME!");
2407 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2412 STATS(jniinvokation();)
2414 va_start(vaargs, methodID);
2415 ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
2422 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2424 STATS(jniinvokation();)
2426 return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
2430 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2432 STATS(jniinvokation();)
2434 log_text("JNI-Call: CallStaticCharMethodA: IMPLEMENT ME!");
2440 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2445 STATS(jniinvokation();)
2447 va_start(vaargs, methodID);
2448 ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
2455 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2457 STATS(jniinvokation();)
2459 return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
2463 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2465 STATS(jniinvokation();)
2467 log_text("JNI-Call: CallStaticShortMethodA: IMPLEMENT ME!");
2473 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2478 STATS(jniinvokation();)
2480 va_start(vaargs, methodID);
2481 ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
2488 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2490 STATS(jniinvokation();)
2492 return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
2496 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2498 STATS(jniinvokation();)
2500 log_text("JNI-Call: CallStaticIntMethodA: IMPLEMENT ME!");
2506 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2511 STATS(jniinvokation();)
2513 va_start(vaargs, methodID);
2514 ret = callLongMethod(0, methodID, vaargs);
2521 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
2524 STATS(jniinvokation();)
2526 return callLongMethod(0, methodID, args);
2530 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2532 STATS(jniinvokation();)
2534 log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!");
2541 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2546 STATS(jniinvokation();)
2548 va_start(vaargs, methodID);
2549 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
2556 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2558 STATS(jniinvokation();)
2560 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
2565 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2567 STATS(jniinvokation();)
2569 log_text("JNI-Call: CallStaticFloatMethodA: IMPLEMENT ME!");
2575 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2580 STATS(jniinvokation();)
2582 va_start(vaargs,methodID);
2583 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
2590 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2592 STATS(jniinvokation();)
2594 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
2598 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2600 STATS(jniinvokation();)
2602 log_text("JNI-Call: CallStaticDoubleMethodA: IMPLEMENT ME!");
2608 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2612 STATS(jniinvokation();)
2614 va_start(vaargs, methodID);
2615 (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
2620 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2622 STATS(jniinvokation();)
2624 (void) callIntegerMethod(0, methodID, TYPE_VOID, args);
2628 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2630 STATS(jniinvokation();)
2632 log_text("JNI-Call: CallStaticVoidMethodA: IMPLEMENT ME!");
2636 /* Accessing Static Fields ****************************************************/
2638 /* GetStaticFieldID ************************************************************
2640 Returns the field ID for a static field of a class. The field is
2641 specified by its name and signature. The GetStatic<type>Field and
2642 SetStatic<type>Field families of accessor functions use field IDs
2643 to retrieve static fields.
2645 *******************************************************************************/
2647 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2650 STATS(jniinvokation();)
2652 f = class_findfield(clazz,
2653 utf_new_char((char *) name),
2654 utf_new_char((char *) sig));
2657 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2663 /* GetStatic<type>Field ********************************************************
2665 This family of accessor routines returns the value of a static
2668 *******************************************************************************/
2670 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2672 STATS(jniinvokation();)
2674 if (!clazz->initialized)
2675 if (!initialize_class(clazz))
2678 return NewLocalRef(env, fieldID->value.a);
2682 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2684 STATS(jniinvokation();)
2686 if (!clazz->initialized)
2687 if (!initialize_class(clazz))
2690 return fieldID->value.i;
2694 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2696 STATS(jniinvokation();)
2698 if (!clazz->initialized)
2699 if (!initialize_class(clazz))
2702 return fieldID->value.i;
2706 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2708 STATS(jniinvokation();)
2710 if (!clazz->initialized)
2711 if (!initialize_class(clazz))
2714 return fieldID->value.i;
2718 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2720 STATS(jniinvokation();)
2722 if (!clazz->initialized)
2723 if (!initialize_class(clazz))
2726 return fieldID->value.i;
2730 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2732 STATS(jniinvokation();)
2734 if (!clazz->initialized)
2735 if (!initialize_class(clazz))
2738 return fieldID->value.i;
2742 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2744 STATS(jniinvokation();)
2746 if (!clazz->initialized)
2747 if (!initialize_class(clazz))
2750 return fieldID->value.l;
2754 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2756 STATS(jniinvokation();)
2758 if (!clazz->initialized)
2759 if (!initialize_class(clazz))
2762 return fieldID->value.f;
2766 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2768 STATS(jniinvokation();)
2770 if (!clazz->initialized)
2771 if (!initialize_class(clazz))
2774 return fieldID->value.d;
2778 /* SetStatic<type>Field *******************************************************
2780 This family of accessor routines sets the value of a static field
2783 *******************************************************************************/
2785 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2787 STATS(jniinvokation();)
2789 if (!clazz->initialized)
2790 if (!initialize_class(clazz))
2793 fieldID->value.a = value;
2797 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2799 STATS(jniinvokation();)
2801 if (!clazz->initialized)
2802 if (!initialize_class(clazz))
2805 fieldID->value.i = value;
2809 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2811 STATS(jniinvokation();)
2813 if (!clazz->initialized)
2814 if (!initialize_class(clazz))
2817 fieldID->value.i = value;
2821 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2823 STATS(jniinvokation();)
2825 if (!clazz->initialized)
2826 if (!initialize_class(clazz))
2829 fieldID->value.i = value;
2833 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2835 STATS(jniinvokation();)
2837 if (!clazz->initialized)
2838 if (!initialize_class(clazz))
2841 fieldID->value.i = value;
2845 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2847 STATS(jniinvokation();)
2849 if (!clazz->initialized)
2850 if (!initialize_class(clazz))
2853 fieldID->value.i = value;
2857 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2859 STATS(jniinvokation();)
2861 if (!clazz->initialized)
2862 if (!initialize_class(clazz))
2865 fieldID->value.l = value;
2869 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2871 STATS(jniinvokation();)
2873 if (!clazz->initialized)
2874 if (!initialize_class(clazz))
2877 fieldID->value.f = value;
2881 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2883 STATS(jniinvokation();)
2885 if (!clazz->initialized)
2886 if (!initialize_class(clazz))
2889 fieldID->value.d = value;
2893 /* String Operations **********************************************************/
2895 /* NewString *******************************************************************
2897 Create new java.lang.String object from an array of Unicode
2900 *******************************************************************************/
2902 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
2904 java_lang_String *s;
2908 STATS(jniinvokation();)
2910 s = (java_lang_String *) builtin_new(class_java_lang_String);
2911 a = builtin_newarray_char(len);
2913 /* javastring or characterarray could not be created */
2918 for (i = 0; i < len; i++)
2919 a->data[i] = buf[i];
2925 return (jstring) NewLocalRef(env, (jobject) s);
2929 static jchar emptyStringJ[]={0,0};
2931 /* GetStringLength *************************************************************
2933 Returns the length (the count of Unicode characters) of a Java
2936 *******************************************************************************/
2938 jsize GetStringLength(JNIEnv *env, jstring str)
2940 return ((java_lang_String *) str)->count;
2944 /******************** convertes javastring to u2-array ****************************/
2946 u2 *javastring_tou2(jstring so)
2948 java_lang_String *s;
2953 STATS(jniinvokation();)
2955 s = (java_lang_String *) so;
2965 /* allocate memory */
2967 stringbuffer = MNEW(u2, s->count + 1);
2971 for (i = 0; i < s->count; i++)
2972 stringbuffer[i] = a->data[s->offset + i];
2974 /* terminate string */
2976 stringbuffer[i] = '\0';
2978 return stringbuffer;
2982 /* GetStringChars **************************************************************
2984 Returns a pointer to the array of Unicode characters of the
2985 string. This pointer is valid until ReleaseStringchars() is called.
2987 *******************************************************************************/
2989 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2993 STATS(jniinvokation();)
2995 jc = javastring_tou2(str);
3007 return emptyStringJ;
3011 /* ReleaseStringChars **********************************************************
3013 Informs the VM that the native code no longer needs access to
3014 chars. The chars argument is a pointer obtained from string using
3017 *******************************************************************************/
3019 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
3021 STATS(jniinvokation();)
3023 if (chars == emptyStringJ)
3026 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
3030 /* NewStringUTF ****************************************************************
3032 Constructs a new java.lang.String object from an array of UTF-8 characters.
3034 *******************************************************************************/
3036 jstring NewStringUTF(JNIEnv *env, const char *bytes)
3038 java_lang_String *s;
3040 STATS(jniinvokation();)
3042 s = javastring_new(utf_new_char(bytes));
3044 return (jstring) NewLocalRef(env, (jobject) s);
3048 /****************** returns the utf8 length in bytes of a string *******************/
3050 jsize GetStringUTFLength (JNIEnv *env, jstring string)
3052 java_lang_String *s = (java_lang_String*) string;
3053 STATS(jniinvokation();)
3055 return (jsize) u2_utflength(s->value->data, s->count);
3059 /* GetStringUTFChars ***********************************************************
3061 Returns a pointer to an array of UTF-8 characters of the
3062 string. This array is valid until it is released by
3063 ReleaseStringUTFChars().
3065 *******************************************************************************/
3067 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
3070 STATS(jniinvokation();)
3078 u = javastring_toutf((java_lang_String *) string, false);
3087 /* ReleaseStringUTFChars *******************************************************
3089 Informs the VM that the native code no longer needs access to
3090 utf. The utf argument is a pointer derived from string using
3091 GetStringUTFChars().
3093 *******************************************************************************/
3095 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
3097 STATS(jniinvokation();)
3099 /* XXX we don't release utf chars right now, perhaps that should be done
3100 later. Since there is always one reference the garbage collector will
3105 /* Array Operations ***********************************************************/
3107 /* GetArrayLength **************************************************************
3109 Returns the number of elements in the array.
3111 *******************************************************************************/
3113 jsize GetArrayLength(JNIEnv *env, jarray array)
3115 STATS(jniinvokation();)
3121 /* NewObjectArray **************************************************************
3123 Constructs a new array holding objects in class elementClass. All
3124 elements are initially set to initialElement.
3126 *******************************************************************************/
3128 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
3130 java_objectarray *oa;
3133 STATS(jniinvokation();)
3136 *exceptionptr = new_negativearraysizeexception();
3140 oa = builtin_anewarray(length, elementClass);
3145 /* set all elements to initialElement */
3147 for (i = 0; i < length; i++)
3148 oa->data[i] = initialElement;
3150 return (jobjectArray) NewLocalRef(env, (jobject) oa);
3154 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
3158 STATS(jniinvokation();)
3160 if (index >= array->header.size) {
3162 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3166 o = array->data[index];
3168 return NewLocalRef(env, o);
3172 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3174 STATS(jniinvokation();)
3175 if (index >= array->header.size)
3176 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3179 /* check if the class of value is a subclass of the element class of the array */
3180 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
3181 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3184 array->data[index] = val;
3189 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3191 java_booleanarray *ba;
3193 STATS(jniinvokation();)
3196 *exceptionptr = new_negativearraysizeexception();
3200 ba = builtin_newarray_boolean(len);
3202 return (jbooleanArray) NewLocalRef(env, (jobject) ba);
3206 jbyteArray NewByteArray(JNIEnv *env, jsize len)
3210 STATS(jniinvokation();)
3213 *exceptionptr = new_negativearraysizeexception();
3217 ba = builtin_newarray_byte(len);
3219 return (jbyteArray) NewLocalRef(env, (jobject) ba);
3223 jcharArray NewCharArray(JNIEnv *env, jsize len)
3227 STATS(jniinvokation();)
3230 *exceptionptr = new_negativearraysizeexception();
3234 ca = builtin_newarray_char(len);
3236 return (jcharArray) NewLocalRef(env, (jobject) ca);
3240 jshortArray NewShortArray(JNIEnv *env, jsize len)
3242 java_shortarray *sa;
3244 STATS(jniinvokation();)
3247 *exceptionptr = new_negativearraysizeexception();
3251 sa = builtin_newarray_short(len);
3253 return (jshortArray) NewLocalRef(env, (jobject) sa);
3257 jintArray NewIntArray(JNIEnv *env, jsize len)
3261 STATS(jniinvokation();)
3264 *exceptionptr = new_negativearraysizeexception();
3268 ia = builtin_newarray_int(len);
3270 return (jintArray) NewLocalRef(env, (jobject) ia);
3274 jlongArray NewLongArray(JNIEnv *env, jsize len)
3278 STATS(jniinvokation();)
3281 *exceptionptr = new_negativearraysizeexception();
3285 la = builtin_newarray_long(len);
3287 return (jlongArray) NewLocalRef(env, (jobject) la);
3291 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3293 java_floatarray *fa;
3295 STATS(jniinvokation();)
3298 *exceptionptr = new_negativearraysizeexception();
3302 fa = builtin_newarray_float(len);
3304 return (jfloatArray) NewLocalRef(env, (jobject) fa);
3308 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3310 java_doublearray *da;
3312 STATS(jniinvokation();)
3315 *exceptionptr = new_negativearraysizeexception();
3319 da = builtin_newarray_double(len);
3321 return (jdoubleArray) NewLocalRef(env, (jobject) da);
3325 /* Get<PrimitiveType>ArrayElements *********************************************
3327 A family of functions that returns the body of the primitive array.
3329 *******************************************************************************/
3331 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3334 STATS(jniinvokation();)
3337 *isCopy = JNI_FALSE;
3343 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3345 STATS(jniinvokation();)
3348 *isCopy = JNI_FALSE;
3354 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3356 STATS(jniinvokation();)
3359 *isCopy = JNI_FALSE;
3365 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3367 STATS(jniinvokation();)
3370 *isCopy = JNI_FALSE;
3376 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3378 STATS(jniinvokation();)
3381 *isCopy = JNI_FALSE;
3387 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3389 STATS(jniinvokation();)
3392 *isCopy = JNI_FALSE;
3398 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3400 STATS(jniinvokation();)
3403 *isCopy = JNI_FALSE;
3409 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3412 STATS(jniinvokation();)
3415 *isCopy = JNI_FALSE;
3421 /* Release<PrimitiveType>ArrayElements *****************************************
3423 A family of functions that informs the VM that the native code no
3424 longer needs access to elems. The elems argument is a pointer
3425 derived from array using the corresponding
3426 Get<PrimitiveType>ArrayElements() function. If necessary, this
3427 function copies back all changes made to elems to the original
3430 *******************************************************************************/
3432 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3433 jboolean *elems, jint mode)
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 ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *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 ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *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 ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *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 ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *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 ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
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 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
3567 STATS(jniinvokation();)
3569 if (elems != array->data) {
3572 MCOPY(array->data, elems, jboolean, array->header.size);
3575 MCOPY(array->data, elems, jboolean, array->header.size);
3576 /* XXX TWISTI how should it be freed? */
3579 /* XXX TWISTI how should it be freed? */
3586 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3587 jdouble *elems, jint mode)
3589 STATS(jniinvokation();)
3591 if (elems != array->data) {
3594 MCOPY(array->data, elems, jboolean, array->header.size);
3597 MCOPY(array->data, elems, jboolean, array->header.size);
3598 /* XXX TWISTI how should it be freed? */
3601 /* XXX TWISTI how should it be freed? */
3608 /* Get<PrimitiveType>ArrayRegion **********************************************
3610 A family of functions that copies a region of a primitive array
3613 *******************************************************************************/
3615 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3616 jsize len, jboolean *buf)
3618 STATS(jniinvokation();)
3620 if (start < 0 || len < 0 || start + len > array->header.size)
3622 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3625 MCOPY(buf, &array->data[start], jboolean, len);
3629 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3632 STATS(jniinvokation();)
3634 if (start < 0 || len < 0 || start + len > array->header.size)
3636 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3639 MCOPY(buf, &array->data[start], jbyte, len);
3643 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3646 STATS(jniinvokation();)
3648 if (start < 0 || len < 0 || start + len > array->header.size)
3650 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3653 MCOPY(buf, &array->data[start], jchar, len);
3657 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3658 jsize len, jshort *buf)
3660 STATS(jniinvokation();)
3662 if (start < 0 || len < 0 || start + len > array->header.size)
3664 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3667 MCOPY(buf, &array->data[start], jshort, len);
3671 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3674 STATS(jniinvokation();)
3676 if (start < 0 || len < 0 || start + len > array->header.size)
3678 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3681 MCOPY(buf, &array->data[start], jint, len);
3685 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
3688 STATS(jniinvokation();)
3690 if (start < 0 || len < 0 || start + len > array->header.size)
3692 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3695 MCOPY(buf, &array->data[start], jlong, len);
3699 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3700 jsize len, jfloat *buf)
3702 STATS(jniinvokation();)
3704 if (start < 0 || len < 0 || start + len > array->header.size)
3706 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3709 MCOPY(buf, &array->data[start], jfloat, len);
3713 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3714 jsize len, jdouble *buf)
3716 STATS(jniinvokation();)
3718 if (start < 0 || len < 0 || start+len>array->header.size)
3720 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3723 MCOPY(buf, &array->data[start], jdouble, len);
3727 /* Set<PrimitiveType>ArrayRegion **********************************************
3729 A family of functions that copies back a region of a primitive
3730 array from a buffer.
3732 *******************************************************************************/
3734 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3735 jsize len, jboolean *buf)
3737 STATS(jniinvokation();)
3739 if (start < 0 || len < 0 || start + len > array->header.size)
3741 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3744 MCOPY(&array->data[start], buf, jboolean, len);
3748 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3751 STATS(jniinvokation();)
3753 if (start < 0 || len < 0 || start + len > array->header.size)
3755 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3758 MCOPY(&array->data[start], buf, jbyte, len);
3762 void SetCharArrayRegion(JNIEnv *env, jcharArray 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, jchar, len);
3777 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3778 jsize len, jshort *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, jshort, len);
3791 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3794 STATS(jniinvokation();)
3796 if (start < 0 || len < 0 || start + len > array->header.size)
3798 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3801 MCOPY(&array->data[start], buf, jint, len);
3806 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
3809 STATS(jniinvokation();)
3811 if (start < 0 || len < 0 || start + len > array->header.size)
3813 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3816 MCOPY(&array->data[start], buf, jlong, len);
3821 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3822 jsize len, jfloat *buf)
3824 STATS(jniinvokation();)
3826 if (start < 0 || len < 0 || start + len > array->header.size)
3828 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3831 MCOPY(&array->data[start], buf, jfloat, len);
3836 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3837 jsize len, jdouble *buf)
3839 STATS(jniinvokation();)
3841 if (start < 0 || len < 0 || start + len > array->header.size)
3843 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3846 MCOPY(&array->data[start], buf, jdouble, len);
3850 /* Registering Native Methods *************************************************/
3852 /* RegisterNatives *************************************************************
3854 Registers native methods with the class specified by the clazz
3855 argument. The methods parameter specifies an array of
3856 JNINativeMethod structures that contain the names, signatures, and
3857 function pointers of the native methods. The nMethods parameter
3858 specifies the number of native methods in the array.
3860 *******************************************************************************/
3862 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
3865 STATS(jniinvokation();)
3867 log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
3873 /* UnregisterNatives ***********************************************************
3875 Unregisters native methods of a class. The class goes back to the
3876 state before it was linked or registered with its native method
3879 This function should not be used in normal native code. Instead, it
3880 provides special programs a way to reload and relink native
3883 *******************************************************************************/
3885 jint UnregisterNatives(JNIEnv *env, jclass clazz)
3887 STATS(jniinvokation();)
3889 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3891 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3897 /* Monitor Operations *********************************************************/
3899 /* MonitorEnter ****************************************************************
3901 Enters the monitor associated with the underlying Java object
3904 *******************************************************************************/
3906 jint MonitorEnter(JNIEnv *env, jobject obj)
3908 STATS(jniinvokation();)
3911 *exceptionptr = new_nullpointerexception();
3915 #if defined(USE_THREADS)
3916 builtin_monitorenter(obj);
3923 /* MonitorExit *****************************************************************
3925 The current thread must be the owner of the monitor associated with
3926 the underlying Java object referred to by obj. The thread
3927 decrements the counter indicating the number of times it has
3928 entered this monitor. If the value of the counter becomes zero, the
3929 current thread releases the monitor.
3931 *******************************************************************************/
3933 jint MonitorExit(JNIEnv *env, jobject obj)
3935 STATS(jniinvokation();)
3937 *exceptionptr = new_nullpointerexception();
3941 #if defined(USE_THREADS)
3942 builtin_monitorexit(obj);
3949 /* JavaVM Interface ***********************************************************/
3951 /* GetJavaVM *******************************************************************
3953 Returns the Java VM interface (used in the Invocation API)
3954 associated with the current thread. The result is placed at the
3955 location pointed to by the second argument, vm.
3957 *******************************************************************************/
3959 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
3961 STATS(jniinvokation();)
3968 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3970 STATS(jniinvokation();)
3971 log_text("JNI-Call: GetStringRegion");
3975 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3977 STATS(jniinvokation();)
3978 log_text("JNI-Call: GetStringUTFRegion");
3982 /* GetPrimitiveArrayCritical ***************************************************
3984 Obtain a direct pointer to array elements.
3986 *******************************************************************************/
3988 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3990 /* do the same as Kaffe does */
3992 return GetByteArrayElements(env, (jbyteArray) array, isCopy);
3996 /* ReleasePrimitiveArrayCritical ***********************************************
3998 No specific documentation.
4000 *******************************************************************************/
4002 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
4005 STATS(jniinvokation();)
4007 /* do the same as Kaffe does */
4009 ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
4013 /* GetStringCritical ***********************************************************
4015 The semantics of these two functions are similar to the existing
4016 Get/ReleaseStringChars functions.
4018 *******************************************************************************/
4020 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
4022 STATS(jniinvokation();)
4024 return GetStringChars(env, string, isCopy);
4028 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
4030 STATS(jniinvokation();)
4032 ReleaseStringChars(env, string, cstring);
4036 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
4038 STATS(jniinvokation();)
4039 log_text("JNI-Call: NewWeakGlobalRef");
4045 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
4047 STATS(jniinvokation();)
4048 log_text("JNI-Call: DeleteWeakGlobalRef");
4054 /* NewGlobalRef ****************************************************************
4056 Creates a new global reference to the object referred to by the obj
4059 *******************************************************************************/
4061 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4063 java_lang_Integer *refcount;
4064 java_objectheader *newval;
4066 STATS(jniinvokation();)
4068 #if defined(USE_THREADS)
4069 builtin_monitorenter(*global_ref_table);
4072 refcount = (java_lang_Integer *)
4073 asm_calljavafunction(getmid, *global_ref_table, lobj, NULL, NULL);
4075 if (refcount == NULL) {
4076 newval = native_new_and_init_int(class_java_lang_Integer, 1);
4078 if (newval == NULL) {
4079 #if defined(USE_THREADS)
4080 builtin_monitorexit(*global_ref_table);
4085 asm_calljavafunction(putmid, *global_ref_table, lobj, newval, NULL);
4088 /* we can access the object itself, as we are in a
4089 synchronized section */
4094 #if defined(USE_THREADS)
4095 builtin_monitorexit(*global_ref_table);
4102 /* DeleteGlobalRef *************************************************************
4104 Deletes the global reference pointed to by globalRef.
4106 *******************************************************************************/
4108 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
4110 java_lang_Integer *refcount;
4113 STATS(jniinvokation();)
4115 #if defined(USE_THREADS)
4116 builtin_monitorenter(*global_ref_table);
4119 refcount = (java_lang_Integer *)
4120 asm_calljavafunction(getmid, *global_ref_table, globalRef, NULL, NULL);
4122 if (refcount == NULL) {
4123 log_text("JNI-DeleteGlobalRef: unable to find global reference");
4127 /* we can access the object itself, as we are in a synchronized
4130 val = refcount->value - 1;
4133 asm_calljavafunction(removemid, *global_ref_table, refcount, NULL,
4137 /* we do not create a new object, but set the new value into
4140 refcount->value = val;
4143 #if defined(USE_THREADS)
4144 builtin_monitorexit(*global_ref_table);
4149 /* ExceptionCheck **************************************************************
4151 Returns JNI_TRUE when there is a pending exception; otherwise,
4154 *******************************************************************************/
4156 jboolean ExceptionCheck(JNIEnv *env)
4158 STATS(jniinvokation();)
4159 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
4163 /* New JNI 1.4 functions ******************************************************/
4165 /* NewDirectByteBuffer *********************************************************
4167 Allocates and returns a direct java.nio.ByteBuffer referring to the
4168 block of memory starting at the memory address address and
4169 extending capacity bytes.
4171 *******************************************************************************/
4173 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
4175 java_nio_DirectByteBufferImpl *nbuf;
4176 #if SIZEOF_VOID_P == 8
4177 gnu_classpath_Pointer64 *paddress;
4179 gnu_classpath_Pointer32 *paddress;
4182 STATS(jniinvokation();)
4184 log_text("JNI-NewDirectByteBuffer: called");
4186 /* allocate a java.nio.DirectByteBufferImpl object */
4188 if (!(nbuf = (java_nio_DirectByteBufferImpl *) builtin_new(class_java_nio_DirectByteBufferImpl)))
4191 /* alocate a gnu.classpath.Pointer{32,64} object */
4193 #if SIZEOF_VOID_P == 8
4194 if (!(paddress = (gnu_classpath_Pointer64 *) builtin_new(class_gnu_classpath_Pointer64)))
4196 if (!(paddress = (gnu_classpath_Pointer32 *) builtin_new(class_gnu_classpath_Pointer32)))
4200 /* fill gnu.classpath.Pointer{32,64} with address */
4202 paddress->data = (ptrint) address;
4204 /* fill java.nio.Buffer object */
4206 nbuf->cap = (s4) capacity;
4207 nbuf->limit = (s4) capacity;
4209 nbuf->address = (gnu_classpath_Pointer *) paddress;
4211 /* add local reference and return the value */
4213 return NewLocalRef(env, (jobject) nbuf);
4217 /* GetDirectBufferAddress ******************************************************
4219 Fetches and returns the starting address of the memory region
4220 referenced by the given direct java.nio.Buffer.
4222 *******************************************************************************/
4224 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
4226 java_nio_DirectByteBufferImpl *nbuf;
4227 #if SIZEOF_VOID_P == 8
4228 gnu_classpath_Pointer64 *address;
4230 gnu_classpath_Pointer32 *address;
4233 STATS(jniinvokation();)
4236 if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
4240 nbuf = (java_nio_DirectByteBufferImpl *) buf;
4242 #if SIZEOF_VOID_P == 8
4243 address = (gnu_classpath_Pointer64 *) nbuf->address;
4245 address = (gnu_classpath_Pointer32 *) nbuf->address;
4248 return (void *) address->data;
4252 /* GetDirectBufferCapacity *****************************************************
4254 Fetches and returns the capacity in bytes of the memory region
4255 referenced by the given direct java.nio.Buffer.
4257 *******************************************************************************/
4259 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
4261 java_nio_Buffer *nbuf;
4263 STATS(jniinvokation();)
4268 nbuf = (java_nio_Buffer *) buf;
4270 return (jlong) nbuf->cap;
4274 jint DestroyJavaVM(JavaVM *vm)
4276 STATS(jniinvokation();)
4277 log_text("DestroyJavaVM called");
4283 /* AttachCurrentThread *********************************************************
4285 Attaches the current thread to a Java VM. Returns a JNI interface
4286 pointer in the JNIEnv argument.
4288 Trying to attach a thread that is already attached is a no-op.
4290 A native thread cannot be attached simultaneously to two Java VMs.
4292 When a thread is attached to the VM, the context class loader is
4293 the bootstrap loader.
4295 *******************************************************************************/
4297 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
4299 STATS(jniinvokation();)
4301 log_text("AttachCurrentThread called");
4303 #if !defined(HAVE___THREAD)
4304 /* cacao_thread_attach();*/
4306 #error "No idea how to implement that. Perhaps Stefan knows"
4315 jint DetachCurrentThread(JavaVM *vm)
4317 STATS(jniinvokation();)
4318 log_text("DetachCurrentThread called");
4324 /* GetEnv **********************************************************************
4326 If the current thread is not attached to the VM, sets *env to NULL,
4327 and returns JNI_EDETACHED. If the specified version is not
4328 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
4329 sets *env to the appropriate interface, and returns JNI_OK.
4331 *******************************************************************************/
4333 jint GetEnv(JavaVM *vm, void **env, jint version)
4335 STATS(jniinvokation();)
4337 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4338 if (thread_getself() == NULL) {
4341 return JNI_EDETACHED;
4345 if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
4346 (version == JNI_VERSION_1_4)) {
4352 #if defined(ENABLE_JVMTI)
4353 if (version == JVMTI_VERSION_1_0) {
4354 *env = (void *) new_jvmtienv();
4363 return JNI_EVERSION;
4368 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4370 STATS(jniinvokation();)
4371 log_text("AttachCurrentThreadAsDaemon called");
4377 /* JNI invocation table *******************************************************/
4379 const struct JNIInvokeInterface JNI_JavaVMTable = {
4385 AttachCurrentThread,
4386 DetachCurrentThread,
4388 AttachCurrentThreadAsDaemon
4392 /* JNI function table *********************************************************/
4394 struct JNINativeInterface JNI_JNIEnvTable = {
4403 &FromReflectedMethod,
4404 &FromReflectedField,
4424 &EnsureLocalCapacity,
4440 &CallBooleanMethodV,
4441 &CallBooleanMethodA,
4467 &CallNonvirtualObjectMethod,
4468 &CallNonvirtualObjectMethodV,
4469 &CallNonvirtualObjectMethodA,
4470 &CallNonvirtualBooleanMethod,
4471 &CallNonvirtualBooleanMethodV,
4472 &CallNonvirtualBooleanMethodA,
4473 &CallNonvirtualByteMethod,
4474 &CallNonvirtualByteMethodV,
4475 &CallNonvirtualByteMethodA,
4476 &CallNonvirtualCharMethod,
4477 &CallNonvirtualCharMethodV,
4478 &CallNonvirtualCharMethodA,
4479 &CallNonvirtualShortMethod,
4480 &CallNonvirtualShortMethodV,
4481 &CallNonvirtualShortMethodA,
4482 &CallNonvirtualIntMethod,
4483 &CallNonvirtualIntMethodV,
4484 &CallNonvirtualIntMethodA,
4485 &CallNonvirtualLongMethod,
4486 &CallNonvirtualLongMethodV,
4487 &CallNonvirtualLongMethodA,
4488 &CallNonvirtualFloatMethod,
4489 &CallNonvirtualFloatMethodV,
4490 &CallNonvirtualFloatMethodA,
4491 &CallNonvirtualDoubleMethod,
4492 &CallNonvirtualDoubleMethodV,
4493 &CallNonvirtualDoubleMethodA,
4494 &CallNonvirtualVoidMethod,
4495 &CallNonvirtualVoidMethodV,
4496 &CallNonvirtualVoidMethodA,
4521 &CallStaticObjectMethod,
4522 &CallStaticObjectMethodV,
4523 &CallStaticObjectMethodA,
4524 &CallStaticBooleanMethod,
4525 &CallStaticBooleanMethodV,
4526 &CallStaticBooleanMethodA,
4527 &CallStaticByteMethod,
4528 &CallStaticByteMethodV,
4529 &CallStaticByteMethodA,
4530 &CallStaticCharMethod,
4531 &CallStaticCharMethodV,
4532 &CallStaticCharMethodA,
4533 &CallStaticShortMethod,
4534 &CallStaticShortMethodV,
4535 &CallStaticShortMethodA,
4536 &CallStaticIntMethod,
4537 &CallStaticIntMethodV,
4538 &CallStaticIntMethodA,
4539 &CallStaticLongMethod,
4540 &CallStaticLongMethodV,
4541 &CallStaticLongMethodA,
4542 &CallStaticFloatMethod,
4543 &CallStaticFloatMethodV,
4544 &CallStaticFloatMethodA,
4545 &CallStaticDoubleMethod,
4546 &CallStaticDoubleMethodV,
4547 &CallStaticDoubleMethodA,
4548 &CallStaticVoidMethod,
4549 &CallStaticVoidMethodV,
4550 &CallStaticVoidMethodA,
4554 &GetStaticObjectField,
4555 &GetStaticBooleanField,
4556 &GetStaticByteField,
4557 &GetStaticCharField,
4558 &GetStaticShortField,
4560 &GetStaticLongField,
4561 &GetStaticFloatField,
4562 &GetStaticDoubleField,
4563 &SetStaticObjectField,
4564 &SetStaticBooleanField,
4565 &SetStaticByteField,
4566 &SetStaticCharField,
4567 &SetStaticShortField,
4569 &SetStaticLongField,
4570 &SetStaticFloatField,
4571 &SetStaticDoubleField,
4576 &ReleaseStringChars,
4579 &GetStringUTFLength,
4581 &ReleaseStringUTFChars,
4586 &GetObjectArrayElement,
4587 &SetObjectArrayElement,
4598 &GetBooleanArrayElements,
4599 &GetByteArrayElements,
4600 &GetCharArrayElements,
4601 &GetShortArrayElements,
4602 &GetIntArrayElements,
4603 &GetLongArrayElements,
4604 &GetFloatArrayElements,
4605 &GetDoubleArrayElements,
4607 &ReleaseBooleanArrayElements,
4608 &ReleaseByteArrayElements,
4609 &ReleaseCharArrayElements,
4610 &ReleaseShortArrayElements,
4611 &ReleaseIntArrayElements,
4612 &ReleaseLongArrayElements,
4613 &ReleaseFloatArrayElements,
4614 &ReleaseDoubleArrayElements,
4616 &GetBooleanArrayRegion,
4617 &GetByteArrayRegion,
4618 &GetCharArrayRegion,
4619 &GetShortArrayRegion,
4621 &GetLongArrayRegion,
4622 &GetFloatArrayRegion,
4623 &GetDoubleArrayRegion,
4624 &SetBooleanArrayRegion,
4625 &SetByteArrayRegion,
4626 &SetCharArrayRegion,
4627 &SetShortArrayRegion,
4629 &SetLongArrayRegion,
4630 &SetFloatArrayRegion,
4631 &SetDoubleArrayRegion,
4641 /* new JNI 1.2 functions */
4644 &GetStringUTFRegion,
4646 &GetPrimitiveArrayCritical,
4647 &ReleasePrimitiveArrayCritical,
4650 &ReleaseStringCritical,
4653 &DeleteWeakGlobalRef,
4657 /* new JNI 1.4 functions */
4659 &NewDirectByteBuffer,
4660 &GetDirectBufferAddress,
4661 &GetDirectBufferCapacity
4665 /* Invocation API Functions ***************************************************/
4667 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4669 Returns a default configuration for the Java VM.
4671 *******************************************************************************/
4673 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4675 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4677 /* GNU classpath currently supports JNI 1.2 */
4679 _vm_args->version = JNI_VERSION_1_2;
4685 /* JNI_GetCreatedJavaVMs *******************************************************
4687 Returns all Java VMs that have been created. Pointers to VMs are written in
4688 the buffer vmBuf in the order they are created. At most bufLen number of
4689 entries will be written. The total number of created VMs is returned in
4692 *******************************************************************************/
4694 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4696 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4702 /* JNI_CreateJavaVM ************************************************************
4704 Loads and initializes a Java VM. The current thread becomes the main thread.
4705 Sets the env argument to the JNI interface pointer of the main thread.
4707 *******************************************************************************/
4709 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4711 const struct JNIInvokeInterface *vm;
4712 struct JNINativeInterface *env;
4714 vm = &JNI_JavaVMTable;
4715 env = &JNI_JNIEnvTable;
4717 *p_vm = (JavaVM *) vm;
4718 *p_env = (JNIEnv *) env;
4724 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4725 jobject obj, java_objectarray *params)
4732 if (methodID == 0) {
4733 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
4737 argcount = methodID->parseddesc->paramcount;
4738 paramcount = argcount;
4740 /* if method is non-static, remove the `this' pointer */
4742 if (!(methodID->flags & ACC_STATIC))
4745 /* the method is an instance method the obj has to be an instance of the
4746 class the method belongs to. For static methods the obj parameter
4749 if (!(methodID->flags & ACC_STATIC) && obj &&
4750 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4752 new_exception_message(string_java_lang_IllegalArgumentException,
4753 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4757 if (((params == NULL) && (paramcount != 0)) ||
4758 (params && (params->header.size != paramcount))) {
4760 new_exception(string_java_lang_IllegalArgumentException);
4765 if (!(methodID->flags & ACC_STATIC) && !obj) {
4767 new_exception_message(string_java_lang_NullPointerException,
4768 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4772 if ((methodID->flags & ACC_STATIC) && (obj))
4776 if ((methodID->flags & ACC_ABSTRACT) ||
4777 (methodID->class->flags & ACC_INTERFACE)) {
4778 methodID = get_virtual(obj, methodID);
4782 blk = MNEW(jni_callblock, argcount);
4784 if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4788 switch (methodID->parseddesc->returntype.decltype) {
4790 (void) asm_calljavafunction2(methodID, argcount,
4791 argcount * sizeof(jni_callblock),
4793 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4796 case PRIMITIVETYPE_INT: {
4798 i = asm_calljavafunction2int(methodID, argcount,
4799 argcount * sizeof(jni_callblock),
4802 o = native_new_and_init_int(class_java_lang_Integer, i);
4806 case PRIMITIVETYPE_BYTE: {
4808 i = asm_calljavafunction2int(methodID, argcount,
4809 argcount * sizeof(jni_callblock),
4812 /* o = native_new_and_init_int(class_java_lang_Byte, i); */
4813 o = builtin_new(class_java_lang_Byte);
4816 class_resolvemethod(o->vftbl->class,
4823 case PRIMITIVETYPE_CHAR: {
4825 intVal = asm_calljavafunction2int(methodID,
4827 argcount * sizeof(jni_callblock),
4829 o = builtin_new(class_java_lang_Character);
4832 class_resolvemethod(o->vftbl->class,
4839 case PRIMITIVETYPE_SHORT: {
4841 intVal = asm_calljavafunction2int(methodID,
4843 argcount * sizeof(jni_callblock),
4845 o = builtin_new(class_java_lang_Short);
4848 class_resolvemethod(o->vftbl->class,
4855 case PRIMITIVETYPE_BOOLEAN: {
4857 intVal = asm_calljavafunction2int(methodID,
4859 argcount * sizeof(jni_callblock),
4861 o = builtin_new(class_java_lang_Boolean);
4864 class_resolvemethod(o->vftbl->class,
4871 case PRIMITIVETYPE_LONG: {
4873 longVal = asm_calljavafunction2long(methodID,
4875 argcount * sizeof(jni_callblock),
4877 o = builtin_new(class_java_lang_Long);
4880 class_resolvemethod(o->vftbl->class,
4887 case PRIMITIVETYPE_FLOAT: {
4889 floatVal = asm_calljavafunction2float(methodID,
4891 argcount * sizeof(jni_callblock),
4893 o = builtin_new(class_java_lang_Float);
4896 class_resolvemethod(o->vftbl->class,
4903 case PRIMITIVETYPE_DOUBLE: {
4905 doubleVal = asm_calljavafunction2double(methodID,
4907 argcount * sizeof(jni_callblock),
4909 o = builtin_new(class_java_lang_Double);
4912 class_resolvemethod(o->vftbl->class,
4920 o = asm_calljavafunction2(methodID, argcount,
4921 argcount * sizeof(jni_callblock), blk);
4925 /* if this happens the exception has already been set by */
4926 /* fill_callblock_from_objectarray */
4928 MFREE(blk, jni_callblock, argcount);
4929 return (jobject *) 0;
4932 MFREE(blk, jni_callblock, argcount);
4934 if (*exceptionptr) {
4935 java_objectheader *cause;
4937 cause = *exceptionptr;
4939 /* clear exception pointer, we are calling JIT code again */
4941 *exceptionptr = NULL;
4944 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
4945 (java_lang_Throwable *) cause);
4948 return (jobject *) o;
4953 * These are local overrides for various environment variables in Emacs.
4954 * Please do not remove this and leave it at the end of the file, where
4955 * Emacs will automagically detect them.
4956 * ---------------------------------------------------------------------
4959 * indent-tabs-mode: t