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 2691 2005-06-14 18:09:42Z twisti $
44 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/native.h"
47 #include "native/include/java_lang_Object.h"
48 #include "native/include/java_lang_Byte.h"
49 #include "native/include/java_lang_Character.h"
50 #include "native/include/java_lang_Short.h"
51 #include "native/include/java_lang_Integer.h"
52 #include "native/include/java_lang_Boolean.h"
53 #include "native/include/java_lang_Long.h"
54 #include "native/include/java_lang_Float.h"
55 #include "native/include/java_lang_Double.h"
56 #include "native/include/java_lang_Throwable.h"
57 #include "native/include/java_lang_reflect_Method.h"
58 #include "native/include/java_lang_reflect_Constructor.h"
59 #include "native/include/java_lang_reflect_Field.h"
61 #include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
62 #include "native/include/java_lang_VMClass.h"
63 #include "native/include/java_lang_VMClassLoader.h"
65 #if defined(USE_THREADS)
66 # if defined(NATIVE_THREADS)
67 # include "threads/native/threads.h"
69 # include "threads/green/threads.h"
73 #include "toolbox/logging.h"
74 #include "vm/builtin.h"
75 #include "vm/exceptions.h"
76 #include "vm/global.h"
77 #include "vm/initialize.h"
78 #include "vm/loader.h"
79 #include "vm/options.h"
80 #include "vm/resolve.h"
81 #include "vm/statistics.h"
82 #include "vm/stringlocal.h"
83 #include "vm/tables.h"
84 #include "vm/jit/asmpart.h"
85 #include "vm/jit/jit.h"
86 #include "vm/statistics.h"
89 /* XXX TWISTI hack: define it extern so they can be found in this file */
90 extern const struct JNIInvokeInterface JNI_JavaVMTable;
91 extern struct JNINativeInterface JNI_JNIEnvTable;
93 /* pointers to VM and the environment needed by GetJavaVM and GetEnv */
94 static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
95 static void* ptr_env = (void*) &JNI_JNIEnvTable;
98 #define PTR_TO_ITEM(ptr) ((u8)(size_t)(ptr))
100 /* global reference table */
101 static jobject *global_ref_table;
102 static bool initrunning=false;
104 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
105 static jmethodID getmid = NULL;
106 static jmethodID putmid = NULL;
107 static jclass intclass = NULL;
108 static jmethodID intvalue = NULL;
109 static jmethodID newint = NULL;
110 static jclass ihmclass = NULL;
111 static jmethodID removemid = NULL;
113 #define JWCLINITDEBUG(x)
116 /********************* accessing instance-fields **********************************/
118 #define setField(obj,typ,var,val) *((typ*) ((long int) obj + (long int) var->offset))=val;
119 #define getField(obj,typ,var) *((typ*) ((long int) obj + (long int) var->offset))
120 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) setField(obj,jdatatype,getFieldID_critical(env,clazz,name,sig),val);
123 static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
124 jni_callblock blk[], va_list data,
127 typedesc *paramtypes;
131 paramtypes = descr->paramtypes;
133 /* if method is non-static fill first block and skip `this' pointer */
138 /* the `this' pointer */
139 blk[0].itemtype = TYPE_ADR;
140 blk[0].item = PTR_TO_ITEM(obj);
146 for (; i < descr->paramcount; i++, paramtypes++) {
147 switch (paramtypes->decltype) {
148 /* primitive types */
149 case PRIMITIVETYPE_BYTE:
150 case PRIMITIVETYPE_CHAR:
151 case PRIMITIVETYPE_SHORT:
152 case PRIMITIVETYPE_BOOLEAN:
153 blk[i].itemtype = TYPE_INT;
154 blk[i].item = (u8) va_arg(data, int);
157 case PRIMITIVETYPE_INT:
158 blk[i].itemtype = TYPE_INT;
159 dummy = va_arg(data, u4);
160 blk[i].item = (u8) dummy;
163 case PRIMITIVETYPE_LONG:
164 blk[i].itemtype = TYPE_LNG;
165 blk[i].item = (u8) va_arg(data, jlong);
168 case PRIMITIVETYPE_FLOAT:
169 blk[i].itemtype = TYPE_FLT;
170 *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
173 case PRIMITIVETYPE_DOUBLE:
174 blk[i].itemtype = TYPE_DBL;
175 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
179 blk[i].itemtype = TYPE_ADR;
180 blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
185 /* The standard doesn't say anything about return value checking, but it */
186 /* appears to be useful. */
188 if (rettype != descr->returntype.decltype)
189 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
193 /* XXX it could be considered if we should do typechecking here in the future */
195 static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
197 java_objectarray *params)
201 typedesc *paramtypes;
206 paramcount = descr->paramcount;
207 paramtypes = descr->paramtypes;
209 /* if method is non-static fill first block and skip `this' pointer */
215 blk[0].itemtype = TYPE_ADR;
216 blk[0].item = PTR_TO_ITEM(obj);
223 for (j = 0; j < paramcount; i++, j++, paramtypes++) {
224 switch (paramtypes->type) {
225 /* primitive types */
230 param = params->data[j];
234 /* internally used data type */
235 blk[i].itemtype = paramtypes->type;
237 /* convert the value according to its declared type */
239 c = param->vftbl->class;
241 switch (paramtypes->decltype) {
242 case PRIMITIVETYPE_BOOLEAN:
243 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
244 blk[i].item = (u8) ((java_lang_Boolean *) param)->value;
249 case PRIMITIVETYPE_BYTE:
250 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
251 blk[i].item = (u8) ((java_lang_Byte *) param)->value;
256 case PRIMITIVETYPE_CHAR:
257 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
258 blk[i].item = (u8) ((java_lang_Character *) param)->value;
263 case PRIMITIVETYPE_SHORT:
264 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
265 blk[i].item = (u8) ((java_lang_Short *) param)->value;
266 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
267 blk[i].item = (u8) ((java_lang_Byte *) param)->value;
272 case PRIMITIVETYPE_INT:
273 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
274 blk[i].item = (u8) ((java_lang_Integer *) param)->value;
275 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
276 blk[i].item = (u8) ((java_lang_Short *) param)->value;
277 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
278 blk[i].item = (u8) ((java_lang_Byte *) param)->value;
283 case PRIMITIVETYPE_LONG:
284 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
285 blk[i].item = (u8) ((java_lang_Long *) param)->value;
286 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
287 blk[i].item = (u8) ((java_lang_Integer *) param)->value;
288 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
289 blk[i].item = (u8) ((java_lang_Short *) param)->value;
290 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
291 blk[i].item = (u8) ((java_lang_Byte *) param)->value;
296 case PRIMITIVETYPE_FLOAT:
297 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
298 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
303 case PRIMITIVETYPE_DOUBLE:
304 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
305 *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Float *) param)->value;
306 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
307 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
314 } /* end declared type switch */
318 if (!resolve_class_from_typedesc(paramtypes, true, &c))
321 if (params->data[j] != 0) {
322 if (paramtypes->arraydim > 0) {
323 if (!builtin_arrayinstanceof(params->data[j], c->vftbl))
327 if (!builtin_instanceof(params->data[j], c))
331 blk[i].itemtype = TYPE_ADR;
332 blk[i].item = PTR_TO_ITEM(params->data[j]);
337 } /* end param type switch */
339 } /* end param loop */
342 /* *rettype = descr->returntype.decltype; */
347 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
352 static jmethodID get_virtual(jobject obj, jmethodID methodID)
354 if (obj->vftbl->class == methodID->class)
357 return class_resolvemethod(obj->vftbl->class, methodID->name,
358 methodID->descriptor);
362 static jmethodID get_nonvirtual(jclass clazz, jmethodID methodID)
364 if (clazz == methodID->class)
367 /* class_resolvemethod -> classfindmethod? (JOWENN) */
368 return class_resolvemethod(clazz, methodID->name, methodID->descriptor);
372 static jobject callObjectMethod(jobject obj, jmethodID methodID, va_list args)
381 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
385 argcount = methodID->parseddesc->paramcount;
387 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
388 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
389 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
393 if (obj && !builtin_instanceof(obj, methodID->class)) {
394 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
401 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
402 log_text("Too many arguments. CallObjectMethod does not support that");
407 blk = MNEW(jni_callblock, /*4 */argcount+2);
409 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_ADR);
410 /* printf("parameter: obj: %p",blk[0].item); */
411 STATS(jnicallXmethodnvokation();)
412 ret = asm_calljavafunction2(methodID,
414 (argcount + 1) * sizeof(jni_callblock),
416 MFREE(blk, jni_callblock, argcount + 1);
417 /* printf("(CallObjectMethodV)-->%p\n",ret); */
424 core function for integer class methods (bool, byte, short, integer)
425 This is basically needed for i386
427 static jint callIntegerMethod(jobject obj, jmethodID methodID, int retType, va_list args)
433 STATS(jniinvokation();)
436 log_text("JNI-Call: CallObjectMethodV");
437 utf_display(methodID->name);
438 utf_display(methodID->descriptor);
439 printf("\nParmaeter count: %d\n",argcount);
440 utf_display(obj->vftbl->class->name);
444 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
448 argcount = methodID->parseddesc->paramcount;
450 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
451 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
452 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
456 if (obj && !builtin_instanceof(obj, methodID->class)) {
457 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
463 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
464 log_text("Too many arguments. CallIntegerMethod does not support that");
469 blk = MNEW(jni_callblock, /*4 */ argcount+2);
471 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
473 /* printf("parameter: obj: %p",blk[0].item); */
474 STATS(jnicallXmethodnvokation();)
475 ret = asm_calljavafunction2int(methodID,
477 (argcount + 1) * sizeof(jni_callblock),
480 MFREE(blk, jni_callblock, argcount + 1);
481 /* printf("(CallObjectMethodV)-->%p\n",ret); */
487 /*core function for long class functions*/
488 static jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
494 STATS(jniinvokation();)
497 log_text("JNI-Call: CallObjectMethodV");
498 utf_display(methodID->name);
499 utf_display(methodID->descriptor);
500 printf("\nParmaeter count: %d\n",argcount);
501 utf_display(obj->vftbl->class->name);
505 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
509 argcount = methodID->parseddesc->paramcount;
511 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
512 ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
513 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
517 if (obj && !builtin_instanceof(obj,methodID->class)) {
518 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
524 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
525 log_text("Too many arguments. CallObjectMethod does not support that");
530 blk = MNEW(jni_callblock,/* 4 */argcount+2);
532 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_LNG);
534 /* printf("parameter: obj: %p",blk[0].item); */
535 STATS(jnicallXmethodnvokation();)
536 ret = asm_calljavafunction2long(methodID,
538 (argcount + 1) * sizeof(jni_callblock),
541 MFREE(blk, jni_callblock, argcount + 1);
542 /* printf("(CallObjectMethodV)-->%p\n",ret); */
548 /*core function for float class methods (float,double)*/
549 static jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,int retType)
551 int argcount = methodID->parseddesc->paramcount;
555 STATS(jniinvokation();)
558 log_text("JNI-Call: CallObjectMethodV");
559 utf_display(methodID->name);
560 utf_display(methodID->descriptor);
561 printf("\nParmaeter count: %d\n",argcount);
562 utf_display(obj->vftbl->class->name);
568 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
569 log_text("Too many arguments. CallObjectMethod does not support that");
574 blk = MNEW(jni_callblock, /*4 */ argcount+2);
576 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
578 /* printf("parameter: obj: %p",blk[0].item); */
579 STATS(jnicallXmethodnvokation();)
580 ret = asm_calljavafunction2double(methodID,
582 (argcount + 1) * sizeof(jni_callblock),
585 MFREE(blk, jni_callblock, argcount + 1);
586 /* printf("(CallObjectMethodV)-->%p\n",ret); */
592 /*************************** function: jclass_findfield ****************************
594 searches for field with specified name and type in a 'classinfo'-structur
595 if no such field is found NULL is returned
597 ************************************************************************************/
599 static fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
602 STATS(jniinvokation();)
604 /* printf(" FieldCount: %d\n",c->fieldscount);
605 utf_display(c->name); */
606 for (i = 0; i < c->fieldscount; i++) {
607 /* utf_display(c->fields[i].name);
609 utf_display(c->fields[i].descriptor);
611 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
612 return &(c->fields[i]);
615 if (c->super.cls) return jclass_findfield(c->super.cls,name,desc);
621 /* GetVersion ******************************************************************
623 Returns the major version number in the higher 16 bits and the
624 minor version number in the lower 16 bits.
626 *******************************************************************************/
628 jint GetVersion(JNIEnv *env)
630 /* GNU classpath currently supports JNI 1.2 */
631 STATS(jniinvokation();)
632 return JNI_VERSION_1_2;
636 /* Class Operations ***********************************************************/
638 /* DefineClass *****************************************************************
640 Loads a class from a buffer of raw class data. The buffer
641 containing the raw class data is not referenced by the VM after the
642 DefineClass call returns, and it may be discarded if desired.
644 *******************************************************************************/
646 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
647 const jbyte *buf, jsize bufLen)
649 java_lang_ClassLoader *cl;
654 STATS(jniinvokation();)
656 cl = (java_lang_ClassLoader *) loader;
657 s = javastring_new_char(name);
658 ba = (java_bytearray *) buf;
660 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
667 /* FindClass *******************************************************************
669 This function loads a locally-defined class. It searches the
670 directories and zip files specified by the CLASSPATH environment
671 variable for the class with the specified name.
673 *******************************************************************************/
675 jclass FindClass(JNIEnv *env, const char *name)
679 java_objectheader *cl;
681 STATS(jniinvokation();)
683 u = utf_new_char_classname((char *) name);
685 /* check stacktrace for classloader, if one found use it, otherwise use */
686 /* the system classloader */
688 #if defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__)
689 cl = cacao_currentClassLoader();
694 if (!(c = load_class_from_classloader(u, cl)))
700 use_class_as_object(c);
706 /* FromReflectedMethod *********************************************************
708 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
709 object to a method ID.
711 *******************************************************************************/
713 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
719 STATS(jniinvokation();)
724 if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
725 java_lang_reflect_Method *rm;
727 rm = (java_lang_reflect_Method *) method;
728 c = (classinfo *) (rm->declaringClass);
731 } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
732 java_lang_reflect_Constructor *rc;
734 rc = (java_lang_reflect_Constructor *) method;
735 c = (classinfo *) (rc->clazz);
741 if ((slot < 0) || (slot >= c->methodscount)) {
742 /* this usually means a severe internal cacao error or somebody
743 tempered around with the reflected method */
744 log_text("error illegal slot for method in class(FromReflectedMethod)");
748 mi = &(c->methods[slot]);
754 /* GetSuperclass ***************************************************************
756 If clazz represents any class other than the class Object, then
757 this function returns the object that represents the superclass of
758 the class specified by clazz.
760 *******************************************************************************/
762 jclass GetSuperclass(JNIEnv *env, jclass sub)
765 STATS(jniinvokation();)
767 c = ((classinfo *) sub)->super.cls;
772 use_class_as_object(c);
778 /* IsAssignableFrom ************************************************************
780 Determines whether an object of sub can be safely cast to sup.
782 *******************************************************************************/
784 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
786 STATS(jniinvokation();)
787 return Java_java_lang_VMClass_isAssignableFrom(env,
789 (java_lang_Class *) sup,
790 (java_lang_Class *) sub);
794 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
796 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
798 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!!!");
799 STATS(jniinvokation();)
804 /* Throw ***********************************************************************
806 Causes a java.lang.Throwable object to be thrown.
808 *******************************************************************************/
810 jint Throw(JNIEnv *env, jthrowable obj)
812 *exceptionptr = (java_objectheader *) obj;
813 STATS(jniinvokation();)
819 /* ThrowNew ********************************************************************
821 Constructs an exception object from the specified class with the
822 message specified by message and causes that exception to be
825 *******************************************************************************/
827 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
829 java_lang_Throwable *o;
831 STATS(jniinvokation();)
833 s = (java_lang_String *) javastring_new_char(msg);
835 /* instantiate exception object */
837 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
843 *exceptionptr = (java_objectheader *) o;
849 /* ExceptionOccurred ***********************************************************
851 Determines if an exception is being thrown. The exception stays
852 being thrown until either the native code calls ExceptionClear(),
853 or the Java code handles the exception.
855 *******************************************************************************/
857 jthrowable ExceptionOccurred(JNIEnv *env)
859 STATS(jniinvokation();)
860 return (jthrowable) *exceptionptr;
864 /* ExceptionDescribe ***********************************************************
866 Prints an exception and a backtrace of the stack to a system
867 error-reporting channel, such as stderr. This is a convenience
868 routine provided for debugging.
870 *******************************************************************************/
872 void ExceptionDescribe(JNIEnv *env)
874 java_objectheader *e;
876 STATS(jniinvokation();)
881 /* clear exception, because we are calling jit code again */
883 *exceptionptr = NULL;
885 /* get printStackTrace method from exception class */
887 m = class_resolveclassmethod(e->vftbl->class,
894 /* XXX what should we do? */
897 /* print the stacktrace */
899 asm_calljavafunction(m, e, NULL, NULL, NULL);
904 /* ExceptionClear **************************************************************
906 Clears any exception that is currently being thrown. If no
907 exception is currently being thrown, this routine has no effect.
909 *******************************************************************************/
911 void ExceptionClear(JNIEnv *env)
913 STATS(jniinvokation();)
914 *exceptionptr = NULL;
918 /* FatalError ******************************************************************
920 Raises a fatal error and does not expect the VM to recover. This
921 function does not return.
923 *******************************************************************************/
925 void FatalError(JNIEnv *env, const char *msg)
927 STATS(jniinvokation();)
928 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
932 /******************* creates a new local reference frame **************************/
934 jint PushLocalFrame(JNIEnv* env, jint capacity)
936 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
937 STATS(jniinvokation();)
942 /**************** Pops off the current local reference frame **********************/
944 jobject PopLocalFrame(JNIEnv* env, jobject result)
946 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
947 STATS(jniinvokation();)
953 /* DeleteLocalRef **************************************************************
955 Deletes the local reference pointed to by localRef.
957 *******************************************************************************/
959 void DeleteLocalRef(JNIEnv *env, jobject localRef)
961 log_text("JNI-Call: DeleteLocalRef: IMPLEMENT ME!");
962 STATS(jniinvokation();)
967 /* IsSameObject ****************************************************************
969 Tests whether two references refer to the same Java object.
971 *******************************************************************************/
973 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
975 STATS(jniinvokation();)
976 return (ref1 == ref2);
980 /* NewLocalRef *****************************************************************
982 Creates a new local reference that refers to the same object as ref.
984 *******************************************************************************/
986 jobject NewLocalRef(JNIEnv *env, jobject ref)
988 log_text("JNI-Call: NewLocalRef: IMPLEMENT ME!");
989 STATS(jniinvokation();)
993 /***********************************************************************************
995 Ensures that at least a given number of local references can
996 be created in the current thread
998 **********************************************************************************/
1000 jint EnsureLocalCapacity (JNIEnv* env, jint capacity)
1002 STATS(jniinvokation();)
1003 return 0; /* return 0 on success */
1007 /* AllocObject *****************************************************************
1009 Allocates a new Java object without invoking any of the
1010 constructors for the object. Returns a reference to the object.
1012 *******************************************************************************/
1014 jobject AllocObject(JNIEnv *env, jclass clazz)
1016 java_objectheader *o;
1017 STATS(jniinvokation();)
1019 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1021 new_exception_utfmessage(string_java_lang_InstantiationException,
1026 o = builtin_new(clazz);
1032 /* NewObject *******************************************************************
1034 Constructs a new Java object. The method ID indicates which
1035 constructor method to invoke. This ID must be obtained by calling
1036 GetMethodID() with <init> as the method name and void (V) as the
1039 *******************************************************************************/
1041 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1043 java_objectheader *o;
1045 int argcount=methodID->parseddesc->paramcount;
1048 STATS(jniinvokation();)
1052 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
1053 log_text("Too many arguments. NewObject does not support that");
1060 o = builtin_new(clazz);
1065 va_start(vaargs, methodID);
1066 for (i = 0; i < argcount; i++) {
1067 args[i] = va_arg(vaargs, void*);
1071 /* call constructor */
1073 asm_calljavafunction(methodID, o, args[0], args[1], args[2]);
1079 /***********************************************************************************
1081 Constructs a new Java object
1082 arguments that are to be passed to the constructor are placed in va_list args
1084 ***********************************************************************************/
1086 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1088 log_text("JNI-Call: NewObjectV");
1089 STATS(jniinvokation();)
1095 /***********************************************************************************
1097 Constructs a new Java object
1098 arguments that are to be passed to the constructor are placed in
1099 args array of jvalues
1101 ***********************************************************************************/
1103 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1105 log_text("JNI-Call: NewObjectA");
1106 STATS(jniinvokation();)
1112 /* GetObjectClass **************************************************************
1114 Returns the class of an object.
1116 *******************************************************************************/
1118 jclass GetObjectClass(JNIEnv *env, jobject obj)
1121 STATS(jniinvokation();)
1123 if (!obj || !obj->vftbl)
1126 c = obj->vftbl->class;
1127 use_class_as_object(c);
1132 /* IsInstanceOf ****************************************************************
1134 Tests whether an object is an instance of a class.
1136 *******************************************************************************/
1138 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1140 STATS(jniinvokation();)
1142 return Java_java_lang_VMClass_isInstance(env,
1144 (java_lang_Class *) clazz,
1145 (java_lang_Object *) obj);
1149 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1151 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1153 java_lang_reflect_Field *f;
1155 jfieldID fid; /* the JNI-fieldid of the wrapping object */
1156 STATS(jniinvokation();)
1157 /*log_text("JNI-Call: FromReflectedField");*/
1159 f=(java_lang_reflect_Field *)field;
1161 c=(classinfo*)(f->declaringClass);
1162 if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1163 /*this usually means a severe internal cacao error or somebody
1164 tempered around with the reflected method*/
1165 log_text("error illegal slot for field in class(FromReflectedField)");
1168 fid=&(c->fields[f->slot]);
1173 /**********************************************************************************
1175 converts a method ID to a java.lang.reflect.Method or
1176 java.lang.reflect.Constructor object
1178 **********************************************************************************/
1180 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1182 log_text("JNI-Call: ToReflectedMethod");
1183 STATS(jniinvokation();)
1189 /* GetMethodID *****************************************************************
1191 returns the method ID for an instance method
1193 *******************************************************************************/
1195 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1198 STATS(jniinvokation();)
1200 m = class_resolvemethod(clazz,
1201 utf_new_char((char *) name),
1202 utf_new_char((char *) sig));
1204 if (!m || (m->flags & ACC_STATIC)) {
1206 new_exception_message(string_java_lang_NoSuchMethodError, name);
1215 /******************** JNI-functions for calling instance methods ******************/
1217 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1221 STATS(jniinvokation();)
1223 /* log_text("JNI-Call: CallObjectMethod");*/
1225 va_start(vaargs, methodID);
1226 ret = callObjectMethod(obj, methodID, vaargs);
1233 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1235 STATS(jniinvokation();)
1236 return callObjectMethod(obj,methodID,args);
1240 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1242 log_text("JNI-Call: CallObjectMethodA");
1243 STATS(jniinvokation();)
1251 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1255 STATS(jniinvokation();)
1257 /* log_text("JNI-Call: CallBooleanMethod");*/
1259 va_start(vaargs,methodID);
1260 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1266 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1268 STATS(jniinvokation();)
1270 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
1274 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1276 STATS(jniinvokation();)
1277 log_text("JNI-Call: CallBooleanMethodA");
1282 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1286 STATS(jniinvokation();)
1288 /* log_text("JNI-Call: CallVyteMethod");*/
1290 va_start(vaargs,methodID);
1291 ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
1297 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1299 /* log_text("JNI-Call: CallByteMethodV");*/
1300 STATS(jniinvokation();)
1302 return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
1306 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1308 log_text("JNI-Call: CallByteMethodA");
1309 STATS(jniinvokation();)
1315 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1319 STATS(jniinvokation();)
1321 /* log_text("JNI-Call: CallCharMethod");*/
1323 va_start(vaargs,methodID);
1324 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
1331 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1333 STATS(jniinvokation();)
1335 /* log_text("JNI-Call: CallCharMethodV");*/
1336 return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
1340 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1342 STATS(jniinvokation();)
1344 log_text("JNI-Call: CallCharMethodA");
1350 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1354 STATS(jniinvokation();)
1356 /* log_text("JNI-Call: CallShortMethod");*/
1358 va_start(vaargs, methodID);
1359 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
1366 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1368 STATS(jniinvokation();)
1369 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
1373 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1375 STATS(jniinvokation();)
1376 log_text("JNI-Call: CallShortMethodA");
1383 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1387 STATS(jniinvokation();)
1389 va_start(vaargs,methodID);
1390 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
1397 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1399 STATS(jniinvokation();)
1400 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
1404 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1406 STATS(jniinvokation();)
1407 log_text("JNI-Call: CallIntMethodA");
1414 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1418 STATS(jniinvokation();)
1420 va_start(vaargs,methodID);
1421 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1428 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1430 STATS(jniinvokation();)
1431 return callLongMethod(obj,get_virtual(obj, methodID),args);
1435 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1437 STATS(jniinvokation();)
1438 log_text("JNI-Call: CallLongMethodA");
1445 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1450 STATS(jniinvokation();)
1451 /* log_text("JNI-Call: CallFloatMethod");*/
1453 va_start(vaargs,methodID);
1454 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
1461 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1463 STATS(jniinvokation();)
1464 log_text("JNI-Call: CallFloatMethodV");
1465 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
1469 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1471 STATS(jniinvokation();)
1472 log_text("JNI-Call: CallFloatMethodA");
1479 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1483 STATS(jniinvokation();)
1485 /* log_text("JNI-Call: CallDoubleMethod");*/
1487 va_start(vaargs,methodID);
1488 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
1495 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1497 STATS(jniinvokation();)
1498 log_text("JNI-Call: CallDoubleMethodV");
1499 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
1503 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1505 STATS(jniinvokation();)
1506 log_text("JNI-Call: CallDoubleMethodA");
1512 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1515 STATS(jniinvokation();)
1517 va_start(vaargs,methodID);
1518 (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
1523 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1525 log_text("JNI-Call: CallVoidMethodV");
1526 STATS(jniinvokation();)
1527 (void)callIntegerMethod(obj,get_virtual(obj,methodID),TYPE_VOID,args);
1531 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1533 STATS(jniinvokation();)
1534 log_text("JNI-Call: CallVoidMethodA");
1539 jobject CallNonvirtualObjectMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1541 STATS(jniinvokation();)
1542 log_text("JNI-Call: CallNonvirtualObjectMethod");
1548 jobject CallNonvirtualObjectMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1550 STATS(jniinvokation();)
1551 log_text("JNI-Call: CallNonvirtualObjectMethodV");
1557 jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1559 STATS(jniinvokation();)
1560 log_text("JNI-Call: CallNonvirtualObjectMethodA");
1567 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1571 STATS(jniinvokation();)
1573 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1575 va_start(vaargs,methodID);
1576 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1583 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1585 STATS(jniinvokation();)
1586 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1587 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
1591 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1593 STATS(jniinvokation();)
1594 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1601 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1606 STATS(jniinvokation();)
1607 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1609 va_start(vaargs,methodID);
1610 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
1616 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1618 STATS(jniinvokation();)
1619 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1620 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
1625 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1627 STATS(jniinvokation();)
1628 log_text("JNI-Call: CallNonvirtualByteMethodA");
1635 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1640 STATS(jniinvokation();)
1641 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1643 va_start(vaargs,methodID);
1644 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
1650 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1652 STATS(jniinvokation();)
1653 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1654 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
1658 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1660 STATS(jniinvokation();)
1661 log_text("JNI-Call: CallNonvirtualCharMethodA");
1668 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1672 STATS(jniinvokation();)
1674 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1676 va_start(vaargs,methodID);
1677 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
1683 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1685 STATS(jniinvokation();)
1686 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1687 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
1691 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1693 STATS(jniinvokation();)
1694 log_text("JNI-Call: CallNonvirtualShortMethodA");
1701 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1706 STATS(jniinvokation();)
1708 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1710 va_start(vaargs,methodID);
1711 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
1717 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1719 STATS(jniinvokation();)
1720 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1721 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
1725 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1727 STATS(jniinvokation();)
1728 log_text("JNI-Call: CallNonvirtualIntMethodA");
1735 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1737 STATS(jniinvokation();)
1738 log_text("JNI-Call: CallNonvirtualLongMethod");
1744 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1746 STATS(jniinvokation();)
1747 log_text("JNI-Call: CallNonvirtualLongMethodV");
1753 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1755 STATS(jniinvokation();)
1756 log_text("JNI-Call: CallNonvirtualLongMethodA");
1763 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1767 STATS(jniinvokation();)
1769 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1772 va_start(vaargs,methodID);
1773 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
1780 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1782 STATS(jniinvokation();)
1783 log_text("JNI-Call: CallNonvirtualFloatMethodV");
1784 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
1788 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1790 STATS(jniinvokation();)
1791 log_text("JNI-Call: CallNonvirtualFloatMethodA");
1798 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1802 STATS(jniinvokation();)
1803 log_text("JNI-Call: CallNonvirtualDoubleMethod");
1805 va_start(vaargs,methodID);
1806 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
1813 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1815 STATS(jniinvokation();)
1816 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
1817 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
1821 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1823 STATS(jniinvokation();)
1824 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
1831 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1834 STATS(jniinvokation();)
1836 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
1838 va_start(vaargs,methodID);
1839 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
1845 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1847 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
1848 STATS(jniinvokation();)
1850 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
1855 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1857 STATS(jniinvokation();)
1858 log_text("JNI-Call: CallNonvirtualVoidMethodA");
1861 /************************* JNI-functions for accessing fields ************************/
1863 jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
1866 STATS(jniinvokation();)
1868 /* log_text("========================= searching for:");
1871 f = jclass_findfield(clazz,
1872 utf_new_char ((char*) name),
1873 utf_new_char ((char*) sig)
1877 /*utf_display(clazz->name);
1880 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
1885 /*************************** retrieve fieldid, abort on error ************************/
1887 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
1889 jfieldID id = GetFieldID(env, clazz, name, sig);
1890 STATS(jniinvokation();)
1894 utf_display(clazz->name);
1895 log_text("\nfield:");
1900 log_text("setfield_critical failed");
1906 jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
1909 jobject dbg,dretval,*dpretval;
1910 long int dli1, dli2, dli3;
1912 printf("GetObjectField(1): thread: %s obj: %p name: %s desc: %s \n",GetStringUTFChars(env,
1913 ((threadobject *) THREADOBJECT)->o
1915 ,obj,((fieldinfo*)fieldID)->name->text,(fieldID->descriptor)->text);
1917 dbg = getField(obj,jobject,fieldID);
1918 dli1 = (long int) obj;
1919 dli2 = (long int) fieldID->offset;
1921 dpretval = (jobject*) dli3;
1922 dretval = *dpretval;
1927 tmp = FindClass(env, "java/lang/Object");
1928 mid = GetMethodID(env,tmp,"toString","()Ljava/lang/String;");
1929 jstr = CallObjectMethod(env,dbg,mid);*/
1931 /* printf("GetObjectField(2): retval %p (obj: %#lx + offset: %#lx = %#lx (jobject*) %p (jobject) %p\n"
1932 ,dbg, dli1, dli2, dli3,dpretval, dretval);*/
1936 STATS(jniinvokation();)
1938 return getField(obj,jobject,fieldID);
1941 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
1943 STATS(jniinvokation();)
1944 return getField(obj,jboolean,fieldID);
1948 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
1950 STATS(jniinvokation();)
1951 return getField(obj,jbyte,fieldID);
1955 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
1957 STATS(jniinvokation();)
1958 return getField(obj,jchar,fieldID);
1962 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
1964 STATS(jniinvokation();)
1965 return getField(obj,jshort,fieldID);
1969 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
1971 STATS(jniinvokation();)
1972 return getField(obj,jint,fieldID);
1976 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
1978 STATS(jniinvokation();)
1979 return getField(obj,jlong,fieldID);
1983 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
1985 STATS(jniinvokation();)
1986 return getField(obj,jfloat,fieldID);
1990 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
1992 STATS(jniinvokation();)
1993 return getField(obj,jdouble,fieldID);
1996 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
1998 STATS(jniinvokation();)
1999 setField(obj,jobject,fieldID,val);
2003 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
2005 STATS(jniinvokation();)
2006 setField(obj,jboolean,fieldID,val);
2010 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
2012 STATS(jniinvokation();)
2013 setField(obj,jbyte,fieldID,val);
2017 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
2019 STATS(jniinvokation();)
2020 setField(obj,jchar,fieldID,val);
2024 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
2026 STATS(jniinvokation();)
2027 setField(obj,jshort,fieldID,val);
2031 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
2033 STATS(jniinvokation();)
2034 setField(obj,jint,fieldID,val);
2038 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
2040 STATS(jniinvokation();)
2041 setField(obj,jlong,fieldID,val);
2045 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
2047 STATS(jniinvokation();)
2048 setField(obj,jfloat,fieldID,val);
2052 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
2054 STATS(jniinvokation();)
2055 setField(obj,jdouble,fieldID,val);
2059 /**************** JNI-functions for calling static methods **********************/
2061 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2064 STATS(jniinvokation();)
2066 m = class_resolvemethod(clazz,
2067 utf_new_char((char *) name),
2068 utf_new_char((char *) sig));
2070 if (!m || !(m->flags & ACC_STATIC)) {
2072 new_exception_message(string_java_lang_NoSuchMethodError, name);
2081 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2085 STATS(jniinvokation();)
2087 /* log_text("JNI-Call: CallStaticObjectMethod");*/
2089 va_start(vaargs, methodID);
2090 ret = callObjectMethod(0, methodID, vaargs);
2097 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2099 STATS(jniinvokation();)
2100 /* log_text("JNI-Call: CallStaticObjectMethodV"); */
2102 return callObjectMethod(0,methodID,args);
2106 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2108 STATS(jniinvokation();)
2109 log_text("JNI-Call: CallStaticObjectMethodA");
2115 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2119 STATS(jniinvokation();)
2121 va_start(vaargs, methodID);
2122 ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
2129 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2131 STATS(jniinvokation();)
2132 return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
2136 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2138 STATS(jniinvokation();)
2139 log_text("JNI-Call: CallStaticBooleanMethodA");
2145 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2149 STATS(jniinvokation();)
2151 /* log_text("JNI-Call: CallStaticByteMethod");*/
2153 va_start(vaargs, methodID);
2154 ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
2161 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2163 STATS(jniinvokation();)
2164 return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
2168 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2170 STATS(jniinvokation();)
2171 log_text("JNI-Call: CallStaticByteMethodA");
2177 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2181 STATS(jniinvokation();)
2183 /* log_text("JNI-Call: CallStaticByteMethod");*/
2185 va_start(vaargs, methodID);
2186 ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
2193 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2195 STATS(jniinvokation();)
2196 return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
2200 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2202 STATS(jniinvokation();)
2203 log_text("JNI-Call: CallStaticCharMethodA");
2210 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2214 STATS(jniinvokation();)
2216 /* log_text("JNI-Call: CallStaticByteMethod");*/
2218 va_start(vaargs, methodID);
2219 ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
2226 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2228 STATS(jniinvokation();)
2229 /*log_text("JNI-Call: CallStaticShortMethodV");*/
2230 return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
2234 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2236 STATS(jniinvokation();)
2237 log_text("JNI-Call: CallStaticShortMethodA");
2244 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2248 STATS(jniinvokation();)
2250 /* log_text("JNI-Call: CallStaticIntMethod");*/
2252 va_start(vaargs, methodID);
2253 ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
2260 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2262 STATS(jniinvokation();)
2263 log_text("JNI-Call: CallStaticIntMethodV");
2265 return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
2269 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2271 STATS(jniinvokation();)
2272 log_text("JNI-Call: CallStaticIntMethodA");
2279 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2283 STATS(jniinvokation();)
2285 /* log_text("JNI-Call: CallStaticLongMethod");*/
2287 va_start(vaargs, methodID);
2288 ret = callLongMethod(0, methodID, vaargs);
2295 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2297 STATS(jniinvokation();)
2298 log_text("JNI-Call: CallStaticLongMethodV");
2300 return callLongMethod(0,methodID,args);
2304 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2306 STATS(jniinvokation();)
2307 log_text("JNI-Call: CallStaticLongMethodA");
2314 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2318 STATS(jniinvokation();)
2320 /* log_text("JNI-Call: CallStaticLongMethod");*/
2322 va_start(vaargs, methodID);
2323 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
2330 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2332 STATS(jniinvokation();)
2334 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
2339 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2341 STATS(jniinvokation();)
2342 log_text("JNI-Call: CallStaticFloatMethodA");
2349 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2353 STATS(jniinvokation();)
2355 /* log_text("JNI-Call: CallStaticDoubleMethod");*/
2357 va_start(vaargs,methodID);
2358 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
2365 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2367 STATS(jniinvokation();)
2368 log_text("JNI-Call: CallStaticDoubleMethodV");
2370 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
2374 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2376 STATS(jniinvokation();)
2377 log_text("JNI-Call: CallStaticDoubleMethodA");
2383 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2386 STATS(jniinvokation();)
2388 va_start(vaargs, methodID);
2389 (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
2394 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2396 log_text("JNI-Call: CallStaticVoidMethodV");
2397 STATS(jniinvokation();)
2398 (void)callIntegerMethod(0, methodID, TYPE_VOID, args);
2402 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2404 STATS(jniinvokation();)
2405 log_text("JNI-Call: CallStaticVoidMethodA");
2409 /* Accessing Static Fields ****************************************************/
2411 /* GetStaticFieldID ************************************************************
2413 Returns the field ID for a static field of a class. The field is
2414 specified by its name and signature. The GetStatic<type>Field and
2415 SetStatic<type>Field families of accessor functions use field IDs
2416 to retrieve static fields.
2418 *******************************************************************************/
2420 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2423 STATS(jniinvokation();)
2425 f = jclass_findfield(clazz,
2426 utf_new_char((char *) name),
2427 utf_new_char((char *) sig));
2430 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2436 /* GetStatic<type>Field ********************************************************
2438 This family of accessor routines returns the value of a static
2441 *******************************************************************************/
2443 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2445 STATS(jniinvokation();)
2446 JWCLINITDEBUG(printf("GetStaticObjectField: calling initialize_class %s\n",clazz->name->text);)
2447 if (!initialize_class(clazz))
2450 return fieldID->value.a;
2454 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2456 STATS(jniinvokation();)
2457 JWCLINITDEBUG(printf("GetStaticBooleanField: calling initialize_class %s\n",clazz->name->text);)
2459 if (!initialize_class(clazz))
2462 return fieldID->value.i;
2466 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2468 STATS(jniinvokation();)
2469 JWCLINITDEBUG(printf("GetStaticByteField: calling initialize_class %s\n",clazz->name->text);)
2471 if (!initialize_class(clazz))
2474 return fieldID->value.i;
2478 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2480 STATS(jniinvokation();)
2481 JWCLINITDEBUG(printf("GetStaticCharField: calling initialize_class %s\n",clazz->name->text);)
2483 if (!initialize_class(clazz))
2486 return fieldID->value.i;
2490 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2492 STATS(jniinvokation();)
2493 JWCLINITDEBUG(printf("GetStaticShorttField: calling initialize_class %s\n",clazz->name->text);)
2494 if (!initialize_class(clazz))
2497 return fieldID->value.i;
2501 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2503 STATS(jniinvokation();)
2504 JWCLINITDEBUG(printf("GetStaticIntField: calling initialize_class %s\n",clazz->name->text);)
2505 if (!initialize_class(clazz))
2508 return fieldID->value.i;
2512 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2514 STATS(jniinvokation();)
2515 JWCLINITDEBUG(printf("GetStaticLongField: calling initialize_class %s\n",clazz->name->text);)
2516 if (!initialize_class(clazz))
2519 return fieldID->value.l;
2523 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2525 STATS(jniinvokation();)
2526 JWCLINITDEBUG(printf("GetStaticFloatField: calling initialize_class %s\n",clazz->name->text);)
2527 if (!initialize_class(clazz))
2530 return fieldID->value.f;
2534 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2536 STATS(jniinvokation();)
2537 JWCLINITDEBUG(printf("GetStaticDoubleField: calling initialize_class %s\n",clazz->name->text);)
2538 if (!initialize_class(clazz))
2541 return fieldID->value.d;
2545 /* SetStatic<type>Field *******************************************************
2547 This family of accessor routines sets the value of a static field
2550 *******************************************************************************/
2552 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2554 STATS(jniinvokation();)
2555 JWCLINITDEBUG(printf("SetStaticObjectField: calling initialize_class %s\n",clazz->name->text);)
2556 if (!initialize_class(clazz))
2559 fieldID->value.a = value;
2563 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2565 STATS(jniinvokation();)
2566 JWCLINITDEBUG(printf("SetStaticBooleanField: calling initialize_class %s\n",clazz->name->text);)
2567 if (!initialize_class(clazz))
2570 fieldID->value.i = value;
2574 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2576 STATS(jniinvokation();)
2577 JWCLINITDEBUG(printf("SetStaticByteField: calling initialize_class %s\n",clazz->name->text);)
2578 if (!initialize_class(clazz))
2581 fieldID->value.i = value;
2585 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2587 STATS(jniinvokation();)
2588 JWCLINITDEBUG(printf("SetStaticCharField: calling initialize_class %s\n",clazz->name->text);)
2589 if (!initialize_class(clazz))
2592 fieldID->value.i = value;
2596 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2598 STATS(jniinvokation();)
2599 JWCLINITDEBUG(printf("SetStaticShortField: calling initialize_class %s\n",clazz->name->text);)
2600 if (!initialize_class(clazz))
2603 fieldID->value.i = value;
2607 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2609 STATS(jniinvokation();)
2610 JWCLINITDEBUG(printf("SetStaticIntField: calling initialize_class %s\n",clazz->name->text);)
2611 if (!initialize_class(clazz))
2614 fieldID->value.i = value;
2618 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2620 STATS(jniinvokation();)
2621 JWCLINITDEBUG(printf("SetStaticLongField: calling initialize_class %s\n",clazz->name->text);)
2622 if (!initialize_class(clazz))
2625 fieldID->value.l = value;
2629 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2631 STATS(jniinvokation();)
2632 JWCLINITDEBUG(printf("SetStaticFloatField: calling initialize_class %s\n",clazz->name->text);)
2633 if (!initialize_class(clazz))
2636 fieldID->value.f = value;
2640 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2642 STATS(jniinvokation();)
2643 JWCLINITDEBUG(printf("SetStaticDoubleField: calling initialize_class %s\n",clazz->name->text);)
2644 if (!initialize_class(clazz))
2647 fieldID->value.d = value;
2651 /* NewString *******************************************************************
2653 Create new java.lang.String object from an array of Unicode
2656 *******************************************************************************/
2658 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
2660 java_lang_String *s;
2663 STATS(jniinvokation();)
2665 s = (java_lang_String *) builtin_new(class_java_lang_String);
2666 a = builtin_newarray_char(len);
2668 /* javastring or characterarray could not be created */
2673 for (i = 0; i < len; i++)
2674 a->data[i] = buf[i];
2684 static jchar emptyStringJ[]={0,0};
2686 /******************* returns the length of a Java string ***************************/
2688 jsize GetStringLength (JNIEnv *env, jstring str)
2690 return ((java_lang_String*) str)->count;
2694 /******************** convertes javastring to u2-array ****************************/
2696 u2 *javastring_tou2 (jstring so)
2698 java_lang_String *s = (java_lang_String*) so;
2702 STATS(jniinvokation();)
2704 if (!s) return NULL;
2707 if (!a) return NULL;
2709 /* allocate memory */
2710 stringbuffer = MNEW( u2 , s->count + 1 );
2713 for (i=0; i<s->count; i++) stringbuffer[i] = a->data[s->offset+i];
2715 /* terminate string */
2716 stringbuffer[i] = '\0';
2718 return stringbuffer;
2721 /********* returns a pointer to an array of Unicode characters of the string *******/
2723 const jchar *GetStringChars (JNIEnv *env, jstring str, jboolean *isCopy)
2725 jchar *jc=javastring_tou2(str);
2726 STATS(jniinvokation();)
2729 if (isCopy) *isCopy=JNI_TRUE;
2732 if (isCopy) *isCopy=JNI_TRUE;
2733 return emptyStringJ;
2736 /**************** native code no longer needs access to chars **********************/
2738 void ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars)
2740 STATS(jniinvokation();)
2741 if (chars==emptyStringJ) return;
2742 MFREE(((jchar*) chars),jchar,((java_lang_String*) str)->count+1);
2746 /* NewStringUTF ****************************************************************
2748 Constructs a new java.lang.String object from an array of UTF-8 characters.
2750 *******************************************************************************/
2752 jstring NewStringUTF(JNIEnv *env, const char *bytes)
2754 STATS(jniinvokation();)
2755 return (jstring) javastring_new(utf_new_char(bytes));
2759 /****************** returns the utf8 length in bytes of a string *******************/
2761 jsize GetStringUTFLength (JNIEnv *env, jstring string)
2763 java_lang_String *s = (java_lang_String*) string;
2764 STATS(jniinvokation();)
2766 return (jsize) u2_utflength(s->value->data, s->count);
2770 /* GetStringUTFChars ***********************************************************
2772 Returns a pointer to an array of UTF-8 characters of the
2773 string. This array is valid until it is released by
2774 ReleaseStringUTFChars().
2776 *******************************************************************************/
2778 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
2781 STATS(jniinvokation();)
2789 u = javastring_toutf((java_lang_String *) string, false);
2798 /***************** native code no longer needs access to utf ***********************/
2800 void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
2802 STATS(jniinvokation();)
2804 /*we don't release utf chars right now, perhaps that should be done later. Since there is always one reference
2805 the garbage collector will never get them*/
2807 log_text("JNI-Call: ReleaseStringUTFChars");
2808 utf_display(utf_new_char(chars));
2812 /************************** array operations ***************************************/
2814 jsize GetArrayLength(JNIEnv *env, jarray array)
2816 STATS(jniinvokation();)
2822 /* NewObjectArray **************************************************************
2824 Constructs a new array holding objects in class elementClass. All
2825 elements are initially set to initialElement.
2827 *******************************************************************************/
2829 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
2831 java_objectarray *oa;
2833 STATS(jniinvokation();)
2836 *exceptionptr = new_negativearraysizeexception();
2840 oa = builtin_anewarray(length, elementClass);
2845 /* set all elements to initialElement */
2847 for (i = 0; i < length; i++)
2848 oa->data[i] = initialElement;
2854 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
2857 STATS(jniinvokation();)
2859 if (index < array->header.size)
2860 j = array->data[index];
2862 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2868 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
2870 STATS(jniinvokation();)
2871 if (index >= array->header.size)
2872 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2875 /* check if the class of value is a subclass of the element class of the array */
2876 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
2877 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
2880 array->data[index] = val;
2886 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
2888 java_booleanarray *j;
2889 STATS(jniinvokation();)
2892 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2896 j = builtin_newarray_boolean(len);
2902 jbyteArray NewByteArray(JNIEnv *env, jsize len)
2905 STATS(jniinvokation();)
2908 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2912 j = builtin_newarray_byte(len);
2918 jcharArray NewCharArray(JNIEnv *env, jsize len)
2921 STATS(jniinvokation();)
2924 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2928 j = builtin_newarray_char(len);
2934 jshortArray NewShortArray(JNIEnv *env, jsize len)
2937 STATS(jniinvokation();)
2940 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2944 j = builtin_newarray_short(len);
2950 jintArray NewIntArray(JNIEnv *env, jsize len)
2953 STATS(jniinvokation();)
2956 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2960 j = builtin_newarray_int(len);
2966 jlongArray NewLongArray(JNIEnv *env, jsize len)
2969 STATS(jniinvokation();)
2972 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2976 j = builtin_newarray_long(len);
2982 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
2985 STATS(jniinvokation();)
2988 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2992 j = builtin_newarray_float(len);
2998 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3000 java_doublearray *j;
3001 STATS(jniinvokation();)
3004 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
3008 j = builtin_newarray_double(len);
3014 jboolean * GetBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *isCopy)
3016 STATS(jniinvokation();)
3017 if (isCopy) *isCopy = JNI_FALSE;
3022 jbyte * GetByteArrayElements (JNIEnv *env, jbyteArray array, jboolean *isCopy)
3024 STATS(jniinvokation();)
3025 if (isCopy) *isCopy = JNI_FALSE;
3030 jchar * GetCharArrayElements (JNIEnv *env, jcharArray array, jboolean *isCopy)
3032 STATS(jniinvokation();)
3033 if (isCopy) *isCopy = JNI_FALSE;
3038 jshort * GetShortArrayElements (JNIEnv *env, jshortArray array, jboolean *isCopy)
3040 STATS(jniinvokation();)
3041 if (isCopy) *isCopy = JNI_FALSE;
3046 jint * GetIntArrayElements (JNIEnv *env, jintArray array, jboolean *isCopy)
3048 STATS(jniinvokation();)
3049 if (isCopy) *isCopy = JNI_FALSE;
3054 jlong * GetLongArrayElements (JNIEnv *env, jlongArray array, jboolean *isCopy)
3056 STATS(jniinvokation();)
3057 if (isCopy) *isCopy = JNI_FALSE;
3062 jfloat * GetFloatArrayElements (JNIEnv *env, jfloatArray array, jboolean *isCopy)
3064 STATS(jniinvokation();)
3065 if (isCopy) *isCopy = JNI_FALSE;
3070 jdouble * GetDoubleArrayElements (JNIEnv *env, jdoubleArray array, jboolean *isCopy)
3072 STATS(jniinvokation();)
3073 if (isCopy) *isCopy = JNI_FALSE;
3079 void ReleaseBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode)
3081 STATS(jniinvokation();)
3086 void ReleaseByteArrayElements (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode)
3088 STATS(jniinvokation();)
3093 void ReleaseCharArrayElements (JNIEnv *env, jcharArray array, jchar *elems, jint mode)
3099 void ReleaseShortArrayElements (JNIEnv *env, jshortArray array, jshort *elems, jint mode)
3101 STATS(jniinvokation();)
3106 void ReleaseIntArrayElements (JNIEnv *env, jintArray array, jint *elems, jint mode)
3108 STATS(jniinvokation();)
3113 void ReleaseLongArrayElements (JNIEnv *env, jlongArray array, jlong *elems, jint mode)
3115 STATS(jniinvokation();)
3120 void ReleaseFloatArrayElements (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode)
3122 STATS(jniinvokation();)
3127 void ReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode)
3129 STATS(jniinvokation();)
3134 void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
3136 STATS(jniinvokation();)
3137 if (start < 0 || len < 0 || start + len > array->header.size)
3138 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3141 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
3145 void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
3147 STATS(jniinvokation();)
3148 if (start < 0 || len < 0 || start + len > array->header.size)
3149 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3152 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
3156 void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
3158 STATS(jniinvokation();)
3159 if (start < 0 || len < 0 || start + len > array->header.size)
3160 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3163 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
3167 void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
3169 STATS(jniinvokation();)
3170 if (start < 0 || len < 0 || start + len > array->header.size)
3171 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3174 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
3178 void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
3180 STATS(jniinvokation();)
3181 if (start < 0 || len < 0 || start + len > array->header.size)
3182 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3185 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
3189 void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
3191 STATS(jniinvokation();)
3192 if (start < 0 || len < 0 || start + len > array->header.size)
3193 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3196 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
3200 void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
3202 STATS(jniinvokation();)
3203 if (start < 0 || len < 0 || start + len > array->header.size)
3204 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3207 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
3211 void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
3213 STATS(jniinvokation();)
3214 if (start < 0 || len < 0 || start+len>array->header.size)
3215 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3218 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
3222 void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
3224 STATS(jniinvokation();)
3225 if (start < 0 || len < 0 || start + len > array->header.size)
3226 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3229 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3233 void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
3235 STATS(jniinvokation();)
3236 if (start < 0 || len < 0 || start + len > array->header.size)
3237 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3240 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3244 void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
3246 STATS(jniinvokation();)
3247 if (start < 0 || len < 0 || start + len > array->header.size)
3248 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3251 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3256 void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
3258 STATS(jniinvokation();)
3259 if (start < 0 || len < 0 || start + len > array->header.size)
3260 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3263 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3267 void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
3269 STATS(jniinvokation();)
3270 if (start < 0 || len < 0 || start + len > array->header.size)
3271 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3274 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3279 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
3281 STATS(jniinvokation();)
3282 if (start < 0 || len < 0 || start + len > array->header.size)
3283 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3286 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3291 void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
3293 STATS(jniinvokation();)
3294 if (start < 0 || len < 0 || start + len > array->header.size)
3295 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3298 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3303 void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
3305 STATS(jniinvokation();)
3306 if (start < 0 || len < 0 || start + len > array->header.size)
3307 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3310 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3314 jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
3316 STATS(jniinvokation();)
3317 log_text("JNI-Call: RegisterNatives");
3322 jint UnregisterNatives (JNIEnv* env, jclass clazz)
3324 STATS(jniinvokation();)
3325 log_text("JNI-Call: UnregisterNatives");
3330 /* Monitor Operations *********************************************************/
3332 /* MonitorEnter ****************************************************************
3334 Enters the monitor associated with the underlying Java object
3337 *******************************************************************************/
3339 jint MonitorEnter(JNIEnv *env, jobject obj)
3341 STATS(jniinvokation();)
3343 *exceptionptr = new_nullpointerexception();
3347 #if defined(USE_THREADS)
3348 builtin_monitorenter(obj);
3355 /* MonitorExit *****************************************************************
3357 The current thread must be the owner of the monitor associated with
3358 the underlying Java object referred to by obj. The thread
3359 decrements the counter indicating the number of times it has
3360 entered this monitor. If the value of the counter becomes zero, the
3361 current thread releases the monitor.
3363 *******************************************************************************/
3365 jint MonitorExit(JNIEnv *env, jobject obj)
3367 STATS(jniinvokation();)
3369 *exceptionptr = new_nullpointerexception();
3373 #if defined(USE_THREADS)
3374 builtin_monitorexit(obj);
3381 /* JavaVM Interface ***********************************************************/
3383 /* GetJavaVM *******************************************************************
3385 Returns the Java VM interface (used in the Invocation API)
3386 associated with the current thread. The result is placed at the
3387 location pointed to by the second argument, vm.
3389 *******************************************************************************/
3391 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
3393 STATS(jniinvokation();)
3400 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3402 STATS(jniinvokation();)
3403 log_text("JNI-Call: GetStringRegion");
3407 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3409 STATS(jniinvokation();)
3410 log_text("JNI-Call: GetStringUTFRegion");
3414 /************** obtain direct pointer to array elements ***********************/
3416 void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
3418 java_objectheader *s = (java_objectheader*) array;
3419 arraydescriptor *desc = s->vftbl->arraydesc;
3421 STATS(jniinvokation();)
3423 if (!desc) return NULL;
3425 return ((u1*)s) + desc->dataoffset;
3429 void ReleasePrimitiveArrayCritical (JNIEnv* env, jarray array, void *carray, jint mode)
3431 STATS(jniinvokation();)
3432 log_text("JNI-Call: ReleasePrimitiveArrayCritical");
3437 /**** returns a pointer to an array of Unicode characters of the string *******/
3439 const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
3441 STATS(jniinvokation();)
3442 log_text("JNI-Call: GetStringCritical");
3444 return GetStringChars(env,string,isCopy);
3447 /*********** native code no longer needs access to chars **********************/
3449 void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
3451 STATS(jniinvokation();)
3452 log_text("JNI-Call: ReleaseStringCritical");
3454 ReleaseStringChars(env,string,cstring);
3458 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3460 STATS(jniinvokation();)
3461 log_text("JNI-Call: NewWeakGlobalRef");
3467 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
3469 STATS(jniinvokation();)
3470 log_text("JNI-Call: DeleteWeakGlobalRef");
3476 /** Creates a new global reference to the object referred to by the obj argument **/
3478 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
3483 STATS(jniinvokation();)
3485 MonitorEnter(env, *global_ref_table);
3487 refcount = CallObjectMethod(env, *global_ref_table, getmid, lobj);
3488 val = (refcount == NULL) ? 0 : CallIntMethod(env, refcount, intvalue);
3489 newval = NewObject(env, intclass, newint, val + 1);
3491 if (newval != NULL) {
3492 CallObjectMethod(env, *global_ref_table, putmid, lobj, newval);
3493 MonitorExit(env, *global_ref_table);
3497 log_text("JNI-NewGlobalRef: unable to create new java.lang.Integer");
3498 MonitorExit(env, *global_ref_table);
3503 /************* Deletes the global reference pointed to by globalRef **************/
3505 void DeleteGlobalRef(JNIEnv* env, jobject gref)
3509 STATS(jniinvokation();)
3511 MonitorEnter(env, *global_ref_table);
3512 refcount = CallObjectMethod(env, *global_ref_table, getmid, gref);
3514 if (refcount == NULL) {
3515 log_text("JNI-DeleteGlobalRef: unable to find global reference");
3519 val = CallIntMethod(env, refcount, intvalue);
3523 CallObjectMethod(env, *global_ref_table, removemid,refcount);
3526 jobject newval = NewObject(env, intclass, newint, val);
3528 if (newval != NULL) {
3529 CallObjectMethod(env,*global_ref_table, putmid,newval);
3532 log_text("JNI-DeleteGlobalRef: unable to create new java.lang.Integer");
3536 MonitorExit(env,*global_ref_table);
3540 /* ExceptionCheck **************************************************************
3542 Returns JNI_TRUE when there is a pending exception; otherwise,
3545 *******************************************************************************/
3547 jboolean ExceptionCheck(JNIEnv *env)
3549 STATS(jniinvokation();)
3550 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
3554 /* New JNI 1.4 functions ******************************************************/
3556 /* NewDirectByteBuffer *********************************************************
3558 Allocates and returns a direct java.nio.ByteBuffer referring to the
3559 block of memory starting at the memory address address and
3560 extending capacity bytes.
3562 *******************************************************************************/
3564 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3566 STATS(jniinvokation();)
3567 log_text("NewDirectByteBuffer: IMPLEMENT ME!");
3573 /* GetDirectBufferAddress ******************************************************
3575 Fetches and returns the starting address of the memory region
3576 referenced by the given direct java.nio.Buffer.
3578 *******************************************************************************/
3580 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
3582 STATS(jniinvokation();)
3583 log_text("GetDirectBufferAddress: IMPLEMENT ME!");
3589 /* GetDirectBufferCapacity *****************************************************
3591 Fetches and returns the capacity in bytes of the memory region
3592 referenced by the given direct java.nio.Buffer.
3594 *******************************************************************************/
3596 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3598 STATS(jniinvokation();)
3599 log_text("GetDirectBufferCapacity: IMPLEMENT ME!");
3605 jint DestroyJavaVM(JavaVM *vm)
3607 STATS(jniinvokation();)
3608 log_text("DestroyJavaVM called");
3614 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
3616 STATS(jniinvokation();)
3617 log_text("AttachCurrentThread called");
3619 #if !defined(HAVE___THREAD)
3620 /* cacao_thread_attach();*/
3622 #error "No idea how to implement that. Perhaps Stefan knows"
3630 jint DetachCurrentThread(JavaVM *vm)
3632 STATS(jniinvokation();)
3633 log_text("DetachCurrentThread called");
3639 jint GetEnv(JavaVM *vm, void **env, jint version)
3641 STATS(jniinvokation();)
3642 if ((version != JNI_VERSION_1_1) && (version != JNI_VERSION_1_2) &&
3643 (version != JNI_VERSION_1_4)) {
3645 return JNI_EVERSION;
3649 TODO: If the current thread is not attached to the VM...
3652 return JNI_EDETACHED;
3662 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
3664 STATS(jniinvokation();)
3665 log_text("AttachCurrentThreadAsDaemon called");
3670 /************* JNI Initialization ****************************************************/
3672 jobject jni_init1(JNIEnv* env, jobject lobj) {
3673 #if defined(USE_THREADS)
3674 while (initrunning) {yieldThread();} /* wait until init is done */
3676 if (global_ref_table == NULL) {
3679 #if defined(USE_THREADS)
3681 /* wait until jni_init is done */
3682 MonitorEnter(env, *global_ref_table) ;
3683 MonitorExit(env, *global_ref_table);
3686 return NewGlobalRef(env, lobj);
3688 void jni_init2(JNIEnv* env, jobject gref) {
3689 log_text("DeleteGlobalref called before NewGlobalref");
3690 #if defined(USE_THREADS)
3691 while (initrunning) {yieldThread();} /* wait until init is done */
3693 if (global_ref_table == NULL) {
3696 #if defined(USE_THREADS)
3698 /* wait until jni_init is done */
3699 MonitorEnter(env, *global_ref_table) ;
3700 MonitorExit(env, *global_ref_table);
3703 DeleteGlobalRef(env, gref);
3710 log_text("JNI-Init: initialize global_ref_table");
3711 /* initalize global reference table */
3712 ihmclass = FindClass(NULL, "java/util/IdentityHashMap");
3714 if (ihmclass == NULL) {
3715 log_text("JNI-Init: unable to find java.util.IdentityHashMap");
3718 mid = GetMethodID(NULL, ihmclass, "<init>","()V");
3720 log_text("JNI-Init: unable to find constructor in java.util.IdentityHashMap");
3723 global_ref_table = (jobject*)heap_allocate(sizeof(jobject),true,NULL);
3725 *global_ref_table = NewObject(NULL,ihmclass,mid);
3727 if (*global_ref_table == NULL) {
3728 log_text("JNI-Init: unable to create new global_ref_table");
3731 initrunning = false;
3733 getmid = GetMethodID(NULL, ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3735 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3738 getmid = GetMethodID(NULL ,ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3739 if (getmid == NULL) {
3740 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3743 putmid = GetMethodID(NULL, ihmclass, "put","(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
3744 if (putmid == NULL) {
3745 log_text("JNI-Init: unable to find method \"put\" in java.util.IdentityHashMap");
3748 intclass = FindClass(NULL, "java/lang/Integer");
3749 if (intclass == NULL) {
3750 log_text("JNI-Init: unable to find java.lang.Integer");
3753 newint = GetMethodID(NULL, intclass, "<init>","(I)V");
3754 if (newint == NULL) {
3755 log_text("JNI-Init: unable to find constructor in java.lang.Integer");
3758 intvalue = GetMethodID(NULL, intclass, "intValue","()I");
3759 if (intvalue == NULL) {
3760 log_text("JNI-Init: unable to find method \"intValue\" in java.lang.Integer");
3763 removemid = GetMethodID(NULL, ihmclass, "remove","(Ljava/lang/Object;)Ljava/lang/Object;");
3764 if (removemid == NULL) {
3765 log_text("JNI-DeleteGlobalRef: unable to find method \"remove\" in java.lang.Object");
3768 /* set NewGlobalRef, DeleteGlobalRef envTable entry to real implementation */
3770 JNI_JNIEnvTable.NewGlobalRef = &NewGlobalRef;
3771 JNI_JNIEnvTable.DeleteGlobalRef = &DeleteGlobalRef;
3775 /* JNI invocation table *******************************************************/
3777 const struct JNIInvokeInterface JNI_JavaVMTable = {
3783 AttachCurrentThread,
3784 DetachCurrentThread,
3786 AttachCurrentThreadAsDaemon
3790 /* JNI function table *********************************************************/
3792 struct JNINativeInterface JNI_JNIEnvTable = {
3801 &FromReflectedMethod,
3802 &FromReflectedField,
3817 &jni_init1, /* &NewGlobalRef, initialize Global_Ref_Table*/
3818 &jni_init2, /* &DeleteGlobalRef,*/
3822 &EnsureLocalCapacity,
3838 &CallBooleanMethodV,
3839 &CallBooleanMethodA,
3865 &CallNonvirtualObjectMethod,
3866 &CallNonvirtualObjectMethodV,
3867 &CallNonvirtualObjectMethodA,
3868 &CallNonvirtualBooleanMethod,
3869 &CallNonvirtualBooleanMethodV,
3870 &CallNonvirtualBooleanMethodA,
3871 &CallNonvirtualByteMethod,
3872 &CallNonvirtualByteMethodV,
3873 &CallNonvirtualByteMethodA,
3874 &CallNonvirtualCharMethod,
3875 &CallNonvirtualCharMethodV,
3876 &CallNonvirtualCharMethodA,
3877 &CallNonvirtualShortMethod,
3878 &CallNonvirtualShortMethodV,
3879 &CallNonvirtualShortMethodA,
3880 &CallNonvirtualIntMethod,
3881 &CallNonvirtualIntMethodV,
3882 &CallNonvirtualIntMethodA,
3883 &CallNonvirtualLongMethod,
3884 &CallNonvirtualLongMethodV,
3885 &CallNonvirtualLongMethodA,
3886 &CallNonvirtualFloatMethod,
3887 &CallNonvirtualFloatMethodV,
3888 &CallNonvirtualFloatMethodA,
3889 &CallNonvirtualDoubleMethod,
3890 &CallNonvirtualDoubleMethodV,
3891 &CallNonvirtualDoubleMethodA,
3892 &CallNonvirtualVoidMethod,
3893 &CallNonvirtualVoidMethodV,
3894 &CallNonvirtualVoidMethodA,
3919 &CallStaticObjectMethod,
3920 &CallStaticObjectMethodV,
3921 &CallStaticObjectMethodA,
3922 &CallStaticBooleanMethod,
3923 &CallStaticBooleanMethodV,
3924 &CallStaticBooleanMethodA,
3925 &CallStaticByteMethod,
3926 &CallStaticByteMethodV,
3927 &CallStaticByteMethodA,
3928 &CallStaticCharMethod,
3929 &CallStaticCharMethodV,
3930 &CallStaticCharMethodA,
3931 &CallStaticShortMethod,
3932 &CallStaticShortMethodV,
3933 &CallStaticShortMethodA,
3934 &CallStaticIntMethod,
3935 &CallStaticIntMethodV,
3936 &CallStaticIntMethodA,
3937 &CallStaticLongMethod,
3938 &CallStaticLongMethodV,
3939 &CallStaticLongMethodA,
3940 &CallStaticFloatMethod,
3941 &CallStaticFloatMethodV,
3942 &CallStaticFloatMethodA,
3943 &CallStaticDoubleMethod,
3944 &CallStaticDoubleMethodV,
3945 &CallStaticDoubleMethodA,
3946 &CallStaticVoidMethod,
3947 &CallStaticVoidMethodV,
3948 &CallStaticVoidMethodA,
3952 &GetStaticObjectField,
3953 &GetStaticBooleanField,
3954 &GetStaticByteField,
3955 &GetStaticCharField,
3956 &GetStaticShortField,
3958 &GetStaticLongField,
3959 &GetStaticFloatField,
3960 &GetStaticDoubleField,
3961 &SetStaticObjectField,
3962 &SetStaticBooleanField,
3963 &SetStaticByteField,
3964 &SetStaticCharField,
3965 &SetStaticShortField,
3967 &SetStaticLongField,
3968 &SetStaticFloatField,
3969 &SetStaticDoubleField,
3974 &ReleaseStringChars,
3977 &GetStringUTFLength,
3979 &ReleaseStringUTFChars,
3984 &GetObjectArrayElement,
3985 &SetObjectArrayElement,
3996 &GetBooleanArrayElements,
3997 &GetByteArrayElements,
3998 &GetCharArrayElements,
3999 &GetShortArrayElements,
4000 &GetIntArrayElements,
4001 &GetLongArrayElements,
4002 &GetFloatArrayElements,
4003 &GetDoubleArrayElements,
4005 &ReleaseBooleanArrayElements,
4006 &ReleaseByteArrayElements,
4007 &ReleaseCharArrayElements,
4008 &ReleaseShortArrayElements,
4009 &ReleaseIntArrayElements,
4010 &ReleaseLongArrayElements,
4011 &ReleaseFloatArrayElements,
4012 &ReleaseDoubleArrayElements,
4014 &GetBooleanArrayRegion,
4015 &GetByteArrayRegion,
4016 &GetCharArrayRegion,
4017 &GetShortArrayRegion,
4019 &GetLongArrayRegion,
4020 &GetFloatArrayRegion,
4021 &GetDoubleArrayRegion,
4022 &SetBooleanArrayRegion,
4023 &SetByteArrayRegion,
4024 &SetCharArrayRegion,
4025 &SetShortArrayRegion,
4027 &SetLongArrayRegion,
4028 &SetFloatArrayRegion,
4029 &SetDoubleArrayRegion,
4039 /* new JNI 1.2 functions */
4042 &GetStringUTFRegion,
4044 &GetPrimitiveArrayCritical,
4045 &ReleasePrimitiveArrayCritical,
4048 &ReleaseStringCritical,
4051 &DeleteWeakGlobalRef,
4055 /* new JNI 1.4 functions */
4057 &NewDirectByteBuffer,
4058 &GetDirectBufferAddress,
4059 &GetDirectBufferCapacity
4063 /* Invocation API Functions ***************************************************/
4065 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4067 Returns a default configuration for the Java VM.
4069 *******************************************************************************/
4071 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4073 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4075 /* GNU classpath currently supports JNI 1.2 */
4077 _vm_args->version = JNI_VERSION_1_2;
4083 /* JNI_GetCreatedJavaVMs *******************************************************
4085 Returns all Java VMs that have been created. Pointers to VMs are written in
4086 the buffer vmBuf in the order they are created. At most bufLen number of
4087 entries will be written. The total number of created VMs is returned in
4090 *******************************************************************************/
4092 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4094 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4100 /* JNI_CreateJavaVM ************************************************************
4102 Loads and initializes a Java VM. The current thread becomes the main thread.
4103 Sets the env argument to the JNI interface pointer of the main thread.
4105 *******************************************************************************/
4107 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4109 *p_vm = (JavaVM *) &JNI_JavaVMTable;
4110 *p_env = (JNIEnv *) &JNI_JNIEnvTable;
4116 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4117 jobject obj, java_objectarray *params)
4123 if (methodID == 0) {
4124 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
4128 argcount = methodID->parseddesc->paramcount;
4130 /* if method is non-static, remove the `this' pointer */
4132 if (!(methodID->flags & ACC_STATIC))
4135 /* the method is an instance method the obj has to be an instance of the
4136 class the method belongs to. For static methods the obj parameter
4139 if (!(methodID->flags & ACC_STATIC) && obj &&
4140 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4142 new_exception_message(string_java_lang_IllegalArgumentException,
4143 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4150 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
4151 log_text("Too many arguments. invokeNativeHelper does not support that");
4156 if (((params == NULL) && (argcount != 0)) ||
4157 (params && (params->header.size != argcount))) {
4159 new_exception(string_java_lang_IllegalArgumentException);
4164 if (!(methodID->flags & ACC_STATIC) && !obj) {
4166 new_exception_message(string_java_lang_NullPointerException,
4167 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4171 if ((methodID->flags & ACC_STATIC) && (obj))
4175 if ((methodID->flags & ACC_ABSTRACT) ||
4176 (methodID->class->flags & ACC_INTERFACE)) {
4177 methodID = get_virtual(obj, methodID);
4181 blk = MNEW(jni_callblock, /*4 */argcount + 2);
4183 if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4187 switch (methodID->parseddesc->returntype.decltype) {
4189 (void) asm_calljavafunction2(methodID, argcount + 1,
4190 (argcount + 1) * sizeof(jni_callblock),
4192 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4195 case PRIMITIVETYPE_INT: {
4197 i = asm_calljavafunction2int(methodID, argcount + 1,
4198 (argcount + 1) * sizeof(jni_callblock),
4201 o = native_new_and_init_int(class_java_lang_Integer, i);
4205 case PRIMITIVETYPE_BYTE: {
4207 i = asm_calljavafunction2int(methodID, argcount + 1,
4208 (argcount + 1) * sizeof(jni_callblock),
4211 /* o = native_new_and_init_int(class_java_lang_Byte, i); */
4212 o = builtin_new(class_java_lang_Byte);
4215 class_resolvemethod(o->vftbl->class,
4222 case PRIMITIVETYPE_CHAR: {
4224 intVal = asm_calljavafunction2int(methodID,
4226 (argcount + 1) * sizeof(jni_callblock),
4228 o = builtin_new(class_java_lang_Character);
4231 class_resolvemethod(o->vftbl->class,
4238 case PRIMITIVETYPE_SHORT: {
4240 intVal = asm_calljavafunction2int(methodID,
4242 (argcount + 1) * sizeof(jni_callblock),
4244 o = builtin_new(class_java_lang_Short);
4247 class_resolvemethod(o->vftbl->class,
4254 case PRIMITIVETYPE_BOOLEAN: {
4256 intVal = asm_calljavafunction2int(methodID,
4258 (argcount + 1) * sizeof(jni_callblock),
4260 o = builtin_new(class_java_lang_Boolean);
4263 class_resolvemethod(o->vftbl->class,
4272 longVal = asm_calljavafunction2long(methodID,
4274 (argcount + 1) * sizeof(jni_callblock),
4276 o = builtin_new(class_java_lang_Long);
4279 class_resolvemethod(o->vftbl->class,
4286 case PRIMITIVETYPE_FLOAT: {
4288 floatVal = asm_calljavafunction2float(methodID,
4290 (argcount + 1) * sizeof(jni_callblock),
4292 o = builtin_new(class_java_lang_Float);
4295 class_resolvemethod(o->vftbl->class,
4302 case PRIMITIVETYPE_DOUBLE: {
4304 doubleVal = asm_calljavafunction2double(methodID,
4306 (argcount + 1) * sizeof(jni_callblock),
4308 o = builtin_new(class_java_lang_Double);
4311 class_resolvemethod(o->vftbl->class,
4319 o = asm_calljavafunction2(methodID, argcount + 1,
4320 (argcount + 1) * sizeof(jni_callblock), blk);
4324 /* if this happens the exception has already been set by */
4325 /* fill_callblock_from_objectarray */
4327 MFREE(blk, jni_callblock, /*4 */ argcount+2);
4328 return (jobject *) 0;
4331 MFREE(blk, jni_callblock, /* 4 */ argcount+2);
4333 if (*exceptionptr) {
4334 java_objectheader *cause;
4336 cause = *exceptionptr;
4338 /* clear exception pointer, we are calling JIT code again */
4340 *exceptionptr = NULL;
4343 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
4344 (java_lang_Throwable *) cause);
4347 return (jobject *) o;
4352 * These are local overrides for various environment variables in Emacs.
4353 * Please do not remove this and leave it at the end of the file, where
4354 * Emacs will automagically detect them.
4355 * ---------------------------------------------------------------------
4358 * indent-tabs-mode: t