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 2995 2005-07-12 01:37:15Z michi $
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) \
121 setField(obj, jdatatype, getFieldID_critical(env,clazz,name,sig), val);
124 static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
125 jni_callblock blk[], va_list data,
128 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 = (s8) va_arg(data, s4);
157 case PRIMITIVETYPE_INT:
158 blk[i].itemtype = TYPE_INT;
159 blk[i].item = (s8) va_arg(data, s4);
162 case PRIMITIVETYPE_LONG:
163 blk[i].itemtype = TYPE_LNG;
164 blk[i].item = (s8) va_arg(data, s8);
167 case PRIMITIVETYPE_FLOAT:
168 blk[i].itemtype = TYPE_FLT;
169 #if defined(__ALPHA__)
170 /* this keeps the assembler function much simpler */
172 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
174 *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
178 case PRIMITIVETYPE_DOUBLE:
179 blk[i].itemtype = TYPE_DBL;
180 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
184 blk[i].itemtype = TYPE_ADR;
185 blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
190 /* The standard doesn't say anything about return value checking, but it */
191 /* appears to be useful. */
193 if (rettype != descr->returntype.decltype)
194 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
198 /* XXX it could be considered if we should do typechecking here in the future */
200 static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
202 java_objectarray *params)
206 typedesc *paramtypes;
211 paramcount = descr->paramcount;
212 paramtypes = descr->paramtypes;
214 /* if method is non-static fill first block and skip `this' pointer */
220 blk[0].itemtype = TYPE_ADR;
221 blk[0].item = PTR_TO_ITEM(obj);
228 for (j = 0; j < paramcount; i++, j++, paramtypes++) {
229 switch (paramtypes->type) {
230 /* primitive types */
235 param = params->data[j];
239 /* internally used data type */
240 blk[i].itemtype = paramtypes->type;
242 /* convert the value according to its declared type */
244 c = param->vftbl->class;
246 switch (paramtypes->decltype) {
247 case PRIMITIVETYPE_BOOLEAN:
248 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
249 blk[i].item = (s8) ((java_lang_Boolean *) param)->value;
254 case PRIMITIVETYPE_BYTE:
255 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
256 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
261 case PRIMITIVETYPE_CHAR:
262 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
263 blk[i].item = (s8) ((java_lang_Character *) param)->value;
268 case PRIMITIVETYPE_SHORT:
269 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
270 blk[i].item = (s8) ((java_lang_Short *) param)->value;
271 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
272 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
277 case PRIMITIVETYPE_INT:
278 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
279 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
280 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
281 blk[i].item = (s8) ((java_lang_Short *) param)->value;
282 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
283 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
288 case PRIMITIVETYPE_LONG:
289 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
290 blk[i].item = (s8) ((java_lang_Long *) param)->value;
291 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
292 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
293 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
294 blk[i].item = (s8) ((java_lang_Short *) param)->value;
295 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
296 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
301 case PRIMITIVETYPE_FLOAT:
302 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
303 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
308 case PRIMITIVETYPE_DOUBLE:
309 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
310 *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Float *) param)->value;
311 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
312 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
319 } /* end declared type switch */
323 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
326 if (params->data[j] != 0) {
327 if (paramtypes->arraydim > 0) {
328 if (!builtin_arrayinstanceof(params->data[j], c->vftbl))
332 if (!builtin_instanceof(params->data[j], c))
336 blk[i].itemtype = TYPE_ADR;
337 blk[i].item = PTR_TO_ITEM(params->data[j]);
342 } /* end param type switch */
344 } /* end param loop */
347 /* *rettype = descr->returntype.decltype; */
352 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
357 static jmethodID get_virtual(jobject obj, jmethodID methodID)
359 if (obj->vftbl->class == methodID->class)
362 return class_resolvemethod(obj->vftbl->class, methodID->name,
363 methodID->descriptor);
367 static jmethodID get_nonvirtual(jclass clazz, jmethodID methodID)
369 if (clazz == methodID->class)
372 /* class_resolvemethod -> classfindmethod? (JOWENN) */
373 return class_resolvemethod(clazz, methodID->name, methodID->descriptor);
377 static jobject callObjectMethod(jobject obj, jmethodID methodID, va_list args)
386 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
390 argcount = methodID->parseddesc->paramcount;
392 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
393 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
394 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
398 if (obj && !builtin_instanceof(obj, methodID->class)) {
399 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
406 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
407 log_text("Too many arguments. CallObjectMethod does not support that");
412 blk = MNEW(jni_callblock, /*4 */argcount+2);
414 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_ADR);
415 /* printf("parameter: obj: %p",blk[0].item); */
416 STATS(jnicallXmethodnvokation();)
417 ret = asm_calljavafunction2(methodID,
419 (argcount + 1) * sizeof(jni_callblock),
421 MFREE(blk, jni_callblock, argcount + 1);
422 /* printf("(CallObjectMethodV)-->%p\n",ret); */
429 core function for integer class methods (bool, byte, short, integer)
430 This is basically needed for i386
432 static jint callIntegerMethod(jobject obj, jmethodID methodID, int retType, va_list args)
438 STATS(jniinvokation();)
441 log_text("JNI-Call: CallObjectMethodV");
442 utf_display(methodID->name);
443 utf_display(methodID->descriptor);
444 printf("\nParmaeter count: %d\n",argcount);
445 utf_display(obj->vftbl->class->name);
449 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
453 argcount = methodID->parseddesc->paramcount;
455 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
456 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
457 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
461 if (obj && !builtin_instanceof(obj, methodID->class)) {
462 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
468 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
469 log_text("Too many arguments. CallIntegerMethod does not support that");
474 blk = MNEW(jni_callblock, /*4 */ argcount+2);
476 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
478 /* printf("parameter: obj: %p",blk[0].item); */
479 STATS(jnicallXmethodnvokation();)
480 ret = asm_calljavafunction2int(methodID,
482 (argcount + 1) * sizeof(jni_callblock),
485 MFREE(blk, jni_callblock, argcount + 1);
486 /* printf("(CallObjectMethodV)-->%p\n",ret); */
492 /*core function for long class functions*/
493 static jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
499 STATS(jniinvokation();)
502 log_text("JNI-Call: CallObjectMethodV");
503 utf_display(methodID->name);
504 utf_display(methodID->descriptor);
505 printf("\nParmaeter count: %d\n",argcount);
506 utf_display(obj->vftbl->class->name);
510 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
514 argcount = methodID->parseddesc->paramcount;
516 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
517 ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
518 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
522 if (obj && !builtin_instanceof(obj,methodID->class)) {
523 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
529 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
530 log_text("Too many arguments. CallObjectMethod does not support that");
535 blk = MNEW(jni_callblock,/* 4 */argcount+2);
537 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_LNG);
539 /* printf("parameter: obj: %p",blk[0].item); */
540 STATS(jnicallXmethodnvokation();)
541 ret = asm_calljavafunction2long(methodID,
543 (argcount + 1) * sizeof(jni_callblock),
546 MFREE(blk, jni_callblock, argcount + 1);
547 /* printf("(CallObjectMethodV)-->%p\n",ret); */
553 /*core function for float class methods (float,double)*/
554 static jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,int retType)
556 int argcount = methodID->parseddesc->paramcount;
560 STATS(jniinvokation();)
563 log_text("JNI-Call: CallObjectMethodV");
564 utf_display(methodID->name);
565 utf_display(methodID->descriptor);
566 printf("\nParmaeter count: %d\n",argcount);
567 utf_display(obj->vftbl->class->name);
573 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
574 log_text("Too many arguments. CallObjectMethod does not support that");
579 blk = MNEW(jni_callblock, /*4 */ argcount+2);
581 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
583 /* printf("parameter: obj: %p",blk[0].item); */
584 STATS(jnicallXmethodnvokation();)
585 ret = asm_calljavafunction2double(methodID,
587 (argcount + 1) * sizeof(jni_callblock),
590 MFREE(blk, jni_callblock, argcount + 1);
591 /* printf("(CallObjectMethodV)-->%p\n",ret); */
597 /*************************** function: jclass_findfield ****************************
599 searches for field with specified name and type in a 'classinfo'-structur
600 if no such field is found NULL is returned
602 ************************************************************************************/
604 static fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
607 STATS(jniinvokation();)
609 /* printf(" FieldCount: %d\n",c->fieldscount);
610 utf_display(c->name); */
611 for (i = 0; i < c->fieldscount; i++) {
612 /* utf_display(c->fields[i].name);
614 utf_display(c->fields[i].descriptor);
616 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
617 return &(c->fields[i]);
620 if (c->super.cls) return jclass_findfield(c->super.cls,name,desc);
626 /* GetVersion ******************************************************************
628 Returns the major version number in the higher 16 bits and the
629 minor version number in the lower 16 bits.
631 *******************************************************************************/
633 jint GetVersion(JNIEnv *env)
635 STATS(jniinvokation();)
637 /* just say we support JNI 1.4 */
639 return JNI_VERSION_1_4;
643 /* Class Operations ***********************************************************/
645 /* DefineClass *****************************************************************
647 Loads a class from a buffer of raw class data. The buffer
648 containing the raw class data is not referenced by the VM after the
649 DefineClass call returns, and it may be discarded if desired.
651 *******************************************************************************/
653 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
654 const jbyte *buf, jsize bufLen)
656 java_lang_ClassLoader *cl;
661 STATS(jniinvokation();)
663 cl = (java_lang_ClassLoader *) loader;
664 s = javastring_new_char(name);
665 ba = (java_bytearray *) buf;
667 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
674 /* FindClass *******************************************************************
676 This function loads a locally-defined class. It searches the
677 directories and zip files specified by the CLASSPATH environment
678 variable for the class with the specified name.
680 *******************************************************************************/
682 jclass FindClass(JNIEnv *env, const char *name)
686 java_objectheader *cl;
688 STATS(jniinvokation();)
690 u = utf_new_char_classname((char *) name);
692 /* check stacktrace for classloader, if one found use it, otherwise use */
693 /* the system classloader */
695 #if defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__)
696 cl = cacao_currentClassLoader();
701 if (!(c = load_class_from_classloader(u, cl)))
707 use_class_as_object(c);
713 /* FromReflectedMethod *********************************************************
715 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
716 object to a method ID.
718 *******************************************************************************/
720 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
726 STATS(jniinvokation();)
731 if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
732 java_lang_reflect_Method *rm;
734 rm = (java_lang_reflect_Method *) method;
735 c = (classinfo *) (rm->declaringClass);
738 } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
739 java_lang_reflect_Constructor *rc;
741 rc = (java_lang_reflect_Constructor *) method;
742 c = (classinfo *) (rc->clazz);
748 if ((slot < 0) || (slot >= c->methodscount)) {
749 /* this usually means a severe internal cacao error or somebody
750 tempered around with the reflected method */
751 log_text("error illegal slot for method in class(FromReflectedMethod)");
755 mi = &(c->methods[slot]);
761 /* GetSuperclass ***************************************************************
763 If clazz represents any class other than the class Object, then
764 this function returns the object that represents the superclass of
765 the class specified by clazz.
767 *******************************************************************************/
769 jclass GetSuperclass(JNIEnv *env, jclass sub)
772 STATS(jniinvokation();)
774 c = ((classinfo *) sub)->super.cls;
779 use_class_as_object(c);
785 /* IsAssignableFrom ************************************************************
787 Determines whether an object of sub can be safely cast to sup.
789 *******************************************************************************/
791 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
793 STATS(jniinvokation();)
794 return Java_java_lang_VMClass_isAssignableFrom(env,
796 (java_lang_Class *) sup,
797 (java_lang_Class *) sub);
801 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
803 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
805 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!!!");
806 STATS(jniinvokation();)
811 /* Throw ***********************************************************************
813 Causes a java.lang.Throwable object to be thrown.
815 *******************************************************************************/
817 jint Throw(JNIEnv *env, jthrowable obj)
819 *exceptionptr = (java_objectheader *) obj;
820 STATS(jniinvokation();)
826 /* ThrowNew ********************************************************************
828 Constructs an exception object from the specified class with the
829 message specified by message and causes that exception to be
832 *******************************************************************************/
834 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
836 java_lang_Throwable *o;
838 STATS(jniinvokation();)
840 s = (java_lang_String *) javastring_new_char(msg);
842 /* instantiate exception object */
844 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
850 *exceptionptr = (java_objectheader *) o;
856 /* ExceptionOccurred ***********************************************************
858 Determines if an exception is being thrown. The exception stays
859 being thrown until either the native code calls ExceptionClear(),
860 or the Java code handles the exception.
862 *******************************************************************************/
864 jthrowable ExceptionOccurred(JNIEnv *env)
866 STATS(jniinvokation();)
867 return (jthrowable) *exceptionptr;
871 /* ExceptionDescribe ***********************************************************
873 Prints an exception and a backtrace of the stack to a system
874 error-reporting channel, such as stderr. This is a convenience
875 routine provided for debugging.
877 *******************************************************************************/
879 void ExceptionDescribe(JNIEnv *env)
881 java_objectheader *e;
883 STATS(jniinvokation();)
888 /* clear exception, because we are calling jit code again */
890 *exceptionptr = NULL;
892 /* get printStackTrace method from exception class */
894 m = class_resolveclassmethod(e->vftbl->class,
901 /* XXX what should we do? */
904 /* print the stacktrace */
906 asm_calljavafunction(m, e, NULL, NULL, NULL);
911 /* ExceptionClear **************************************************************
913 Clears any exception that is currently being thrown. If no
914 exception is currently being thrown, this routine has no effect.
916 *******************************************************************************/
918 void ExceptionClear(JNIEnv *env)
920 STATS(jniinvokation();)
921 *exceptionptr = NULL;
925 /* FatalError ******************************************************************
927 Raises a fatal error and does not expect the VM to recover. This
928 function does not return.
930 *******************************************************************************/
932 void FatalError(JNIEnv *env, const char *msg)
934 STATS(jniinvokation();)
935 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
939 /******************* creates a new local reference frame **************************/
941 jint PushLocalFrame(JNIEnv* env, jint capacity)
943 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
944 STATS(jniinvokation();)
949 /**************** Pops off the current local reference frame **********************/
951 jobject PopLocalFrame(JNIEnv* env, jobject result)
953 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
954 STATS(jniinvokation();)
960 /* DeleteLocalRef **************************************************************
962 Deletes the local reference pointed to by localRef.
964 *******************************************************************************/
966 void DeleteLocalRef(JNIEnv *env, jobject localRef)
968 log_text("JNI-Call: DeleteLocalRef: IMPLEMENT ME!");
969 STATS(jniinvokation();)
974 /* IsSameObject ****************************************************************
976 Tests whether two references refer to the same Java object.
978 *******************************************************************************/
980 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
982 STATS(jniinvokation();)
983 return (ref1 == ref2);
987 /* NewLocalRef *****************************************************************
989 Creates a new local reference that refers to the same object as ref.
991 *******************************************************************************/
993 jobject NewLocalRef(JNIEnv *env, jobject ref)
995 log_text("JNI-Call: NewLocalRef: IMPLEMENT ME!");
996 STATS(jniinvokation();)
1000 /***********************************************************************************
1002 Ensures that at least a given number of local references can
1003 be created in the current thread
1005 **********************************************************************************/
1007 jint EnsureLocalCapacity (JNIEnv* env, jint capacity)
1009 STATS(jniinvokation();)
1010 return 0; /* return 0 on success */
1014 /* AllocObject *****************************************************************
1016 Allocates a new Java object without invoking any of the
1017 constructors for the object. Returns a reference to the object.
1019 *******************************************************************************/
1021 jobject AllocObject(JNIEnv *env, jclass clazz)
1023 java_objectheader *o;
1024 STATS(jniinvokation();)
1026 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1028 new_exception_utfmessage(string_java_lang_InstantiationException,
1033 o = builtin_new(clazz);
1039 /* NewObject *******************************************************************
1041 Constructs a new Java object. The method ID indicates which
1042 constructor method to invoke. This ID must be obtained by calling
1043 GetMethodID() with <init> as the method name and void (V) as the
1046 *******************************************************************************/
1048 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1050 java_objectheader *o;
1052 int argcount=methodID->parseddesc->paramcount;
1055 STATS(jniinvokation();)
1059 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
1060 log_text("Too many arguments. NewObject does not support that");
1067 o = builtin_new(clazz);
1072 va_start(vaargs, methodID);
1073 for (i = 0; i < argcount; i++) {
1074 args[i] = va_arg(vaargs, void*);
1078 /* call constructor */
1080 asm_calljavafunction(methodID, o, args[0], args[1], args[2]);
1086 /***********************************************************************************
1088 Constructs a new Java object
1089 arguments that are to be passed to the constructor are placed in va_list args
1091 ***********************************************************************************/
1093 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1095 log_text("JNI-Call: NewObjectV");
1096 STATS(jniinvokation();)
1102 /***********************************************************************************
1104 Constructs a new Java object
1105 arguments that are to be passed to the constructor are placed in
1106 args array of jvalues
1108 ***********************************************************************************/
1110 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1112 log_text("JNI-Call: NewObjectA");
1113 STATS(jniinvokation();)
1119 /* GetObjectClass **************************************************************
1121 Returns the class of an object.
1123 *******************************************************************************/
1125 jclass GetObjectClass(JNIEnv *env, jobject obj)
1128 STATS(jniinvokation();)
1130 if (!obj || !obj->vftbl)
1133 c = obj->vftbl->class;
1134 use_class_as_object(c);
1139 /* IsInstanceOf ****************************************************************
1141 Tests whether an object is an instance of a class.
1143 *******************************************************************************/
1145 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1147 STATS(jniinvokation();)
1149 return Java_java_lang_VMClass_isInstance(env,
1151 (java_lang_Class *) clazz,
1152 (java_lang_Object *) obj);
1156 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1158 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1160 java_lang_reflect_Field *f;
1162 jfieldID fid; /* the JNI-fieldid of the wrapping object */
1163 STATS(jniinvokation();)
1164 /*log_text("JNI-Call: FromReflectedField");*/
1166 f=(java_lang_reflect_Field *)field;
1168 c=(classinfo*)(f->declaringClass);
1169 if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1170 /*this usually means a severe internal cacao error or somebody
1171 tempered around with the reflected method*/
1172 log_text("error illegal slot for field in class(FromReflectedField)");
1175 fid=&(c->fields[f->slot]);
1180 /**********************************************************************************
1182 converts a method ID to a java.lang.reflect.Method or
1183 java.lang.reflect.Constructor object
1185 **********************************************************************************/
1187 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1189 log_text("JNI-Call: ToReflectedMethod");
1190 STATS(jniinvokation();)
1196 /* GetMethodID *****************************************************************
1198 returns the method ID for an instance method
1200 *******************************************************************************/
1202 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1205 STATS(jniinvokation();)
1207 m = class_resolvemethod(clazz,
1208 utf_new_char((char *) name),
1209 utf_new_char((char *) sig));
1211 if (!m || (m->flags & ACC_STATIC)) {
1213 new_exception_message(string_java_lang_NoSuchMethodError, name);
1222 /******************** JNI-functions for calling instance methods ******************/
1224 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1228 STATS(jniinvokation();)
1230 /* log_text("JNI-Call: CallObjectMethod");*/
1232 va_start(vaargs, methodID);
1233 ret = callObjectMethod(obj, methodID, vaargs);
1240 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1242 STATS(jniinvokation();)
1243 return callObjectMethod(obj,methodID,args);
1247 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1249 log_text("JNI-Call: CallObjectMethodA");
1250 STATS(jniinvokation();)
1258 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1262 STATS(jniinvokation();)
1264 /* log_text("JNI-Call: CallBooleanMethod");*/
1266 va_start(vaargs,methodID);
1267 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1273 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1275 STATS(jniinvokation();)
1277 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
1281 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1283 STATS(jniinvokation();)
1284 log_text("JNI-Call: CallBooleanMethodA");
1289 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1293 STATS(jniinvokation();)
1295 /* log_text("JNI-Call: CallVyteMethod");*/
1297 va_start(vaargs,methodID);
1298 ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
1304 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1306 /* log_text("JNI-Call: CallByteMethodV");*/
1307 STATS(jniinvokation();)
1309 return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
1313 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1315 log_text("JNI-Call: CallByteMethodA");
1316 STATS(jniinvokation();)
1322 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1326 STATS(jniinvokation();)
1328 /* log_text("JNI-Call: CallCharMethod");*/
1330 va_start(vaargs,methodID);
1331 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
1338 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1340 STATS(jniinvokation();)
1342 /* log_text("JNI-Call: CallCharMethodV");*/
1343 return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
1347 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1349 STATS(jniinvokation();)
1351 log_text("JNI-Call: CallCharMethodA");
1357 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1361 STATS(jniinvokation();)
1363 /* log_text("JNI-Call: CallShortMethod");*/
1365 va_start(vaargs, methodID);
1366 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
1373 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1375 STATS(jniinvokation();)
1376 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
1380 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1382 STATS(jniinvokation();)
1383 log_text("JNI-Call: CallShortMethodA");
1390 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1394 STATS(jniinvokation();)
1396 va_start(vaargs,methodID);
1397 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
1404 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1406 STATS(jniinvokation();)
1407 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
1411 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1413 STATS(jniinvokation();)
1414 log_text("JNI-Call: CallIntMethodA");
1421 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1425 STATS(jniinvokation();)
1427 va_start(vaargs,methodID);
1428 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1435 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1437 STATS(jniinvokation();)
1438 return callLongMethod(obj,get_virtual(obj, methodID),args);
1442 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1444 STATS(jniinvokation();)
1445 log_text("JNI-Call: CallLongMethodA");
1452 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1457 STATS(jniinvokation();)
1458 /* log_text("JNI-Call: CallFloatMethod");*/
1460 va_start(vaargs,methodID);
1461 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
1468 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1470 STATS(jniinvokation();)
1471 log_text("JNI-Call: CallFloatMethodV");
1472 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
1476 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1478 STATS(jniinvokation();)
1479 log_text("JNI-Call: CallFloatMethodA");
1486 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1490 STATS(jniinvokation();)
1492 /* log_text("JNI-Call: CallDoubleMethod");*/
1494 va_start(vaargs,methodID);
1495 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
1502 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1504 STATS(jniinvokation();)
1505 log_text("JNI-Call: CallDoubleMethodV");
1506 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
1510 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1512 STATS(jniinvokation();)
1513 log_text("JNI-Call: CallDoubleMethodA");
1519 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1522 STATS(jniinvokation();)
1524 va_start(vaargs,methodID);
1525 (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
1530 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1532 log_text("JNI-Call: CallVoidMethodV");
1533 STATS(jniinvokation();)
1534 (void)callIntegerMethod(obj,get_virtual(obj,methodID),TYPE_VOID,args);
1538 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1540 STATS(jniinvokation();)
1541 log_text("JNI-Call: CallVoidMethodA");
1546 jobject CallNonvirtualObjectMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1548 STATS(jniinvokation();)
1549 log_text("JNI-Call: CallNonvirtualObjectMethod");
1555 jobject CallNonvirtualObjectMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1557 STATS(jniinvokation();)
1558 log_text("JNI-Call: CallNonvirtualObjectMethodV");
1564 jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1566 STATS(jniinvokation();)
1567 log_text("JNI-Call: CallNonvirtualObjectMethodA");
1574 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1578 STATS(jniinvokation();)
1580 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1582 va_start(vaargs,methodID);
1583 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1590 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1592 STATS(jniinvokation();)
1593 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1594 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
1598 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1600 STATS(jniinvokation();)
1601 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1608 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1613 STATS(jniinvokation();)
1614 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1616 va_start(vaargs,methodID);
1617 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
1623 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1625 STATS(jniinvokation();)
1626 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1627 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
1632 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1634 STATS(jniinvokation();)
1635 log_text("JNI-Call: CallNonvirtualByteMethodA");
1642 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1647 STATS(jniinvokation();)
1648 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1650 va_start(vaargs,methodID);
1651 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
1657 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1659 STATS(jniinvokation();)
1660 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1661 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
1665 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1667 STATS(jniinvokation();)
1668 log_text("JNI-Call: CallNonvirtualCharMethodA");
1675 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1679 STATS(jniinvokation();)
1681 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1683 va_start(vaargs,methodID);
1684 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
1690 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1692 STATS(jniinvokation();)
1693 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1694 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
1698 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1700 STATS(jniinvokation();)
1701 log_text("JNI-Call: CallNonvirtualShortMethodA");
1708 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1713 STATS(jniinvokation();)
1715 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1717 va_start(vaargs,methodID);
1718 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
1724 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1726 STATS(jniinvokation();)
1727 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1728 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
1732 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1734 STATS(jniinvokation();)
1735 log_text("JNI-Call: CallNonvirtualIntMethodA");
1742 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1744 STATS(jniinvokation();)
1745 log_text("JNI-Call: CallNonvirtualLongMethod");
1751 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1753 STATS(jniinvokation();)
1754 log_text("JNI-Call: CallNonvirtualLongMethodV");
1760 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1762 STATS(jniinvokation();)
1763 log_text("JNI-Call: CallNonvirtualLongMethodA");
1770 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1774 STATS(jniinvokation();)
1776 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1779 va_start(vaargs,methodID);
1780 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
1787 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1789 STATS(jniinvokation();)
1790 log_text("JNI-Call: CallNonvirtualFloatMethodV");
1791 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
1795 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1797 STATS(jniinvokation();)
1798 log_text("JNI-Call: CallNonvirtualFloatMethodA");
1805 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1809 STATS(jniinvokation();)
1810 log_text("JNI-Call: CallNonvirtualDoubleMethod");
1812 va_start(vaargs,methodID);
1813 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
1820 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1822 STATS(jniinvokation();)
1823 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
1824 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
1828 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1830 STATS(jniinvokation();)
1831 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
1838 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1841 STATS(jniinvokation();)
1843 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
1845 va_start(vaargs,methodID);
1846 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
1852 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1854 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
1855 STATS(jniinvokation();)
1857 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
1862 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1864 STATS(jniinvokation();)
1865 log_text("JNI-Call: CallNonvirtualVoidMethodA");
1868 /************************* JNI-functions for accessing fields ************************/
1870 jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
1874 STATS(jniinvokation();)
1876 /* log_text("========================= searching for:");
1879 f = jclass_findfield(clazz,
1880 utf_new_char ((char*) name),
1881 utf_new_char ((char*) sig)
1885 /*utf_display(clazz->name);
1888 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
1893 /*************************** retrieve fieldid, abort on error ************************/
1895 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
1897 jfieldID id = GetFieldID(env, clazz, name, sig);
1898 STATS(jniinvokation();)
1902 utf_display(clazz->name);
1903 log_text("\nfield:");
1908 log_text("setfield_critical failed");
1914 jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
1917 jobject dbg,dretval,*dpretval;
1918 long int dli1, dli2, dli3;
1920 printf("GetObjectField(1): thread: %s obj: %p name: %s desc: %s \n",GetStringUTFChars(env,
1921 ((threadobject *) THREADOBJECT)->o
1923 ,obj,((fieldinfo*)fieldID)->name->text,(fieldID->descriptor)->text);
1925 dbg = getField(obj,jobject,fieldID);
1926 dli1 = (long int) obj;
1927 dli2 = (long int) fieldID->offset;
1929 dpretval = (jobject*) dli3;
1930 dretval = *dpretval;
1935 tmp = FindClass(env, "java/lang/Object");
1936 mid = GetMethodID(env,tmp,"toString","()Ljava/lang/String;");
1937 jstr = CallObjectMethod(env,dbg,mid);*/
1939 /* printf("GetObjectField(2): retval %p (obj: %#lx + offset: %#lx = %#lx (jobject*) %p (jobject) %p\n"
1940 ,dbg, dli1, dli2, dli3,dpretval, dretval);*/
1944 STATS(jniinvokation();)
1946 return getField(obj,jobject,fieldID);
1949 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
1951 STATS(jniinvokation();)
1952 return getField(obj,jboolean,fieldID);
1956 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
1958 STATS(jniinvokation();)
1959 return getField(obj,jbyte,fieldID);
1963 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
1965 STATS(jniinvokation();)
1966 return getField(obj,jchar,fieldID);
1970 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
1972 STATS(jniinvokation();)
1973 return getField(obj,jshort,fieldID);
1977 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
1979 STATS(jniinvokation();)
1980 return getField(obj,jint,fieldID);
1984 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
1986 STATS(jniinvokation();)
1987 return getField(obj,jlong,fieldID);
1991 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
1993 STATS(jniinvokation();)
1994 return getField(obj,jfloat,fieldID);
1998 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
2000 STATS(jniinvokation();)
2001 return getField(obj,jdouble,fieldID);
2004 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
2006 STATS(jniinvokation();)
2007 setField(obj,jobject,fieldID,val);
2011 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
2013 STATS(jniinvokation();)
2014 setField(obj,jboolean,fieldID,val);
2018 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
2020 STATS(jniinvokation();)
2021 setField(obj,jbyte,fieldID,val);
2025 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
2027 STATS(jniinvokation();)
2028 setField(obj,jchar,fieldID,val);
2032 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
2034 STATS(jniinvokation();)
2035 setField(obj,jshort,fieldID,val);
2039 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
2041 STATS(jniinvokation();)
2042 setField(obj,jint,fieldID,val);
2046 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
2048 STATS(jniinvokation();)
2049 setField(obj,jlong,fieldID,val);
2053 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
2055 STATS(jniinvokation();)
2056 setField(obj,jfloat,fieldID,val);
2060 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
2062 STATS(jniinvokation();)
2063 setField(obj,jdouble,fieldID,val);
2067 /**************** JNI-functions for calling static methods **********************/
2069 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2072 STATS(jniinvokation();)
2074 m = class_resolvemethod(clazz,
2075 utf_new_char((char *) name),
2076 utf_new_char((char *) sig));
2078 if (!m || !(m->flags & ACC_STATIC)) {
2080 new_exception_message(string_java_lang_NoSuchMethodError, name);
2089 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2093 STATS(jniinvokation();)
2095 /* log_text("JNI-Call: CallStaticObjectMethod");*/
2097 va_start(vaargs, methodID);
2098 ret = callObjectMethod(0, methodID, vaargs);
2105 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2107 STATS(jniinvokation();)
2108 /* log_text("JNI-Call: CallStaticObjectMethodV"); */
2110 return callObjectMethod(0,methodID,args);
2114 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2116 STATS(jniinvokation();)
2117 log_text("JNI-Call: CallStaticObjectMethodA");
2123 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2127 STATS(jniinvokation();)
2129 va_start(vaargs, methodID);
2130 ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
2137 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2139 STATS(jniinvokation();)
2140 return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
2144 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2146 STATS(jniinvokation();)
2147 log_text("JNI-Call: CallStaticBooleanMethodA");
2153 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2157 STATS(jniinvokation();)
2159 /* log_text("JNI-Call: CallStaticByteMethod");*/
2161 va_start(vaargs, methodID);
2162 ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
2169 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2171 STATS(jniinvokation();)
2172 return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
2176 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2178 STATS(jniinvokation();)
2179 log_text("JNI-Call: CallStaticByteMethodA");
2185 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2189 STATS(jniinvokation();)
2191 /* log_text("JNI-Call: CallStaticByteMethod");*/
2193 va_start(vaargs, methodID);
2194 ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
2201 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2203 STATS(jniinvokation();)
2204 return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
2208 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2210 STATS(jniinvokation();)
2211 log_text("JNI-Call: CallStaticCharMethodA");
2218 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2222 STATS(jniinvokation();)
2224 /* log_text("JNI-Call: CallStaticByteMethod");*/
2226 va_start(vaargs, methodID);
2227 ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
2234 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2236 STATS(jniinvokation();)
2237 /*log_text("JNI-Call: CallStaticShortMethodV");*/
2238 return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
2242 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2244 STATS(jniinvokation();)
2245 log_text("JNI-Call: CallStaticShortMethodA");
2252 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2256 STATS(jniinvokation();)
2258 /* log_text("JNI-Call: CallStaticIntMethod");*/
2260 va_start(vaargs, methodID);
2261 ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
2268 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2270 STATS(jniinvokation();)
2271 log_text("JNI-Call: CallStaticIntMethodV");
2273 return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
2277 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2279 STATS(jniinvokation();)
2280 log_text("JNI-Call: CallStaticIntMethodA");
2287 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2291 STATS(jniinvokation();)
2293 /* log_text("JNI-Call: CallStaticLongMethod");*/
2295 va_start(vaargs, methodID);
2296 ret = callLongMethod(0, methodID, vaargs);
2303 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2305 STATS(jniinvokation();)
2306 log_text("JNI-Call: CallStaticLongMethodV");
2308 return callLongMethod(0,methodID,args);
2312 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2314 STATS(jniinvokation();)
2315 log_text("JNI-Call: CallStaticLongMethodA");
2322 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2326 STATS(jniinvokation();)
2328 /* log_text("JNI-Call: CallStaticLongMethod");*/
2330 va_start(vaargs, methodID);
2331 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
2338 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2340 STATS(jniinvokation();)
2342 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
2347 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2349 STATS(jniinvokation();)
2350 log_text("JNI-Call: CallStaticFloatMethodA");
2357 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2361 STATS(jniinvokation();)
2363 /* log_text("JNI-Call: CallStaticDoubleMethod");*/
2365 va_start(vaargs,methodID);
2366 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
2373 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2375 STATS(jniinvokation();)
2376 log_text("JNI-Call: CallStaticDoubleMethodV");
2378 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
2382 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2384 STATS(jniinvokation();)
2385 log_text("JNI-Call: CallStaticDoubleMethodA");
2391 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2394 STATS(jniinvokation();)
2396 va_start(vaargs, methodID);
2397 (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
2402 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2404 log_text("JNI-Call: CallStaticVoidMethodV");
2405 STATS(jniinvokation();)
2406 (void)callIntegerMethod(0, methodID, TYPE_VOID, args);
2410 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2412 STATS(jniinvokation();)
2413 log_text("JNI-Call: CallStaticVoidMethodA");
2417 /* Accessing Static Fields ****************************************************/
2419 /* GetStaticFieldID ************************************************************
2421 Returns the field ID for a static field of a class. The field is
2422 specified by its name and signature. The GetStatic<type>Field and
2423 SetStatic<type>Field families of accessor functions use field IDs
2424 to retrieve static fields.
2426 *******************************************************************************/
2428 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2431 STATS(jniinvokation();)
2433 f = jclass_findfield(clazz,
2434 utf_new_char((char *) name),
2435 utf_new_char((char *) sig));
2438 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2444 /* GetStatic<type>Field ********************************************************
2446 This family of accessor routines returns the value of a static
2449 *******************************************************************************/
2451 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2453 STATS(jniinvokation();)
2454 JWCLINITDEBUG(printf("GetStaticObjectField: calling initialize_class %s\n",clazz->name->text);)
2455 if (!initialize_class(clazz))
2458 return fieldID->value.a;
2462 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2464 STATS(jniinvokation();)
2465 JWCLINITDEBUG(printf("GetStaticBooleanField: calling initialize_class %s\n",clazz->name->text);)
2467 if (!initialize_class(clazz))
2470 return fieldID->value.i;
2474 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2476 STATS(jniinvokation();)
2477 JWCLINITDEBUG(printf("GetStaticByteField: calling initialize_class %s\n",clazz->name->text);)
2479 if (!initialize_class(clazz))
2482 return fieldID->value.i;
2486 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2488 STATS(jniinvokation();)
2489 JWCLINITDEBUG(printf("GetStaticCharField: calling initialize_class %s\n",clazz->name->text);)
2491 if (!initialize_class(clazz))
2494 return fieldID->value.i;
2498 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2500 STATS(jniinvokation();)
2501 JWCLINITDEBUG(printf("GetStaticShorttField: calling initialize_class %s\n",clazz->name->text);)
2502 if (!initialize_class(clazz))
2505 return fieldID->value.i;
2509 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2511 STATS(jniinvokation();)
2512 JWCLINITDEBUG(printf("GetStaticIntField: calling initialize_class %s\n",clazz->name->text);)
2513 if (!initialize_class(clazz))
2516 return fieldID->value.i;
2520 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2522 STATS(jniinvokation();)
2523 JWCLINITDEBUG(printf("GetStaticLongField: calling initialize_class %s\n",clazz->name->text);)
2524 if (!initialize_class(clazz))
2527 return fieldID->value.l;
2531 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2533 STATS(jniinvokation();)
2534 JWCLINITDEBUG(printf("GetStaticFloatField: calling initialize_class %s\n",clazz->name->text);)
2535 if (!initialize_class(clazz))
2538 return fieldID->value.f;
2542 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2544 STATS(jniinvokation();)
2545 JWCLINITDEBUG(printf("GetStaticDoubleField: calling initialize_class %s\n",clazz->name->text);)
2546 if (!initialize_class(clazz))
2549 return fieldID->value.d;
2553 /* SetStatic<type>Field *******************************************************
2555 This family of accessor routines sets the value of a static field
2558 *******************************************************************************/
2560 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2562 STATS(jniinvokation();)
2563 JWCLINITDEBUG(printf("SetStaticObjectField: calling initialize_class %s\n",clazz->name->text);)
2564 if (!initialize_class(clazz))
2567 fieldID->value.a = value;
2571 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2573 STATS(jniinvokation();)
2574 JWCLINITDEBUG(printf("SetStaticBooleanField: calling initialize_class %s\n",clazz->name->text);)
2575 if (!initialize_class(clazz))
2578 fieldID->value.i = value;
2582 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2584 STATS(jniinvokation();)
2585 JWCLINITDEBUG(printf("SetStaticByteField: calling initialize_class %s\n",clazz->name->text);)
2586 if (!initialize_class(clazz))
2589 fieldID->value.i = value;
2593 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2595 STATS(jniinvokation();)
2596 JWCLINITDEBUG(printf("SetStaticCharField: calling initialize_class %s\n",clazz->name->text);)
2597 if (!initialize_class(clazz))
2600 fieldID->value.i = value;
2604 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2606 STATS(jniinvokation();)
2607 JWCLINITDEBUG(printf("SetStaticShortField: calling initialize_class %s\n",clazz->name->text);)
2608 if (!initialize_class(clazz))
2611 fieldID->value.i = value;
2615 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2617 STATS(jniinvokation();)
2618 JWCLINITDEBUG(printf("SetStaticIntField: calling initialize_class %s\n",clazz->name->text);)
2619 if (!initialize_class(clazz))
2622 fieldID->value.i = value;
2626 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2628 STATS(jniinvokation();)
2629 JWCLINITDEBUG(printf("SetStaticLongField: calling initialize_class %s\n",clazz->name->text);)
2630 if (!initialize_class(clazz))
2633 fieldID->value.l = value;
2637 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2639 STATS(jniinvokation();)
2640 JWCLINITDEBUG(printf("SetStaticFloatField: calling initialize_class %s\n",clazz->name->text);)
2641 if (!initialize_class(clazz))
2644 fieldID->value.f = value;
2648 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2650 STATS(jniinvokation();)
2651 JWCLINITDEBUG(printf("SetStaticDoubleField: calling initialize_class %s\n",clazz->name->text);)
2652 if (!initialize_class(clazz))
2655 fieldID->value.d = value;
2659 /* NewString *******************************************************************
2661 Create new java.lang.String object from an array of Unicode
2664 *******************************************************************************/
2666 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
2668 java_lang_String *s;
2671 STATS(jniinvokation();)
2673 s = (java_lang_String *) builtin_new(class_java_lang_String);
2674 a = builtin_newarray_char(len);
2676 /* javastring or characterarray could not be created */
2681 for (i = 0; i < len; i++)
2682 a->data[i] = buf[i];
2692 static jchar emptyStringJ[]={0,0};
2694 /******************* returns the length of a Java string ***************************/
2696 jsize GetStringLength (JNIEnv *env, jstring str)
2698 return ((java_lang_String*) str)->count;
2702 /******************** convertes javastring to u2-array ****************************/
2704 u2 *javastring_tou2 (jstring so)
2706 java_lang_String *s = (java_lang_String*) so;
2710 STATS(jniinvokation();)
2712 if (!s) return NULL;
2715 if (!a) return NULL;
2717 /* allocate memory */
2718 stringbuffer = MNEW( u2 , s->count + 1 );
2721 for (i=0; i<s->count; i++) stringbuffer[i] = a->data[s->offset+i];
2723 /* terminate string */
2724 stringbuffer[i] = '\0';
2726 return stringbuffer;
2729 /********* returns a pointer to an array of Unicode characters of the string *******/
2731 const jchar *GetStringChars (JNIEnv *env, jstring str, jboolean *isCopy)
2733 jchar *jc=javastring_tou2(str);
2734 STATS(jniinvokation();)
2737 if (isCopy) *isCopy=JNI_TRUE;
2740 if (isCopy) *isCopy=JNI_TRUE;
2741 return emptyStringJ;
2744 /**************** native code no longer needs access to chars **********************/
2746 void ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars)
2748 STATS(jniinvokation();)
2749 if (chars==emptyStringJ) return;
2750 MFREE(((jchar*) chars),jchar,((java_lang_String*) str)->count+1);
2754 /* NewStringUTF ****************************************************************
2756 Constructs a new java.lang.String object from an array of UTF-8 characters.
2758 *******************************************************************************/
2760 jstring NewStringUTF(JNIEnv *env, const char *bytes)
2762 STATS(jniinvokation();)
2763 return (jstring) javastring_new(utf_new_char(bytes));
2767 /****************** returns the utf8 length in bytes of a string *******************/
2769 jsize GetStringUTFLength (JNIEnv *env, jstring string)
2771 java_lang_String *s = (java_lang_String*) string;
2772 STATS(jniinvokation();)
2774 return (jsize) u2_utflength(s->value->data, s->count);
2778 /* GetStringUTFChars ***********************************************************
2780 Returns a pointer to an array of UTF-8 characters of the
2781 string. This array is valid until it is released by
2782 ReleaseStringUTFChars().
2784 *******************************************************************************/
2786 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
2789 STATS(jniinvokation();)
2797 u = javastring_toutf((java_lang_String *) string, false);
2806 /* ReleaseStringUTFChars *******************************************************
2808 Informs the VM that the native code no longer needs access to
2809 utf. The utf argument is a pointer derived from string using
2810 GetStringUTFChars().
2812 *******************************************************************************/
2814 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2816 STATS(jniinvokation();)
2818 /* XXX we don't release utf chars right now, perhaps that should be done
2819 later. Since there is always one reference the garbage collector will
2824 /* Array Operations ***********************************************************/
2826 /* GetArrayLength **************************************************************
2828 Returns the number of elements in the array.
2830 *******************************************************************************/
2832 jsize GetArrayLength(JNIEnv *env, jarray array)
2834 STATS(jniinvokation();)
2840 /* NewObjectArray **************************************************************
2842 Constructs a new array holding objects in class elementClass. All
2843 elements are initially set to initialElement.
2845 *******************************************************************************/
2847 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
2849 java_objectarray *oa;
2851 STATS(jniinvokation();)
2854 *exceptionptr = new_negativearraysizeexception();
2858 oa = builtin_anewarray(length, elementClass);
2863 /* set all elements to initialElement */
2865 for (i = 0; i < length; i++)
2866 oa->data[i] = initialElement;
2872 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
2875 STATS(jniinvokation();)
2877 if (index < array->header.size)
2878 j = array->data[index];
2880 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2886 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
2888 STATS(jniinvokation();)
2889 if (index >= array->header.size)
2890 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2893 /* check if the class of value is a subclass of the element class of the array */
2894 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
2895 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
2898 array->data[index] = val;
2904 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
2906 java_booleanarray *j;
2907 STATS(jniinvokation();)
2910 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2914 j = builtin_newarray_boolean(len);
2920 jbyteArray NewByteArray(JNIEnv *env, jsize len)
2923 STATS(jniinvokation();)
2926 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2930 j = builtin_newarray_byte(len);
2936 jcharArray NewCharArray(JNIEnv *env, jsize len)
2939 STATS(jniinvokation();)
2942 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2946 j = builtin_newarray_char(len);
2952 jshortArray NewShortArray(JNIEnv *env, jsize len)
2955 STATS(jniinvokation();)
2958 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2962 j = builtin_newarray_short(len);
2968 jintArray NewIntArray(JNIEnv *env, jsize len)
2971 STATS(jniinvokation();)
2974 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2978 j = builtin_newarray_int(len);
2984 jlongArray NewLongArray(JNIEnv *env, jsize len)
2987 STATS(jniinvokation();)
2990 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2994 j = builtin_newarray_long(len);
3000 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3003 STATS(jniinvokation();)
3006 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
3010 j = builtin_newarray_float(len);
3016 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3018 java_doublearray *j;
3019 STATS(jniinvokation();)
3022 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
3026 j = builtin_newarray_double(len);
3032 jboolean * GetBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *isCopy)
3034 STATS(jniinvokation();)
3035 if (isCopy) *isCopy = JNI_FALSE;
3040 jbyte * GetByteArrayElements (JNIEnv *env, jbyteArray array, jboolean *isCopy)
3042 STATS(jniinvokation();)
3043 if (isCopy) *isCopy = JNI_FALSE;
3048 jchar * GetCharArrayElements (JNIEnv *env, jcharArray array, jboolean *isCopy)
3050 STATS(jniinvokation();)
3051 if (isCopy) *isCopy = JNI_FALSE;
3056 jshort * GetShortArrayElements (JNIEnv *env, jshortArray array, jboolean *isCopy)
3058 STATS(jniinvokation();)
3059 if (isCopy) *isCopy = JNI_FALSE;
3064 jint * GetIntArrayElements (JNIEnv *env, jintArray array, jboolean *isCopy)
3066 STATS(jniinvokation();)
3067 if (isCopy) *isCopy = JNI_FALSE;
3072 jlong * GetLongArrayElements (JNIEnv *env, jlongArray array, jboolean *isCopy)
3074 STATS(jniinvokation();)
3075 if (isCopy) *isCopy = JNI_FALSE;
3080 jfloat * GetFloatArrayElements (JNIEnv *env, jfloatArray array, jboolean *isCopy)
3082 STATS(jniinvokation();)
3083 if (isCopy) *isCopy = JNI_FALSE;
3088 jdouble * GetDoubleArrayElements (JNIEnv *env, jdoubleArray array, jboolean *isCopy)
3090 STATS(jniinvokation();)
3091 if (isCopy) *isCopy = JNI_FALSE;
3097 void ReleaseBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode)
3099 STATS(jniinvokation();)
3104 void ReleaseByteArrayElements (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode)
3106 STATS(jniinvokation();)
3111 void ReleaseCharArrayElements (JNIEnv *env, jcharArray array, jchar *elems, jint mode)
3117 void ReleaseShortArrayElements (JNIEnv *env, jshortArray array, jshort *elems, jint mode)
3119 STATS(jniinvokation();)
3124 void ReleaseIntArrayElements (JNIEnv *env, jintArray array, jint *elems, jint mode)
3126 STATS(jniinvokation();)
3131 void ReleaseLongArrayElements (JNIEnv *env, jlongArray array, jlong *elems, jint mode)
3133 STATS(jniinvokation();)
3138 void ReleaseFloatArrayElements (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode)
3140 STATS(jniinvokation();)
3145 void ReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode)
3147 STATS(jniinvokation();)
3152 void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
3154 STATS(jniinvokation();)
3155 if (start < 0 || len < 0 || start + len > array->header.size)
3156 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3159 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
3163 void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
3165 STATS(jniinvokation();)
3166 if (start < 0 || len < 0 || start + len > array->header.size)
3167 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3170 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
3174 void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
3176 STATS(jniinvokation();)
3177 if (start < 0 || len < 0 || start + len > array->header.size)
3178 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3181 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
3185 void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
3187 STATS(jniinvokation();)
3188 if (start < 0 || len < 0 || start + len > array->header.size)
3189 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3192 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
3196 void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
3198 STATS(jniinvokation();)
3199 if (start < 0 || len < 0 || start + len > array->header.size)
3200 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3203 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
3207 void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
3209 STATS(jniinvokation();)
3210 if (start < 0 || len < 0 || start + len > array->header.size)
3211 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3214 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
3218 void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
3220 STATS(jniinvokation();)
3221 if (start < 0 || len < 0 || start + len > array->header.size)
3222 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3225 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
3229 void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
3231 STATS(jniinvokation();)
3232 if (start < 0 || len < 0 || start+len>array->header.size)
3233 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3236 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
3240 void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
3242 STATS(jniinvokation();)
3243 if (start < 0 || len < 0 || start + len > array->header.size)
3244 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3247 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3251 void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
3253 STATS(jniinvokation();)
3254 if (start < 0 || len < 0 || start + len > array->header.size)
3255 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3258 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3262 void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
3264 STATS(jniinvokation();)
3265 if (start < 0 || len < 0 || start + len > array->header.size)
3266 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3269 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3274 void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
3276 STATS(jniinvokation();)
3277 if (start < 0 || len < 0 || start + len > array->header.size)
3278 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3281 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3285 void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
3287 STATS(jniinvokation();)
3288 if (start < 0 || len < 0 || start + len > array->header.size)
3289 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3292 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3297 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
3299 STATS(jniinvokation();)
3300 if (start < 0 || len < 0 || start + len > array->header.size)
3301 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3304 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3309 void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
3311 STATS(jniinvokation();)
3312 if (start < 0 || len < 0 || start + len > array->header.size)
3313 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3316 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3321 void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
3323 STATS(jniinvokation();)
3324 if (start < 0 || len < 0 || start + len > array->header.size)
3325 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3328 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3332 jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
3334 STATS(jniinvokation();)
3335 log_text("JNI-Call: RegisterNatives");
3340 jint UnregisterNatives (JNIEnv* env, jclass clazz)
3342 STATS(jniinvokation();)
3343 log_text("JNI-Call: UnregisterNatives");
3348 /* Monitor Operations *********************************************************/
3350 /* MonitorEnter ****************************************************************
3352 Enters the monitor associated with the underlying Java object
3355 *******************************************************************************/
3357 jint MonitorEnter(JNIEnv *env, jobject obj)
3359 STATS(jniinvokation();)
3361 *exceptionptr = new_nullpointerexception();
3365 #if defined(USE_THREADS)
3366 builtin_monitorenter(obj);
3373 /* MonitorExit *****************************************************************
3375 The current thread must be the owner of the monitor associated with
3376 the underlying Java object referred to by obj. The thread
3377 decrements the counter indicating the number of times it has
3378 entered this monitor. If the value of the counter becomes zero, the
3379 current thread releases the monitor.
3381 *******************************************************************************/
3383 jint MonitorExit(JNIEnv *env, jobject obj)
3385 STATS(jniinvokation();)
3387 *exceptionptr = new_nullpointerexception();
3391 #if defined(USE_THREADS)
3392 builtin_monitorexit(obj);
3399 /* JavaVM Interface ***********************************************************/
3401 /* GetJavaVM *******************************************************************
3403 Returns the Java VM interface (used in the Invocation API)
3404 associated with the current thread. The result is placed at the
3405 location pointed to by the second argument, vm.
3407 *******************************************************************************/
3409 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
3411 STATS(jniinvokation();)
3418 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3420 STATS(jniinvokation();)
3421 log_text("JNI-Call: GetStringRegion");
3425 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3427 STATS(jniinvokation();)
3428 log_text("JNI-Call: GetStringUTFRegion");
3432 /************** obtain direct pointer to array elements ***********************/
3434 void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
3436 java_objectheader *s = (java_objectheader*) array;
3437 arraydescriptor *desc = s->vftbl->arraydesc;
3439 STATS(jniinvokation();)
3441 if (!desc) return NULL;
3443 return ((u1*)s) + desc->dataoffset;
3447 void ReleasePrimitiveArrayCritical (JNIEnv* env, jarray array, void *carray, jint mode)
3449 STATS(jniinvokation();)
3450 log_text("JNI-Call: ReleasePrimitiveArrayCritical");
3455 /**** returns a pointer to an array of Unicode characters of the string *******/
3457 const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
3459 STATS(jniinvokation();)
3460 log_text("JNI-Call: GetStringCritical");
3462 return GetStringChars(env,string,isCopy);
3465 /*********** native code no longer needs access to chars **********************/
3467 void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
3469 STATS(jniinvokation();)
3470 log_text("JNI-Call: ReleaseStringCritical");
3472 ReleaseStringChars(env,string,cstring);
3476 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3478 STATS(jniinvokation();)
3479 log_text("JNI-Call: NewWeakGlobalRef");
3485 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
3487 STATS(jniinvokation();)
3488 log_text("JNI-Call: DeleteWeakGlobalRef");
3494 /** Creates a new global reference to the object referred to by the obj argument **/
3496 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
3501 STATS(jniinvokation();)
3503 MonitorEnter(env, *global_ref_table);
3505 refcount = CallObjectMethod(env, *global_ref_table, getmid, lobj);
3506 val = (refcount == NULL) ? 0 : CallIntMethod(env, refcount, intvalue);
3507 newval = NewObject(env, intclass, newint, val + 1);
3509 if (newval != NULL) {
3510 CallObjectMethod(env, *global_ref_table, putmid, lobj, newval);
3511 MonitorExit(env, *global_ref_table);
3515 log_text("JNI-NewGlobalRef: unable to create new java.lang.Integer");
3516 MonitorExit(env, *global_ref_table);
3521 /************* Deletes the global reference pointed to by globalRef **************/
3523 void DeleteGlobalRef(JNIEnv* env, jobject gref)
3527 STATS(jniinvokation();)
3529 MonitorEnter(env, *global_ref_table);
3530 refcount = CallObjectMethod(env, *global_ref_table, getmid, gref);
3532 if (refcount == NULL) {
3533 log_text("JNI-DeleteGlobalRef: unable to find global reference");
3537 val = CallIntMethod(env, refcount, intvalue);
3541 CallObjectMethod(env, *global_ref_table, removemid,refcount);
3544 jobject newval = NewObject(env, intclass, newint, val);
3546 if (newval != NULL) {
3547 CallObjectMethod(env,*global_ref_table, putmid,newval);
3550 log_text("JNI-DeleteGlobalRef: unable to create new java.lang.Integer");
3554 MonitorExit(env,*global_ref_table);
3558 /* ExceptionCheck **************************************************************
3560 Returns JNI_TRUE when there is a pending exception; otherwise,
3563 *******************************************************************************/
3565 jboolean ExceptionCheck(JNIEnv *env)
3567 STATS(jniinvokation();)
3568 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
3572 /* New JNI 1.4 functions ******************************************************/
3574 /* NewDirectByteBuffer *********************************************************
3576 Allocates and returns a direct java.nio.ByteBuffer referring to the
3577 block of memory starting at the memory address address and
3578 extending capacity bytes.
3580 *******************************************************************************/
3582 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3584 STATS(jniinvokation();)
3585 log_text("NewDirectByteBuffer: IMPLEMENT ME!");
3591 /* GetDirectBufferAddress ******************************************************
3593 Fetches and returns the starting address of the memory region
3594 referenced by the given direct java.nio.Buffer.
3596 *******************************************************************************/
3598 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
3600 STATS(jniinvokation();)
3601 log_text("GetDirectBufferAddress: IMPLEMENT ME!");
3607 /* GetDirectBufferCapacity *****************************************************
3609 Fetches and returns the capacity in bytes of the memory region
3610 referenced by the given direct java.nio.Buffer.
3612 *******************************************************************************/
3614 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3616 STATS(jniinvokation();)
3617 log_text("GetDirectBufferCapacity: IMPLEMENT ME!");
3623 jint DestroyJavaVM(JavaVM *vm)
3625 STATS(jniinvokation();)
3626 log_text("DestroyJavaVM called");
3632 /* AttachCurrentThread *********************************************************
3634 Attaches the current thread to a Java VM. Returns a JNI interface
3635 pointer in the JNIEnv argument.
3637 Trying to attach a thread that is already attached is a no-op.
3639 A native thread cannot be attached simultaneously to two Java VMs.
3641 When a thread is attached to the VM, the context class loader is
3642 the bootstrap loader.
3644 *******************************************************************************/
3646 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
3648 STATS(jniinvokation();)
3649 log_text("AttachCurrentThread called");
3651 #if !defined(HAVE___THREAD)
3652 /* cacao_thread_attach();*/
3654 #error "No idea how to implement that. Perhaps Stefan knows"
3663 jint DetachCurrentThread(JavaVM *vm)
3665 STATS(jniinvokation();)
3666 log_text("DetachCurrentThread called");
3672 /* GetEnv **********************************************************************
3674 If the current thread is not attached to the VM, sets *env to NULL,
3675 and returns JNI_EDETACHED. If the specified version is not
3676 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3677 sets *env to the appropriate interface, and returns JNI_OK.
3679 *******************************************************************************/
3681 jint GetEnv(JavaVM *vm, void **env, jint version)
3683 STATS(jniinvokation();)
3685 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3686 if (thread_getself() == NULL) {
3688 return JNI_EDETACHED;
3692 if ((version != JNI_VERSION_1_1) && (version != JNI_VERSION_1_2) &&
3693 (version != JNI_VERSION_1_4)) {
3695 return JNI_EVERSION;
3704 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
3706 STATS(jniinvokation();)
3707 log_text("AttachCurrentThreadAsDaemon called");
3712 /************* JNI Initialization ****************************************************/
3714 jobject jni_init1(JNIEnv* env, jobject lobj) {
3715 #if defined(USE_THREADS)
3716 while (initrunning) {yieldThread();} /* wait until init is done */
3718 if (global_ref_table == NULL) {
3721 #if defined(USE_THREADS)
3723 /* wait until jni_init is done */
3724 MonitorEnter(env, *global_ref_table) ;
3725 MonitorExit(env, *global_ref_table);
3728 return NewGlobalRef(env, lobj);
3730 void jni_init2(JNIEnv* env, jobject gref) {
3731 log_text("DeleteGlobalref called before NewGlobalref");
3732 #if defined(USE_THREADS)
3733 while (initrunning) {yieldThread();} /* wait until init is done */
3735 if (global_ref_table == NULL) {
3738 #if defined(USE_THREADS)
3740 /* wait until jni_init is done */
3741 MonitorEnter(env, *global_ref_table) ;
3742 MonitorExit(env, *global_ref_table);
3745 DeleteGlobalRef(env, gref);
3752 log_text("JNI-Init: initialize global_ref_table");
3753 /* initalize global reference table */
3754 ihmclass = FindClass(NULL, "java/util/IdentityHashMap");
3756 if (ihmclass == NULL) {
3757 log_text("JNI-Init: unable to find java.util.IdentityHashMap");
3760 mid = GetMethodID(NULL, ihmclass, "<init>","()V");
3762 log_text("JNI-Init: unable to find constructor in java.util.IdentityHashMap");
3765 global_ref_table = (jobject*)heap_allocate(sizeof(jobject),true,NULL);
3767 *global_ref_table = NewObject(NULL,ihmclass,mid);
3769 if (*global_ref_table == NULL) {
3770 log_text("JNI-Init: unable to create new global_ref_table");
3773 initrunning = false;
3775 getmid = GetMethodID(NULL, ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3777 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3780 getmid = GetMethodID(NULL ,ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3781 if (getmid == NULL) {
3782 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3785 putmid = GetMethodID(NULL, ihmclass, "put","(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
3786 if (putmid == NULL) {
3787 log_text("JNI-Init: unable to find method \"put\" in java.util.IdentityHashMap");
3790 intclass = FindClass(NULL, "java/lang/Integer");
3791 if (intclass == NULL) {
3792 log_text("JNI-Init: unable to find java.lang.Integer");
3795 newint = GetMethodID(NULL, intclass, "<init>","(I)V");
3796 if (newint == NULL) {
3797 log_text("JNI-Init: unable to find constructor in java.lang.Integer");
3800 intvalue = GetMethodID(NULL, intclass, "intValue","()I");
3801 if (intvalue == NULL) {
3802 log_text("JNI-Init: unable to find method \"intValue\" in java.lang.Integer");
3805 removemid = GetMethodID(NULL, ihmclass, "remove","(Ljava/lang/Object;)Ljava/lang/Object;");
3806 if (removemid == NULL) {
3807 log_text("JNI-DeleteGlobalRef: unable to find method \"remove\" in java.lang.Object");
3810 /* set NewGlobalRef, DeleteGlobalRef envTable entry to real implementation */
3812 JNI_JNIEnvTable.NewGlobalRef = &NewGlobalRef;
3813 JNI_JNIEnvTable.DeleteGlobalRef = &DeleteGlobalRef;
3817 /* JNI invocation table *******************************************************/
3819 const struct JNIInvokeInterface JNI_JavaVMTable = {
3825 AttachCurrentThread,
3826 DetachCurrentThread,
3828 AttachCurrentThreadAsDaemon
3832 /* JNI function table *********************************************************/
3834 struct JNINativeInterface JNI_JNIEnvTable = {
3843 &FromReflectedMethod,
3844 &FromReflectedField,
3859 &jni_init1, /* &NewGlobalRef, initialize Global_Ref_Table*/
3860 &jni_init2, /* &DeleteGlobalRef,*/
3864 &EnsureLocalCapacity,
3880 &CallBooleanMethodV,
3881 &CallBooleanMethodA,
3907 &CallNonvirtualObjectMethod,
3908 &CallNonvirtualObjectMethodV,
3909 &CallNonvirtualObjectMethodA,
3910 &CallNonvirtualBooleanMethod,
3911 &CallNonvirtualBooleanMethodV,
3912 &CallNonvirtualBooleanMethodA,
3913 &CallNonvirtualByteMethod,
3914 &CallNonvirtualByteMethodV,
3915 &CallNonvirtualByteMethodA,
3916 &CallNonvirtualCharMethod,
3917 &CallNonvirtualCharMethodV,
3918 &CallNonvirtualCharMethodA,
3919 &CallNonvirtualShortMethod,
3920 &CallNonvirtualShortMethodV,
3921 &CallNonvirtualShortMethodA,
3922 &CallNonvirtualIntMethod,
3923 &CallNonvirtualIntMethodV,
3924 &CallNonvirtualIntMethodA,
3925 &CallNonvirtualLongMethod,
3926 &CallNonvirtualLongMethodV,
3927 &CallNonvirtualLongMethodA,
3928 &CallNonvirtualFloatMethod,
3929 &CallNonvirtualFloatMethodV,
3930 &CallNonvirtualFloatMethodA,
3931 &CallNonvirtualDoubleMethod,
3932 &CallNonvirtualDoubleMethodV,
3933 &CallNonvirtualDoubleMethodA,
3934 &CallNonvirtualVoidMethod,
3935 &CallNonvirtualVoidMethodV,
3936 &CallNonvirtualVoidMethodA,
3961 &CallStaticObjectMethod,
3962 &CallStaticObjectMethodV,
3963 &CallStaticObjectMethodA,
3964 &CallStaticBooleanMethod,
3965 &CallStaticBooleanMethodV,
3966 &CallStaticBooleanMethodA,
3967 &CallStaticByteMethod,
3968 &CallStaticByteMethodV,
3969 &CallStaticByteMethodA,
3970 &CallStaticCharMethod,
3971 &CallStaticCharMethodV,
3972 &CallStaticCharMethodA,
3973 &CallStaticShortMethod,
3974 &CallStaticShortMethodV,
3975 &CallStaticShortMethodA,
3976 &CallStaticIntMethod,
3977 &CallStaticIntMethodV,
3978 &CallStaticIntMethodA,
3979 &CallStaticLongMethod,
3980 &CallStaticLongMethodV,
3981 &CallStaticLongMethodA,
3982 &CallStaticFloatMethod,
3983 &CallStaticFloatMethodV,
3984 &CallStaticFloatMethodA,
3985 &CallStaticDoubleMethod,
3986 &CallStaticDoubleMethodV,
3987 &CallStaticDoubleMethodA,
3988 &CallStaticVoidMethod,
3989 &CallStaticVoidMethodV,
3990 &CallStaticVoidMethodA,
3994 &GetStaticObjectField,
3995 &GetStaticBooleanField,
3996 &GetStaticByteField,
3997 &GetStaticCharField,
3998 &GetStaticShortField,
4000 &GetStaticLongField,
4001 &GetStaticFloatField,
4002 &GetStaticDoubleField,
4003 &SetStaticObjectField,
4004 &SetStaticBooleanField,
4005 &SetStaticByteField,
4006 &SetStaticCharField,
4007 &SetStaticShortField,
4009 &SetStaticLongField,
4010 &SetStaticFloatField,
4011 &SetStaticDoubleField,
4016 &ReleaseStringChars,
4019 &GetStringUTFLength,
4021 &ReleaseStringUTFChars,
4026 &GetObjectArrayElement,
4027 &SetObjectArrayElement,
4038 &GetBooleanArrayElements,
4039 &GetByteArrayElements,
4040 &GetCharArrayElements,
4041 &GetShortArrayElements,
4042 &GetIntArrayElements,
4043 &GetLongArrayElements,
4044 &GetFloatArrayElements,
4045 &GetDoubleArrayElements,
4047 &ReleaseBooleanArrayElements,
4048 &ReleaseByteArrayElements,
4049 &ReleaseCharArrayElements,
4050 &ReleaseShortArrayElements,
4051 &ReleaseIntArrayElements,
4052 &ReleaseLongArrayElements,
4053 &ReleaseFloatArrayElements,
4054 &ReleaseDoubleArrayElements,
4056 &GetBooleanArrayRegion,
4057 &GetByteArrayRegion,
4058 &GetCharArrayRegion,
4059 &GetShortArrayRegion,
4061 &GetLongArrayRegion,
4062 &GetFloatArrayRegion,
4063 &GetDoubleArrayRegion,
4064 &SetBooleanArrayRegion,
4065 &SetByteArrayRegion,
4066 &SetCharArrayRegion,
4067 &SetShortArrayRegion,
4069 &SetLongArrayRegion,
4070 &SetFloatArrayRegion,
4071 &SetDoubleArrayRegion,
4081 /* new JNI 1.2 functions */
4084 &GetStringUTFRegion,
4086 &GetPrimitiveArrayCritical,
4087 &ReleasePrimitiveArrayCritical,
4090 &ReleaseStringCritical,
4093 &DeleteWeakGlobalRef,
4097 /* new JNI 1.4 functions */
4099 &NewDirectByteBuffer,
4100 &GetDirectBufferAddress,
4101 &GetDirectBufferCapacity
4105 /* Invocation API Functions ***************************************************/
4107 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4109 Returns a default configuration for the Java VM.
4111 *******************************************************************************/
4113 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4115 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4117 /* GNU classpath currently supports JNI 1.2 */
4119 _vm_args->version = JNI_VERSION_1_2;
4125 /* JNI_GetCreatedJavaVMs *******************************************************
4127 Returns all Java VMs that have been created. Pointers to VMs are written in
4128 the buffer vmBuf in the order they are created. At most bufLen number of
4129 entries will be written. The total number of created VMs is returned in
4132 *******************************************************************************/
4134 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4136 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4142 /* JNI_CreateJavaVM ************************************************************
4144 Loads and initializes a Java VM. The current thread becomes the main thread.
4145 Sets the env argument to the JNI interface pointer of the main thread.
4147 *******************************************************************************/
4149 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4151 *p_vm = (JavaVM *) &JNI_JavaVMTable;
4152 *p_env = (JNIEnv *) &JNI_JNIEnvTable;
4158 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4159 jobject obj, java_objectarray *params)
4165 if (methodID == 0) {
4166 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
4170 argcount = methodID->parseddesc->paramcount;
4172 /* if method is non-static, remove the `this' pointer */
4174 if (!(methodID->flags & ACC_STATIC))
4177 /* the method is an instance method the obj has to be an instance of the
4178 class the method belongs to. For static methods the obj parameter
4181 if (!(methodID->flags & ACC_STATIC) && obj &&
4182 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4184 new_exception_message(string_java_lang_IllegalArgumentException,
4185 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4192 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
4193 log_text("Too many arguments. invokeNativeHelper does not support that");
4198 if (((params == NULL) && (argcount != 0)) ||
4199 (params && (params->header.size != argcount))) {
4201 new_exception(string_java_lang_IllegalArgumentException);
4206 if (!(methodID->flags & ACC_STATIC) && !obj) {
4208 new_exception_message(string_java_lang_NullPointerException,
4209 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4213 if ((methodID->flags & ACC_STATIC) && (obj))
4217 if ((methodID->flags & ACC_ABSTRACT) ||
4218 (methodID->class->flags & ACC_INTERFACE)) {
4219 methodID = get_virtual(obj, methodID);
4223 blk = MNEW(jni_callblock, /*4 */argcount + 2);
4225 if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4229 switch (methodID->parseddesc->returntype.decltype) {
4231 (void) asm_calljavafunction2(methodID, argcount + 1,
4232 (argcount + 1) * sizeof(jni_callblock),
4234 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4237 case PRIMITIVETYPE_INT: {
4239 i = asm_calljavafunction2int(methodID, argcount + 1,
4240 (argcount + 1) * sizeof(jni_callblock),
4243 o = native_new_and_init_int(class_java_lang_Integer, i);
4247 case PRIMITIVETYPE_BYTE: {
4249 i = asm_calljavafunction2int(methodID, argcount + 1,
4250 (argcount + 1) * sizeof(jni_callblock),
4253 /* o = native_new_and_init_int(class_java_lang_Byte, i); */
4254 o = builtin_new(class_java_lang_Byte);
4257 class_resolvemethod(o->vftbl->class,
4264 case PRIMITIVETYPE_CHAR: {
4266 intVal = asm_calljavafunction2int(methodID,
4268 (argcount + 1) * sizeof(jni_callblock),
4270 o = builtin_new(class_java_lang_Character);
4273 class_resolvemethod(o->vftbl->class,
4280 case PRIMITIVETYPE_SHORT: {
4282 intVal = asm_calljavafunction2int(methodID,
4284 (argcount + 1) * sizeof(jni_callblock),
4286 o = builtin_new(class_java_lang_Short);
4289 class_resolvemethod(o->vftbl->class,
4296 case PRIMITIVETYPE_BOOLEAN: {
4298 intVal = asm_calljavafunction2int(methodID,
4300 (argcount + 1) * sizeof(jni_callblock),
4302 o = builtin_new(class_java_lang_Boolean);
4305 class_resolvemethod(o->vftbl->class,
4314 longVal = asm_calljavafunction2long(methodID,
4316 (argcount + 1) * sizeof(jni_callblock),
4318 o = builtin_new(class_java_lang_Long);
4321 class_resolvemethod(o->vftbl->class,
4328 case PRIMITIVETYPE_FLOAT: {
4330 floatVal = asm_calljavafunction2float(methodID,
4332 (argcount + 1) * sizeof(jni_callblock),
4334 o = builtin_new(class_java_lang_Float);
4337 class_resolvemethod(o->vftbl->class,
4344 case PRIMITIVETYPE_DOUBLE: {
4346 doubleVal = asm_calljavafunction2double(methodID,
4348 (argcount + 1) * sizeof(jni_callblock),
4350 o = builtin_new(class_java_lang_Double);
4353 class_resolvemethod(o->vftbl->class,
4361 o = asm_calljavafunction2(methodID, argcount + 1,
4362 (argcount + 1) * sizeof(jni_callblock), blk);
4366 /* if this happens the exception has already been set by */
4367 /* fill_callblock_from_objectarray */
4369 MFREE(blk, jni_callblock, /*4 */ argcount+2);
4370 return (jobject *) 0;
4373 MFREE(blk, jni_callblock, /* 4 */ argcount+2);
4375 if (*exceptionptr) {
4376 java_objectheader *cause;
4378 cause = *exceptionptr;
4380 /* clear exception pointer, we are calling JIT code again */
4382 *exceptionptr = NULL;
4385 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
4386 (java_lang_Throwable *) cause);
4389 return (jobject *) o;
4394 * These are local overrides for various environment variables in Emacs.
4395 * Please do not remove this and leave it at the end of the file, where
4396 * Emacs will automagically detect them.
4397 * ---------------------------------------------------------------------
4400 * indent-tabs-mode: t