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 3017 2005-07-12 21:50:06Z twisti $
44 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/native.h"
47 #include "native/include/java_lang_Object.h"
48 #include "native/include/java_lang_Byte.h"
49 #include "native/include/java_lang_Character.h"
50 #include "native/include/java_lang_Short.h"
51 #include "native/include/java_lang_Integer.h"
52 #include "native/include/java_lang_Boolean.h"
53 #include "native/include/java_lang_Long.h"
54 #include "native/include/java_lang_Float.h"
55 #include "native/include/java_lang_Double.h"
56 #include "native/include/java_lang_Throwable.h"
57 #include "native/include/java_lang_reflect_Method.h"
58 #include "native/include/java_lang_reflect_Constructor.h"
59 #include "native/include/java_lang_reflect_Field.h"
61 #include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
62 #include "native/include/java_lang_VMClass.h"
63 #include "native/include/java_lang_VMClassLoader.h"
65 #if defined(USE_THREADS)
66 # if defined(NATIVE_THREADS)
67 # include "threads/native/threads.h"
69 # include "threads/green/threads.h"
73 #include "toolbox/logging.h"
74 #include "vm/builtin.h"
75 #include "vm/exceptions.h"
76 #include "vm/global.h"
77 #include "vm/initialize.h"
78 #include "vm/loader.h"
79 #include "vm/options.h"
80 #include "vm/resolve.h"
81 #include "vm/statistics.h"
82 #include "vm/stringlocal.h"
83 #include "vm/tables.h"
84 #include "vm/jit/asmpart.h"
85 #include "vm/jit/jit.h"
86 #include "vm/statistics.h"
89 /* XXX TWISTI hack: define it extern so they can be found in this file */
91 extern const struct JNIInvokeInterface JNI_JavaVMTable;
92 extern struct JNINativeInterface JNI_JNIEnvTable;
94 /* pointers to VM and the environment needed by GetJavaVM and GetEnv */
96 static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
97 static void* ptr_env = (void*) &JNI_JNIEnvTable;
100 #define PTR_TO_ITEM(ptr) ((u8)(size_t)(ptr))
102 /* global reference table */
103 static jobject *global_ref_table;
104 static bool initrunning=false;
106 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
107 static jmethodID getmid = NULL;
108 static jmethodID putmid = NULL;
109 static jclass intclass = NULL;
110 static jmethodID intvalue = NULL;
111 static jmethodID newint = NULL;
112 static jclass ihmclass = NULL;
113 static jmethodID removemid = NULL;
115 #define JWCLINITDEBUG(x)
118 /********************* accessing instance-fields **********************************/
120 #define setField(obj,typ,var,val) *((typ*) ((long int) obj + (long int) var->offset))=val;
121 #define getField(obj,typ,var) *((typ*) ((long int) obj + (long int) var->offset))
122 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) \
123 setField(obj, jdatatype, getFieldID_critical(env,clazz,name,sig), val);
126 static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
127 jni_callblock blk[], va_list data,
130 typedesc *paramtypes;
133 paramtypes = descr->paramtypes;
135 /* if method is non-static fill first block and skip `this' pointer */
140 /* the `this' pointer */
141 blk[0].itemtype = TYPE_ADR;
142 blk[0].item = PTR_TO_ITEM(obj);
148 for (; i < descr->paramcount; i++, paramtypes++) {
149 switch (paramtypes->decltype) {
150 /* primitive types */
151 case PRIMITIVETYPE_BYTE:
152 case PRIMITIVETYPE_CHAR:
153 case PRIMITIVETYPE_SHORT:
154 case PRIMITIVETYPE_BOOLEAN:
155 blk[i].itemtype = TYPE_INT;
156 blk[i].item = (s8) va_arg(data, s4);
159 case PRIMITIVETYPE_INT:
160 blk[i].itemtype = TYPE_INT;
161 blk[i].item = (s8) va_arg(data, s4);
164 case PRIMITIVETYPE_LONG:
165 blk[i].itemtype = TYPE_LNG;
166 blk[i].item = (s8) va_arg(data, s8);
169 case PRIMITIVETYPE_FLOAT:
170 blk[i].itemtype = TYPE_FLT;
171 #if defined(__ALPHA__)
172 /* this keeps the assembler function much simpler */
174 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
176 *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
180 case PRIMITIVETYPE_DOUBLE:
181 blk[i].itemtype = TYPE_DBL;
182 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
186 blk[i].itemtype = TYPE_ADR;
187 blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
192 /* The standard doesn't say anything about return value checking, but it */
193 /* appears to be useful. */
195 if (rettype != descr->returntype.decltype)
196 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
200 /* XXX it could be considered if we should do typechecking here in the future */
202 static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
204 java_objectarray *params)
208 typedesc *paramtypes;
213 paramcount = descr->paramcount;
214 paramtypes = descr->paramtypes;
216 /* if method is non-static fill first block and skip `this' pointer */
222 blk[0].itemtype = TYPE_ADR;
223 blk[0].item = PTR_TO_ITEM(obj);
230 for (j = 0; j < paramcount; i++, j++, paramtypes++) {
231 switch (paramtypes->type) {
232 /* primitive types */
237 param = params->data[j];
241 /* internally used data type */
242 blk[i].itemtype = paramtypes->type;
244 /* convert the value according to its declared type */
246 c = param->vftbl->class;
248 switch (paramtypes->decltype) {
249 case PRIMITIVETYPE_BOOLEAN:
250 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
251 blk[i].item = (s8) ((java_lang_Boolean *) param)->value;
256 case PRIMITIVETYPE_BYTE:
257 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
258 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
263 case PRIMITIVETYPE_CHAR:
264 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
265 blk[i].item = (s8) ((java_lang_Character *) param)->value;
270 case PRIMITIVETYPE_SHORT:
271 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
272 blk[i].item = (s8) ((java_lang_Short *) param)->value;
273 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
274 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
279 case PRIMITIVETYPE_INT:
280 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
281 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
282 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
283 blk[i].item = (s8) ((java_lang_Short *) param)->value;
284 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
285 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
290 case PRIMITIVETYPE_LONG:
291 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
292 blk[i].item = (s8) ((java_lang_Long *) param)->value;
293 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
294 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
295 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
296 blk[i].item = (s8) ((java_lang_Short *) param)->value;
297 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
298 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
303 case PRIMITIVETYPE_FLOAT:
304 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
305 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
310 case PRIMITIVETYPE_DOUBLE:
311 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
312 *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Float *) param)->value;
313 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
314 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
321 } /* end declared type switch */
325 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
328 if (params->data[j] != 0) {
329 if (paramtypes->arraydim > 0) {
330 if (!builtin_arrayinstanceof(params->data[j], c->vftbl))
334 if (!builtin_instanceof(params->data[j], c))
338 blk[i].itemtype = TYPE_ADR;
339 blk[i].item = PTR_TO_ITEM(params->data[j]);
344 } /* end param type switch */
346 } /* end param loop */
349 /* *rettype = descr->returntype.decltype; */
354 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
359 static jmethodID get_virtual(jobject obj, jmethodID methodID)
361 if (obj->vftbl->class == methodID->class)
364 return class_resolvemethod(obj->vftbl->class, methodID->name,
365 methodID->descriptor);
369 static jmethodID get_nonvirtual(jclass clazz, jmethodID methodID)
371 if (clazz == methodID->class)
374 /* class_resolvemethod -> classfindmethod? (JOWENN) */
375 return class_resolvemethod(clazz, methodID->name, methodID->descriptor);
379 static jobject callObjectMethod(jobject obj, jmethodID methodID, va_list args)
388 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
392 argcount = methodID->parseddesc->paramcount;
394 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
395 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
396 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
400 if (obj && !builtin_instanceof(obj, methodID->class)) {
401 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
408 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
409 log_text("Too many arguments. CallObjectMethod does not support that");
414 blk = MNEW(jni_callblock, /*4 */argcount+2);
416 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_ADR);
417 /* printf("parameter: obj: %p",blk[0].item); */
418 STATS(jnicallXmethodnvokation();)
419 ret = asm_calljavafunction2(methodID,
421 (argcount + 1) * sizeof(jni_callblock),
423 MFREE(blk, jni_callblock, argcount + 1);
424 /* printf("(CallObjectMethodV)-->%p\n",ret); */
431 core function for integer class methods (bool, byte, short, integer)
432 This is basically needed for i386
434 static jint callIntegerMethod(jobject obj, jmethodID methodID, int retType, va_list args)
440 STATS(jniinvokation();)
443 log_text("JNI-Call: CallObjectMethodV");
444 utf_display(methodID->name);
445 utf_display(methodID->descriptor);
446 printf("\nParmaeter count: %d\n",argcount);
447 utf_display(obj->vftbl->class->name);
451 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
455 argcount = methodID->parseddesc->paramcount;
457 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
458 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
459 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
463 if (obj && !builtin_instanceof(obj, methodID->class)) {
464 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
470 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
471 log_text("Too many arguments. CallIntegerMethod does not support that");
476 blk = MNEW(jni_callblock, /*4 */ argcount+2);
478 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
480 /* printf("parameter: obj: %p",blk[0].item); */
481 STATS(jnicallXmethodnvokation();)
482 ret = asm_calljavafunction2int(methodID,
484 (argcount + 1) * sizeof(jni_callblock),
487 MFREE(blk, jni_callblock, argcount + 1);
488 /* printf("(CallObjectMethodV)-->%p\n",ret); */
494 /*core function for long class functions*/
495 static jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
501 STATS(jniinvokation();)
504 log_text("JNI-Call: CallObjectMethodV");
505 utf_display(methodID->name);
506 utf_display(methodID->descriptor);
507 printf("\nParmaeter count: %d\n",argcount);
508 utf_display(obj->vftbl->class->name);
512 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
516 argcount = methodID->parseddesc->paramcount;
518 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
519 ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
520 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
524 if (obj && !builtin_instanceof(obj,methodID->class)) {
525 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
531 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
532 log_text("Too many arguments. CallObjectMethod does not support that");
537 blk = MNEW(jni_callblock,/* 4 */argcount+2);
539 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_LNG);
541 /* printf("parameter: obj: %p",blk[0].item); */
542 STATS(jnicallXmethodnvokation();)
543 ret = asm_calljavafunction2long(methodID,
545 (argcount + 1) * sizeof(jni_callblock),
548 MFREE(blk, jni_callblock, argcount + 1);
549 /* printf("(CallObjectMethodV)-->%p\n",ret); */
555 /*core function for float class methods (float,double)*/
556 static jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,int retType)
558 int argcount = methodID->parseddesc->paramcount;
562 STATS(jniinvokation();)
565 log_text("JNI-Call: CallObjectMethodV");
566 utf_display(methodID->name);
567 utf_display(methodID->descriptor);
568 printf("\nParmaeter count: %d\n",argcount);
569 utf_display(obj->vftbl->class->name);
575 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
576 log_text("Too many arguments. CallObjectMethod does not support that");
581 blk = MNEW(jni_callblock, /*4 */ argcount+2);
583 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
585 /* printf("parameter: obj: %p",blk[0].item); */
586 STATS(jnicallXmethodnvokation();)
587 ret = asm_calljavafunction2double(methodID,
589 (argcount + 1) * sizeof(jni_callblock),
592 MFREE(blk, jni_callblock, argcount + 1);
593 /* printf("(CallObjectMethodV)-->%p\n",ret); */
599 /*************************** function: jclass_findfield ****************************
601 searches for field with specified name and type in a 'classinfo'-structur
602 if no such field is found NULL is returned
604 ************************************************************************************/
606 static fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
609 STATS(jniinvokation();)
611 /* printf(" FieldCount: %d\n",c->fieldscount);
612 utf_display(c->name); */
613 for (i = 0; i < c->fieldscount; i++) {
614 /* utf_display(c->fields[i].name);
616 utf_display(c->fields[i].descriptor);
618 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
619 return &(c->fields[i]);
622 if (c->super.cls) return jclass_findfield(c->super.cls,name,desc);
628 /* GetVersion ******************************************************************
630 Returns the major version number in the higher 16 bits and the
631 minor version number in the lower 16 bits.
633 *******************************************************************************/
635 jint GetVersion(JNIEnv *env)
637 STATS(jniinvokation();)
639 /* just say we support JNI 1.4 */
641 return JNI_VERSION_1_4;
645 /* Class Operations ***********************************************************/
647 /* DefineClass *****************************************************************
649 Loads a class from a buffer of raw class data. The buffer
650 containing the raw class data is not referenced by the VM after the
651 DefineClass call returns, and it may be discarded if desired.
653 *******************************************************************************/
655 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
656 const jbyte *buf, jsize bufLen)
658 java_lang_ClassLoader *cl;
663 STATS(jniinvokation();)
665 cl = (java_lang_ClassLoader *) loader;
666 s = javastring_new_char(name);
667 ba = (java_bytearray *) buf;
669 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
676 /* FindClass *******************************************************************
678 This function loads a locally-defined class. It searches the
679 directories and zip files specified by the CLASSPATH environment
680 variable for the class with the specified name.
682 *******************************************************************************/
684 jclass FindClass(JNIEnv *env, const char *name)
688 java_objectheader *cl;
690 STATS(jniinvokation();)
692 u = utf_new_char_classname((char *) name);
694 /* check stacktrace for classloader, if one found use it, otherwise use */
695 /* the system classloader */
697 #if defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__)
698 cl = cacao_currentClassLoader();
703 if (!(c = load_class_from_classloader(u, cl)))
709 use_class_as_object(c);
715 /* FromReflectedMethod *********************************************************
717 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
718 object to a method ID.
720 *******************************************************************************/
722 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
728 STATS(jniinvokation();)
733 if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
734 java_lang_reflect_Method *rm;
736 rm = (java_lang_reflect_Method *) method;
737 c = (classinfo *) (rm->declaringClass);
740 } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
741 java_lang_reflect_Constructor *rc;
743 rc = (java_lang_reflect_Constructor *) method;
744 c = (classinfo *) (rc->clazz);
750 if ((slot < 0) || (slot >= c->methodscount)) {
751 /* this usually means a severe internal cacao error or somebody
752 tempered around with the reflected method */
753 log_text("error illegal slot for method in class(FromReflectedMethod)");
757 mi = &(c->methods[slot]);
763 /* GetSuperclass ***************************************************************
765 If clazz represents any class other than the class Object, then
766 this function returns the object that represents the superclass of
767 the class specified by clazz.
769 *******************************************************************************/
771 jclass GetSuperclass(JNIEnv *env, jclass sub)
774 STATS(jniinvokation();)
776 c = ((classinfo *) sub)->super.cls;
781 use_class_as_object(c);
787 /* IsAssignableFrom ************************************************************
789 Determines whether an object of sub can be safely cast to sup.
791 *******************************************************************************/
793 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
795 STATS(jniinvokation();)
796 return Java_java_lang_VMClass_isAssignableFrom(env,
798 (java_lang_Class *) sup,
799 (java_lang_Class *) sub);
803 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
805 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
807 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!!!");
808 STATS(jniinvokation();)
813 /* Throw ***********************************************************************
815 Causes a java.lang.Throwable object to be thrown.
817 *******************************************************************************/
819 jint Throw(JNIEnv *env, jthrowable obj)
821 *exceptionptr = (java_objectheader *) obj;
822 STATS(jniinvokation();)
828 /* ThrowNew ********************************************************************
830 Constructs an exception object from the specified class with the
831 message specified by message and causes that exception to be
834 *******************************************************************************/
836 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
838 java_lang_Throwable *o;
840 STATS(jniinvokation();)
842 s = (java_lang_String *) javastring_new_char(msg);
844 /* instantiate exception object */
846 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
852 *exceptionptr = (java_objectheader *) o;
858 /* ExceptionOccurred ***********************************************************
860 Determines if an exception is being thrown. The exception stays
861 being thrown until either the native code calls ExceptionClear(),
862 or the Java code handles the exception.
864 *******************************************************************************/
866 jthrowable ExceptionOccurred(JNIEnv *env)
868 STATS(jniinvokation();)
869 return (jthrowable) *exceptionptr;
873 /* ExceptionDescribe ***********************************************************
875 Prints an exception and a backtrace of the stack to a system
876 error-reporting channel, such as stderr. This is a convenience
877 routine provided for debugging.
879 *******************************************************************************/
881 void ExceptionDescribe(JNIEnv *env)
883 java_objectheader *e;
885 STATS(jniinvokation();)
890 /* clear exception, because we are calling jit code again */
892 *exceptionptr = NULL;
894 /* get printStackTrace method from exception class */
896 m = class_resolveclassmethod(e->vftbl->class,
903 /* XXX what should we do? */
906 /* print the stacktrace */
908 asm_calljavafunction(m, e, NULL, NULL, NULL);
913 /* ExceptionClear **************************************************************
915 Clears any exception that is currently being thrown. If no
916 exception is currently being thrown, this routine has no effect.
918 *******************************************************************************/
920 void ExceptionClear(JNIEnv *env)
922 STATS(jniinvokation();)
923 *exceptionptr = NULL;
927 /* FatalError ******************************************************************
929 Raises a fatal error and does not expect the VM to recover. This
930 function does not return.
932 *******************************************************************************/
934 void FatalError(JNIEnv *env, const char *msg)
936 STATS(jniinvokation();)
937 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
941 /******************* creates a new local reference frame **************************/
943 jint PushLocalFrame(JNIEnv* env, jint capacity)
945 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
946 STATS(jniinvokation();)
951 /**************** Pops off the current local reference frame **********************/
953 jobject PopLocalFrame(JNIEnv* env, jobject result)
955 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
956 STATS(jniinvokation();)
962 /* DeleteLocalRef **************************************************************
964 Deletes the local reference pointed to by localRef.
966 *******************************************************************************/
968 void DeleteLocalRef(JNIEnv *env, jobject localRef)
970 STATS(jniinvokation();)
972 log_text("JNI-Call: DeleteLocalRef: IMPLEMENT ME!");
976 /* IsSameObject ****************************************************************
978 Tests whether two references refer to the same Java object.
980 *******************************************************************************/
982 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
984 STATS(jniinvokation();)
985 return (ref1 == ref2);
989 /* NewLocalRef *****************************************************************
991 Creates a new local reference that refers to the same object as ref.
993 *******************************************************************************/
995 jobject NewLocalRef(JNIEnv *env, jobject ref)
997 log_text("JNI-Call: NewLocalRef: IMPLEMENT ME!");
998 STATS(jniinvokation();)
1002 /***********************************************************************************
1004 Ensures that at least a given number of local references can
1005 be created in the current thread
1007 **********************************************************************************/
1009 jint EnsureLocalCapacity (JNIEnv* env, jint capacity)
1011 STATS(jniinvokation();)
1012 return 0; /* return 0 on success */
1016 /* AllocObject *****************************************************************
1018 Allocates a new Java object without invoking any of the
1019 constructors for the object. Returns a reference to the object.
1021 *******************************************************************************/
1023 jobject AllocObject(JNIEnv *env, jclass clazz)
1025 java_objectheader *o;
1026 STATS(jniinvokation();)
1028 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1030 new_exception_utfmessage(string_java_lang_InstantiationException,
1035 o = builtin_new(clazz);
1041 /* NewObject *******************************************************************
1043 Constructs a new Java object. The method ID indicates which
1044 constructor method to invoke. This ID must be obtained by calling
1045 GetMethodID() with <init> as the method name and void (V) as the
1048 *******************************************************************************/
1050 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1052 java_objectheader *o;
1054 int argcount=methodID->parseddesc->paramcount;
1057 STATS(jniinvokation();)
1061 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
1062 log_text("Too many arguments. NewObject does not support that");
1069 o = builtin_new(clazz);
1074 va_start(vaargs, methodID);
1075 for (i = 0; i < argcount; i++) {
1076 args[i] = va_arg(vaargs, void*);
1080 /* call constructor */
1082 asm_calljavafunction(methodID, o, args[0], args[1], args[2]);
1088 /***********************************************************************************
1090 Constructs a new Java object
1091 arguments that are to be passed to the constructor are placed in va_list args
1093 ***********************************************************************************/
1095 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1097 log_text("JNI-Call: NewObjectV");
1098 STATS(jniinvokation();)
1104 /***********************************************************************************
1106 Constructs a new Java object
1107 arguments that are to be passed to the constructor are placed in
1108 args array of jvalues
1110 ***********************************************************************************/
1112 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1114 log_text("JNI-Call: NewObjectA");
1115 STATS(jniinvokation();)
1121 /* GetObjectClass **************************************************************
1123 Returns the class of an object.
1125 *******************************************************************************/
1127 jclass GetObjectClass(JNIEnv *env, jobject obj)
1130 STATS(jniinvokation();)
1132 if (!obj || !obj->vftbl)
1135 c = obj->vftbl->class;
1136 use_class_as_object(c);
1141 /* IsInstanceOf ****************************************************************
1143 Tests whether an object is an instance of a class.
1145 *******************************************************************************/
1147 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1149 STATS(jniinvokation();)
1151 return Java_java_lang_VMClass_isInstance(env,
1153 (java_lang_Class *) clazz,
1154 (java_lang_Object *) obj);
1158 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1160 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1162 java_lang_reflect_Field *f;
1164 jfieldID fid; /* the JNI-fieldid of the wrapping object */
1165 STATS(jniinvokation();)
1166 /*log_text("JNI-Call: FromReflectedField");*/
1168 f=(java_lang_reflect_Field *)field;
1170 c=(classinfo*)(f->declaringClass);
1171 if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1172 /*this usually means a severe internal cacao error or somebody
1173 tempered around with the reflected method*/
1174 log_text("error illegal slot for field in class(FromReflectedField)");
1177 fid=&(c->fields[f->slot]);
1182 /**********************************************************************************
1184 converts a method ID to a java.lang.reflect.Method or
1185 java.lang.reflect.Constructor object
1187 **********************************************************************************/
1189 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1191 log_text("JNI-Call: ToReflectedMethod");
1192 STATS(jniinvokation();)
1198 /* GetMethodID *****************************************************************
1200 returns the method ID for an instance method
1202 *******************************************************************************/
1204 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1207 STATS(jniinvokation();)
1209 m = class_resolvemethod(clazz,
1210 utf_new_char((char *) name),
1211 utf_new_char((char *) sig));
1213 if (!m || (m->flags & ACC_STATIC)) {
1215 new_exception_message(string_java_lang_NoSuchMethodError, name);
1224 /******************** JNI-functions for calling instance methods ******************/
1226 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1230 STATS(jniinvokation();)
1232 /* log_text("JNI-Call: CallObjectMethod");*/
1234 va_start(vaargs, methodID);
1235 ret = callObjectMethod(obj, methodID, vaargs);
1242 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1244 STATS(jniinvokation();)
1245 return callObjectMethod(obj,methodID,args);
1249 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1251 log_text("JNI-Call: CallObjectMethodA");
1252 STATS(jniinvokation();)
1260 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1264 STATS(jniinvokation();)
1266 /* log_text("JNI-Call: CallBooleanMethod");*/
1268 va_start(vaargs,methodID);
1269 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1275 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1277 STATS(jniinvokation();)
1279 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
1283 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1285 STATS(jniinvokation();)
1286 log_text("JNI-Call: CallBooleanMethodA");
1291 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1295 STATS(jniinvokation();)
1297 /* log_text("JNI-Call: CallVyteMethod");*/
1299 va_start(vaargs,methodID);
1300 ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
1306 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1308 /* log_text("JNI-Call: CallByteMethodV");*/
1309 STATS(jniinvokation();)
1311 return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
1315 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1317 log_text("JNI-Call: CallByteMethodA");
1318 STATS(jniinvokation();)
1324 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1328 STATS(jniinvokation();)
1330 /* log_text("JNI-Call: CallCharMethod");*/
1332 va_start(vaargs,methodID);
1333 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
1340 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1342 STATS(jniinvokation();)
1344 /* log_text("JNI-Call: CallCharMethodV");*/
1345 return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
1349 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1351 STATS(jniinvokation();)
1353 log_text("JNI-Call: CallCharMethodA");
1359 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1363 STATS(jniinvokation();)
1365 /* log_text("JNI-Call: CallShortMethod");*/
1367 va_start(vaargs, methodID);
1368 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
1375 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1377 STATS(jniinvokation();)
1378 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
1382 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1384 STATS(jniinvokation();)
1385 log_text("JNI-Call: CallShortMethodA");
1392 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1396 STATS(jniinvokation();)
1398 va_start(vaargs,methodID);
1399 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
1406 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1408 STATS(jniinvokation();)
1409 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
1413 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1415 STATS(jniinvokation();)
1416 log_text("JNI-Call: CallIntMethodA");
1423 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1427 STATS(jniinvokation();)
1429 va_start(vaargs,methodID);
1430 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1437 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1439 STATS(jniinvokation();)
1440 return callLongMethod(obj,get_virtual(obj, methodID),args);
1444 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1446 STATS(jniinvokation();)
1447 log_text("JNI-Call: CallLongMethodA");
1454 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1459 STATS(jniinvokation();)
1460 /* log_text("JNI-Call: CallFloatMethod");*/
1462 va_start(vaargs,methodID);
1463 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
1470 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1472 STATS(jniinvokation();)
1473 log_text("JNI-Call: CallFloatMethodV");
1474 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
1478 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1480 STATS(jniinvokation();)
1481 log_text("JNI-Call: CallFloatMethodA");
1488 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1492 STATS(jniinvokation();)
1494 /* log_text("JNI-Call: CallDoubleMethod");*/
1496 va_start(vaargs,methodID);
1497 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
1504 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1506 STATS(jniinvokation();)
1507 log_text("JNI-Call: CallDoubleMethodV");
1508 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
1512 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1514 STATS(jniinvokation();)
1515 log_text("JNI-Call: CallDoubleMethodA");
1521 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1524 STATS(jniinvokation();)
1526 va_start(vaargs,methodID);
1527 (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
1532 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1534 log_text("JNI-Call: CallVoidMethodV");
1535 STATS(jniinvokation();)
1536 (void)callIntegerMethod(obj,get_virtual(obj,methodID),TYPE_VOID,args);
1540 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1542 STATS(jniinvokation();)
1543 log_text("JNI-Call: CallVoidMethodA");
1548 jobject CallNonvirtualObjectMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1550 STATS(jniinvokation();)
1551 log_text("JNI-Call: CallNonvirtualObjectMethod");
1557 jobject CallNonvirtualObjectMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1559 STATS(jniinvokation();)
1560 log_text("JNI-Call: CallNonvirtualObjectMethodV");
1566 jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1568 STATS(jniinvokation();)
1569 log_text("JNI-Call: CallNonvirtualObjectMethodA");
1576 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1580 STATS(jniinvokation();)
1582 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1584 va_start(vaargs,methodID);
1585 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1592 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1594 STATS(jniinvokation();)
1595 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1596 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
1600 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1602 STATS(jniinvokation();)
1603 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1610 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1615 STATS(jniinvokation();)
1616 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1618 va_start(vaargs,methodID);
1619 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
1625 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1627 STATS(jniinvokation();)
1628 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1629 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
1634 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1636 STATS(jniinvokation();)
1637 log_text("JNI-Call: CallNonvirtualByteMethodA");
1644 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1649 STATS(jniinvokation();)
1650 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1652 va_start(vaargs,methodID);
1653 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
1659 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1661 STATS(jniinvokation();)
1662 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1663 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
1667 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1669 STATS(jniinvokation();)
1670 log_text("JNI-Call: CallNonvirtualCharMethodA");
1677 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1681 STATS(jniinvokation();)
1683 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1685 va_start(vaargs,methodID);
1686 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
1692 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1694 STATS(jniinvokation();)
1695 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1696 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
1700 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1702 STATS(jniinvokation();)
1703 log_text("JNI-Call: CallNonvirtualShortMethodA");
1710 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1715 STATS(jniinvokation();)
1717 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1719 va_start(vaargs,methodID);
1720 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
1726 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1728 STATS(jniinvokation();)
1729 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1730 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
1734 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1736 STATS(jniinvokation();)
1737 log_text("JNI-Call: CallNonvirtualIntMethodA");
1744 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1746 STATS(jniinvokation();)
1747 log_text("JNI-Call: CallNonvirtualLongMethod");
1753 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1755 STATS(jniinvokation();)
1756 log_text("JNI-Call: CallNonvirtualLongMethodV");
1762 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1764 STATS(jniinvokation();)
1765 log_text("JNI-Call: CallNonvirtualLongMethodA");
1772 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1776 STATS(jniinvokation();)
1778 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1781 va_start(vaargs,methodID);
1782 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
1789 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1791 STATS(jniinvokation();)
1792 log_text("JNI-Call: CallNonvirtualFloatMethodV");
1793 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
1797 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1799 STATS(jniinvokation();)
1800 log_text("JNI-Call: CallNonvirtualFloatMethodA");
1807 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1811 STATS(jniinvokation();)
1812 log_text("JNI-Call: CallNonvirtualDoubleMethod");
1814 va_start(vaargs,methodID);
1815 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
1822 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1824 STATS(jniinvokation();)
1825 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
1826 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
1830 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1832 STATS(jniinvokation();)
1833 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
1840 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1843 STATS(jniinvokation();)
1845 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
1847 va_start(vaargs,methodID);
1848 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
1854 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1856 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
1857 STATS(jniinvokation();)
1859 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
1864 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1866 STATS(jniinvokation();)
1867 log_text("JNI-Call: CallNonvirtualVoidMethodA");
1870 /************************* JNI-functions for accessing fields ************************/
1872 jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
1876 STATS(jniinvokation();)
1878 /* log_text("========================= searching for:");
1881 f = jclass_findfield(clazz,
1882 utf_new_char ((char*) name),
1883 utf_new_char ((char*) sig)
1887 /*utf_display(clazz->name);
1890 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
1895 /*************************** retrieve fieldid, abort on error ************************/
1897 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
1899 jfieldID id = GetFieldID(env, clazz, name, sig);
1900 STATS(jniinvokation();)
1904 utf_display(clazz->name);
1905 log_text("\nfield:");
1910 log_text("setfield_critical failed");
1916 jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
1919 jobject dbg,dretval,*dpretval;
1920 long int dli1, dli2, dli3;
1922 printf("GetObjectField(1): thread: %s obj: %p name: %s desc: %s \n",GetStringUTFChars(env,
1923 ((threadobject *) THREADOBJECT)->o
1925 ,obj,((fieldinfo*)fieldID)->name->text,(fieldID->descriptor)->text);
1927 dbg = getField(obj,jobject,fieldID);
1928 dli1 = (long int) obj;
1929 dli2 = (long int) fieldID->offset;
1931 dpretval = (jobject*) dli3;
1932 dretval = *dpretval;
1937 tmp = FindClass(env, "java/lang/Object");
1938 mid = GetMethodID(env,tmp,"toString","()Ljava/lang/String;");
1939 jstr = CallObjectMethod(env,dbg,mid);*/
1941 /* printf("GetObjectField(2): retval %p (obj: %#lx + offset: %#lx = %#lx (jobject*) %p (jobject) %p\n"
1942 ,dbg, dli1, dli2, dli3,dpretval, dretval);*/
1946 STATS(jniinvokation();)
1948 return getField(obj,jobject,fieldID);
1951 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
1953 STATS(jniinvokation();)
1954 return getField(obj,jboolean,fieldID);
1958 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
1960 STATS(jniinvokation();)
1961 return getField(obj,jbyte,fieldID);
1965 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
1967 STATS(jniinvokation();)
1968 return getField(obj,jchar,fieldID);
1972 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
1974 STATS(jniinvokation();)
1975 return getField(obj,jshort,fieldID);
1979 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
1981 STATS(jniinvokation();)
1982 return getField(obj,jint,fieldID);
1986 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
1988 STATS(jniinvokation();)
1989 return getField(obj,jlong,fieldID);
1993 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
1995 STATS(jniinvokation();)
1996 return getField(obj,jfloat,fieldID);
2000 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
2002 STATS(jniinvokation();)
2003 return getField(obj,jdouble,fieldID);
2006 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
2008 STATS(jniinvokation();)
2009 setField(obj,jobject,fieldID,val);
2013 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
2015 STATS(jniinvokation();)
2016 setField(obj,jboolean,fieldID,val);
2020 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
2022 STATS(jniinvokation();)
2023 setField(obj,jbyte,fieldID,val);
2027 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
2029 STATS(jniinvokation();)
2030 setField(obj,jchar,fieldID,val);
2034 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
2036 STATS(jniinvokation();)
2037 setField(obj,jshort,fieldID,val);
2041 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
2043 STATS(jniinvokation();)
2044 setField(obj,jint,fieldID,val);
2048 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
2050 STATS(jniinvokation();)
2051 setField(obj,jlong,fieldID,val);
2055 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
2057 STATS(jniinvokation();)
2058 setField(obj,jfloat,fieldID,val);
2062 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
2064 STATS(jniinvokation();)
2065 setField(obj,jdouble,fieldID,val);
2069 /**************** JNI-functions for calling static methods **********************/
2071 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2074 STATS(jniinvokation();)
2076 m = class_resolvemethod(clazz,
2077 utf_new_char((char *) name),
2078 utf_new_char((char *) sig));
2080 if (!m || !(m->flags & ACC_STATIC)) {
2082 new_exception_message(string_java_lang_NoSuchMethodError, name);
2091 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2095 STATS(jniinvokation();)
2097 /* log_text("JNI-Call: CallStaticObjectMethod");*/
2099 va_start(vaargs, methodID);
2100 ret = callObjectMethod(0, methodID, vaargs);
2107 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2109 STATS(jniinvokation();)
2110 /* log_text("JNI-Call: CallStaticObjectMethodV"); */
2112 return callObjectMethod(0,methodID,args);
2116 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2118 STATS(jniinvokation();)
2119 log_text("JNI-Call: CallStaticObjectMethodA");
2125 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2129 STATS(jniinvokation();)
2131 va_start(vaargs, methodID);
2132 ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
2139 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2141 STATS(jniinvokation();)
2142 return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
2146 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2148 STATS(jniinvokation();)
2149 log_text("JNI-Call: CallStaticBooleanMethodA");
2155 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2159 STATS(jniinvokation();)
2161 /* log_text("JNI-Call: CallStaticByteMethod");*/
2163 va_start(vaargs, methodID);
2164 ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
2171 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2173 STATS(jniinvokation();)
2174 return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
2178 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2180 STATS(jniinvokation();)
2181 log_text("JNI-Call: CallStaticByteMethodA");
2187 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2191 STATS(jniinvokation();)
2193 /* log_text("JNI-Call: CallStaticByteMethod");*/
2195 va_start(vaargs, methodID);
2196 ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
2203 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2205 STATS(jniinvokation();)
2206 return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
2210 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2212 STATS(jniinvokation();)
2213 log_text("JNI-Call: CallStaticCharMethodA");
2220 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2224 STATS(jniinvokation();)
2226 /* log_text("JNI-Call: CallStaticByteMethod");*/
2228 va_start(vaargs, methodID);
2229 ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
2236 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2238 STATS(jniinvokation();)
2239 /*log_text("JNI-Call: CallStaticShortMethodV");*/
2240 return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
2244 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2246 STATS(jniinvokation();)
2247 log_text("JNI-Call: CallStaticShortMethodA");
2254 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2258 STATS(jniinvokation();)
2260 /* log_text("JNI-Call: CallStaticIntMethod");*/
2262 va_start(vaargs, methodID);
2263 ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
2270 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2272 STATS(jniinvokation();)
2273 log_text("JNI-Call: CallStaticIntMethodV");
2275 return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
2279 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2281 STATS(jniinvokation();)
2282 log_text("JNI-Call: CallStaticIntMethodA");
2289 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2293 STATS(jniinvokation();)
2295 /* log_text("JNI-Call: CallStaticLongMethod");*/
2297 va_start(vaargs, methodID);
2298 ret = callLongMethod(0, methodID, vaargs);
2305 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2307 STATS(jniinvokation();)
2308 log_text("JNI-Call: CallStaticLongMethodV");
2310 return callLongMethod(0,methodID,args);
2314 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2316 STATS(jniinvokation();)
2317 log_text("JNI-Call: CallStaticLongMethodA");
2324 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2328 STATS(jniinvokation();)
2330 /* log_text("JNI-Call: CallStaticLongMethod");*/
2332 va_start(vaargs, methodID);
2333 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
2340 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2342 STATS(jniinvokation();)
2344 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
2349 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2351 STATS(jniinvokation();)
2352 log_text("JNI-Call: CallStaticFloatMethodA");
2359 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2363 STATS(jniinvokation();)
2365 /* log_text("JNI-Call: CallStaticDoubleMethod");*/
2367 va_start(vaargs,methodID);
2368 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
2375 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2377 STATS(jniinvokation();)
2378 log_text("JNI-Call: CallStaticDoubleMethodV");
2380 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
2384 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2386 STATS(jniinvokation();)
2387 log_text("JNI-Call: CallStaticDoubleMethodA");
2393 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2396 STATS(jniinvokation();)
2398 va_start(vaargs, methodID);
2399 (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
2404 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2406 log_text("JNI-Call: CallStaticVoidMethodV");
2407 STATS(jniinvokation();)
2408 (void)callIntegerMethod(0, methodID, TYPE_VOID, args);
2412 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2414 STATS(jniinvokation();)
2415 log_text("JNI-Call: CallStaticVoidMethodA");
2419 /* Accessing Static Fields ****************************************************/
2421 /* GetStaticFieldID ************************************************************
2423 Returns the field ID for a static field of a class. The field is
2424 specified by its name and signature. The GetStatic<type>Field and
2425 SetStatic<type>Field families of accessor functions use field IDs
2426 to retrieve static fields.
2428 *******************************************************************************/
2430 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2433 STATS(jniinvokation();)
2435 f = jclass_findfield(clazz,
2436 utf_new_char((char *) name),
2437 utf_new_char((char *) sig));
2440 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2446 /* GetStatic<type>Field ********************************************************
2448 This family of accessor routines returns the value of a static
2451 *******************************************************************************/
2453 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2455 STATS(jniinvokation();)
2456 JWCLINITDEBUG(printf("GetStaticObjectField: calling initialize_class %s\n",clazz->name->text);)
2457 if (!initialize_class(clazz))
2460 return fieldID->value.a;
2464 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2466 STATS(jniinvokation();)
2467 JWCLINITDEBUG(printf("GetStaticBooleanField: calling initialize_class %s\n",clazz->name->text);)
2469 if (!initialize_class(clazz))
2472 return fieldID->value.i;
2476 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2478 STATS(jniinvokation();)
2479 JWCLINITDEBUG(printf("GetStaticByteField: calling initialize_class %s\n",clazz->name->text);)
2481 if (!initialize_class(clazz))
2484 return fieldID->value.i;
2488 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2490 STATS(jniinvokation();)
2491 JWCLINITDEBUG(printf("GetStaticCharField: calling initialize_class %s\n",clazz->name->text);)
2493 if (!initialize_class(clazz))
2496 return fieldID->value.i;
2500 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2502 STATS(jniinvokation();)
2503 JWCLINITDEBUG(printf("GetStaticShorttField: calling initialize_class %s\n",clazz->name->text);)
2504 if (!initialize_class(clazz))
2507 return fieldID->value.i;
2511 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2513 STATS(jniinvokation();)
2514 JWCLINITDEBUG(printf("GetStaticIntField: calling initialize_class %s\n",clazz->name->text);)
2515 if (!initialize_class(clazz))
2518 return fieldID->value.i;
2522 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2524 STATS(jniinvokation();)
2525 JWCLINITDEBUG(printf("GetStaticLongField: calling initialize_class %s\n",clazz->name->text);)
2526 if (!initialize_class(clazz))
2529 return fieldID->value.l;
2533 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2535 STATS(jniinvokation();)
2536 JWCLINITDEBUG(printf("GetStaticFloatField: calling initialize_class %s\n",clazz->name->text);)
2537 if (!initialize_class(clazz))
2540 return fieldID->value.f;
2544 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2546 STATS(jniinvokation();)
2547 JWCLINITDEBUG(printf("GetStaticDoubleField: calling initialize_class %s\n",clazz->name->text);)
2548 if (!initialize_class(clazz))
2551 return fieldID->value.d;
2555 /* SetStatic<type>Field *******************************************************
2557 This family of accessor routines sets the value of a static field
2560 *******************************************************************************/
2562 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2564 STATS(jniinvokation();)
2565 JWCLINITDEBUG(printf("SetStaticObjectField: calling initialize_class %s\n",clazz->name->text);)
2566 if (!initialize_class(clazz))
2569 fieldID->value.a = value;
2573 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2575 STATS(jniinvokation();)
2576 JWCLINITDEBUG(printf("SetStaticBooleanField: calling initialize_class %s\n",clazz->name->text);)
2577 if (!initialize_class(clazz))
2580 fieldID->value.i = value;
2584 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2586 STATS(jniinvokation();)
2587 JWCLINITDEBUG(printf("SetStaticByteField: calling initialize_class %s\n",clazz->name->text);)
2588 if (!initialize_class(clazz))
2591 fieldID->value.i = value;
2595 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2597 STATS(jniinvokation();)
2598 JWCLINITDEBUG(printf("SetStaticCharField: calling initialize_class %s\n",clazz->name->text);)
2599 if (!initialize_class(clazz))
2602 fieldID->value.i = value;
2606 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2608 STATS(jniinvokation();)
2609 JWCLINITDEBUG(printf("SetStaticShortField: calling initialize_class %s\n",clazz->name->text);)
2610 if (!initialize_class(clazz))
2613 fieldID->value.i = value;
2617 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2619 STATS(jniinvokation();)
2620 JWCLINITDEBUG(printf("SetStaticIntField: calling initialize_class %s\n",clazz->name->text);)
2621 if (!initialize_class(clazz))
2624 fieldID->value.i = value;
2628 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2630 STATS(jniinvokation();)
2631 JWCLINITDEBUG(printf("SetStaticLongField: calling initialize_class %s\n",clazz->name->text);)
2632 if (!initialize_class(clazz))
2635 fieldID->value.l = value;
2639 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2641 STATS(jniinvokation();)
2642 JWCLINITDEBUG(printf("SetStaticFloatField: calling initialize_class %s\n",clazz->name->text);)
2643 if (!initialize_class(clazz))
2646 fieldID->value.f = value;
2650 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2652 STATS(jniinvokation();)
2653 JWCLINITDEBUG(printf("SetStaticDoubleField: calling initialize_class %s\n",clazz->name->text);)
2654 if (!initialize_class(clazz))
2657 fieldID->value.d = value;
2661 /* String Operations **********************************************************/
2663 /* NewString *******************************************************************
2665 Create new java.lang.String object from an array of Unicode
2668 *******************************************************************************/
2670 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
2672 java_lang_String *s;
2676 STATS(jniinvokation();)
2678 s = (java_lang_String *) builtin_new(class_java_lang_String);
2679 a = builtin_newarray_char(len);
2681 /* javastring or characterarray could not be created */
2686 for (i = 0; i < len; i++)
2687 a->data[i] = buf[i];
2697 static jchar emptyStringJ[]={0,0};
2699 /* GetStringLength *************************************************************
2701 Returns the length (the count of Unicode characters) of a Java
2704 *******************************************************************************/
2706 jsize GetStringLength(JNIEnv *env, jstring str)
2708 return ((java_lang_String *) str)->count;
2712 /******************** convertes javastring to u2-array ****************************/
2714 u2 *javastring_tou2(jstring so)
2716 java_lang_String *s;
2721 STATS(jniinvokation();)
2723 s = (java_lang_String *) so;
2733 /* allocate memory */
2735 stringbuffer = MNEW(u2, s->count + 1);
2739 for (i = 0; i < s->count; i++)
2740 stringbuffer[i] = a->data[s->offset + i];
2742 /* terminate string */
2744 stringbuffer[i] = '\0';
2746 return stringbuffer;
2750 /* GetStringChars **************************************************************
2752 Returns a pointer to the array of Unicode characters of the
2753 string. This pointer is valid until ReleaseStringchars() is called.
2755 *******************************************************************************/
2757 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2761 STATS(jniinvokation();)
2763 jc = javastring_tou2(str);
2775 return emptyStringJ;
2779 /* ReleaseStringChars **********************************************************
2781 Informs the VM that the native code no longer needs access to
2782 chars. The chars argument is a pointer obtained from string using
2785 *******************************************************************************/
2787 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2789 STATS(jniinvokation();)
2791 if (chars == emptyStringJ)
2794 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
2798 /* NewStringUTF ****************************************************************
2800 Constructs a new java.lang.String object from an array of UTF-8 characters.
2802 *******************************************************************************/
2804 jstring NewStringUTF(JNIEnv *env, const char *bytes)
2806 STATS(jniinvokation();)
2807 return (jstring) javastring_new(utf_new_char(bytes));
2811 /****************** returns the utf8 length in bytes of a string *******************/
2813 jsize GetStringUTFLength (JNIEnv *env, jstring string)
2815 java_lang_String *s = (java_lang_String*) string;
2816 STATS(jniinvokation();)
2818 return (jsize) u2_utflength(s->value->data, s->count);
2822 /* GetStringUTFChars ***********************************************************
2824 Returns a pointer to an array of UTF-8 characters of the
2825 string. This array is valid until it is released by
2826 ReleaseStringUTFChars().
2828 *******************************************************************************/
2830 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
2833 STATS(jniinvokation();)
2841 u = javastring_toutf((java_lang_String *) string, false);
2850 /* ReleaseStringUTFChars *******************************************************
2852 Informs the VM that the native code no longer needs access to
2853 utf. The utf argument is a pointer derived from string using
2854 GetStringUTFChars().
2856 *******************************************************************************/
2858 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2860 STATS(jniinvokation();)
2862 /* XXX we don't release utf chars right now, perhaps that should be done
2863 later. Since there is always one reference the garbage collector will
2868 /* Array Operations ***********************************************************/
2870 /* GetArrayLength **************************************************************
2872 Returns the number of elements in the array.
2874 *******************************************************************************/
2876 jsize GetArrayLength(JNIEnv *env, jarray array)
2878 STATS(jniinvokation();)
2884 /* NewObjectArray **************************************************************
2886 Constructs a new array holding objects in class elementClass. All
2887 elements are initially set to initialElement.
2889 *******************************************************************************/
2891 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
2893 java_objectarray *oa;
2895 STATS(jniinvokation();)
2898 *exceptionptr = new_negativearraysizeexception();
2902 oa = builtin_anewarray(length, elementClass);
2907 /* set all elements to initialElement */
2909 for (i = 0; i < length; i++)
2910 oa->data[i] = initialElement;
2916 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
2919 STATS(jniinvokation();)
2921 if (index < array->header.size)
2922 j = array->data[index];
2924 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2930 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
2932 STATS(jniinvokation();)
2933 if (index >= array->header.size)
2934 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2937 /* check if the class of value is a subclass of the element class of the array */
2938 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
2939 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
2942 array->data[index] = val;
2948 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
2950 java_booleanarray *j;
2951 STATS(jniinvokation();)
2954 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2958 j = builtin_newarray_boolean(len);
2964 jbyteArray NewByteArray(JNIEnv *env, jsize len)
2967 STATS(jniinvokation();)
2970 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2974 j = builtin_newarray_byte(len);
2980 jcharArray NewCharArray(JNIEnv *env, jsize len)
2983 STATS(jniinvokation();)
2986 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2990 j = builtin_newarray_char(len);
2996 jshortArray NewShortArray(JNIEnv *env, jsize len)
2999 STATS(jniinvokation();)
3002 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
3006 j = builtin_newarray_short(len);
3012 jintArray NewIntArray(JNIEnv *env, jsize len)
3015 STATS(jniinvokation();)
3018 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
3022 j = builtin_newarray_int(len);
3028 jlongArray NewLongArray(JNIEnv *env, jsize len)
3031 STATS(jniinvokation();)
3034 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
3038 j = builtin_newarray_long(len);
3044 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3047 STATS(jniinvokation();)
3050 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
3054 j = builtin_newarray_float(len);
3060 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3062 java_doublearray *j;
3063 STATS(jniinvokation();)
3066 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
3070 j = builtin_newarray_double(len);
3076 /* Get<PrimitiveType>ArrayElements *********************************************
3078 A family of functions that returns the body of the primitive array.
3080 *******************************************************************************/
3082 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3085 STATS(jniinvokation();)
3088 *isCopy = JNI_FALSE;
3094 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3096 STATS(jniinvokation();)
3099 *isCopy = JNI_FALSE;
3105 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3107 STATS(jniinvokation();)
3110 *isCopy = JNI_FALSE;
3116 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3118 STATS(jniinvokation();)
3121 *isCopy = JNI_FALSE;
3127 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3129 STATS(jniinvokation();)
3132 *isCopy = JNI_FALSE;
3138 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3140 STATS(jniinvokation();)
3143 *isCopy = JNI_FALSE;
3149 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3151 STATS(jniinvokation();)
3154 *isCopy = JNI_FALSE;
3160 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3163 STATS(jniinvokation();)
3166 *isCopy = JNI_FALSE;
3172 /* Release<PrimitiveType>ArrayElements *****************************************
3174 A family of functions that informs the VM that the native code no
3175 longer needs access to elems. The elems argument is a pointer
3176 derived from array using the corresponding
3177 Get<PrimitiveType>ArrayElements() function. If necessary, this
3178 function copies back all changes made to elems to the original
3181 *******************************************************************************/
3183 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3184 jboolean *elems, jint mode)
3186 STATS(jniinvokation();)
3188 if (elems != array->data) {
3191 MCOPY(array->data, elems, jboolean, array->header.size);
3194 MCOPY(array->data, elems, jboolean, array->header.size);
3195 /* XXX TWISTI how should it be freed? */
3198 /* XXX TWISTI how should it be freed? */
3205 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
3208 STATS(jniinvokation();)
3210 if (elems != array->data) {
3213 MCOPY(array->data, elems, jboolean, array->header.size);
3216 MCOPY(array->data, elems, jboolean, array->header.size);
3217 /* XXX TWISTI how should it be freed? */
3220 /* XXX TWISTI how should it be freed? */
3227 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
3230 STATS(jniinvokation();)
3232 if (elems != array->data) {
3235 MCOPY(array->data, elems, jboolean, array->header.size);
3238 MCOPY(array->data, elems, jboolean, array->header.size);
3239 /* XXX TWISTI how should it be freed? */
3242 /* XXX TWISTI how should it be freed? */
3249 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
3252 STATS(jniinvokation();)
3254 if (elems != array->data) {
3257 MCOPY(array->data, elems, jboolean, array->header.size);
3260 MCOPY(array->data, elems, jboolean, array->header.size);
3261 /* XXX TWISTI how should it be freed? */
3264 /* XXX TWISTI how should it be freed? */
3271 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
3274 STATS(jniinvokation();)
3276 if (elems != array->data) {
3279 MCOPY(array->data, elems, jboolean, array->header.size);
3282 MCOPY(array->data, elems, jboolean, array->header.size);
3283 /* XXX TWISTI how should it be freed? */
3286 /* XXX TWISTI how should it be freed? */
3293 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
3296 STATS(jniinvokation();)
3298 if (elems != array->data) {
3301 MCOPY(array->data, elems, jboolean, array->header.size);
3304 MCOPY(array->data, elems, jboolean, array->header.size);
3305 /* XXX TWISTI how should it be freed? */
3308 /* XXX TWISTI how should it be freed? */
3315 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
3318 STATS(jniinvokation();)
3320 if (elems != array->data) {
3323 MCOPY(array->data, elems, jboolean, array->header.size);
3326 MCOPY(array->data, elems, jboolean, array->header.size);
3327 /* XXX TWISTI how should it be freed? */
3330 /* XXX TWISTI how should it be freed? */
3337 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3338 jdouble *elems, jint mode)
3340 STATS(jniinvokation();)
3342 if (elems != array->data) {
3345 MCOPY(array->data, elems, jboolean, array->header.size);
3348 MCOPY(array->data, elems, jboolean, array->header.size);
3349 /* XXX TWISTI how should it be freed? */
3352 /* XXX TWISTI how should it be freed? */
3359 /* Get<PrimitiveType>ArrayRegion **********************************************
3361 A family of functions that copies a region of a primitive array
3364 *******************************************************************************/
3366 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3367 jsize len, jboolean *buf)
3369 STATS(jniinvokation();)
3371 if (start < 0 || len < 0 || start + len > array->header.size)
3373 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3376 MCOPY(buf, &array->data[start], jboolean, len);
3380 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3383 STATS(jniinvokation();)
3385 if (start < 0 || len < 0 || start + len > array->header.size)
3387 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3390 MCOPY(buf, &array->data[start], jbyte, len);
3394 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3397 STATS(jniinvokation();)
3399 if (start < 0 || len < 0 || start + len > array->header.size)
3401 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3404 MCOPY(buf, &array->data[start], jchar, len);
3408 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3409 jsize len, jshort *buf)
3411 STATS(jniinvokation();)
3413 if (start < 0 || len < 0 || start + len > array->header.size)
3415 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3418 MCOPY(buf, &array->data[start], jshort, len);
3422 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3425 STATS(jniinvokation();)
3427 if (start < 0 || len < 0 || start + len > array->header.size)
3429 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3432 MCOPY(buf, &array->data[start], jint, len);
3436 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
3439 STATS(jniinvokation();)
3441 if (start < 0 || len < 0 || start + len > array->header.size)
3443 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3446 MCOPY(buf, &array->data[start], jlong, len);
3450 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3451 jsize len, jfloat *buf)
3453 STATS(jniinvokation();)
3455 if (start < 0 || len < 0 || start + len > array->header.size)
3457 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3460 MCOPY(buf, &array->data[start], jfloat, len);
3464 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3465 jsize len, jdouble *buf)
3467 STATS(jniinvokation();)
3469 if (start < 0 || len < 0 || start+len>array->header.size)
3471 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3474 MCOPY(buf, &array->data[start], jdouble, len);
3478 /* Set<PrimitiveType>ArrayRegion **********************************************
3480 A family of functions that copies back a region of a primitive
3481 array from a buffer.
3483 *******************************************************************************/
3485 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3486 jsize len, jboolean *buf)
3488 STATS(jniinvokation();)
3490 if (start < 0 || len < 0 || start + len > array->header.size)
3492 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3495 MCOPY(&array->data[start], buf, jboolean, len);
3499 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3502 STATS(jniinvokation();)
3504 if (start < 0 || len < 0 || start + len > array->header.size)
3506 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3509 MCOPY(&array->data[start], buf, jbyte, len);
3513 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3516 STATS(jniinvokation();)
3518 if (start < 0 || len < 0 || start + len > array->header.size)
3520 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3523 MCOPY(&array->data[start], buf, jchar, len);
3528 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3529 jsize len, jshort *buf)
3531 STATS(jniinvokation();)
3533 if (start < 0 || len < 0 || start + len > array->header.size)
3535 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3538 MCOPY(&array->data[start], buf, jshort, len);
3542 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3545 STATS(jniinvokation();)
3547 if (start < 0 || len < 0 || start + len > array->header.size)
3549 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3552 MCOPY(&array->data[start], buf, jint, len);
3557 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
3560 STATS(jniinvokation();)
3562 if (start < 0 || len < 0 || start + len > array->header.size)
3564 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3567 MCOPY(&array->data[start], buf, jlong, len);
3572 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3573 jsize len, jfloat *buf)
3575 STATS(jniinvokation();)
3577 if (start < 0 || len < 0 || start + len > array->header.size)
3579 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3582 MCOPY(&array->data[start], buf, jfloat, len);
3587 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3588 jsize len, jdouble *buf)
3590 STATS(jniinvokation();)
3592 if (start < 0 || len < 0 || start + len > array->header.size)
3594 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3597 MCOPY(&array->data[start], buf, jdouble, len);
3601 /* Registering Native Methods *************************************************/
3603 /* RegisterNatives *************************************************************
3605 Registers native methods with the class specified by the clazz
3606 argument. The methods parameter specifies an array of
3607 JNINativeMethod structures that contain the names, signatures, and
3608 function pointers of the native methods. The nMethods parameter
3609 specifies the number of native methods in the array.
3611 *******************************************************************************/
3613 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
3616 STATS(jniinvokation();)
3618 log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
3624 /* UnregisterNatives ***********************************************************
3626 Unregisters native methods of a class. The class goes back to the
3627 state before it was linked or registered with its native method
3630 This function should not be used in normal native code. Instead, it
3631 provides special programs a way to reload and relink native
3634 *******************************************************************************/
3636 jint UnregisterNatives(JNIEnv *env, jclass clazz)
3638 STATS(jniinvokation();)
3640 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3642 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3648 /* Monitor Operations *********************************************************/
3650 /* MonitorEnter ****************************************************************
3652 Enters the monitor associated with the underlying Java object
3655 *******************************************************************************/
3657 jint MonitorEnter(JNIEnv *env, jobject obj)
3659 STATS(jniinvokation();)
3661 *exceptionptr = new_nullpointerexception();
3665 #if defined(USE_THREADS)
3666 builtin_monitorenter(obj);
3673 /* MonitorExit *****************************************************************
3675 The current thread must be the owner of the monitor associated with
3676 the underlying Java object referred to by obj. The thread
3677 decrements the counter indicating the number of times it has
3678 entered this monitor. If the value of the counter becomes zero, the
3679 current thread releases the monitor.
3681 *******************************************************************************/
3683 jint MonitorExit(JNIEnv *env, jobject obj)
3685 STATS(jniinvokation();)
3687 *exceptionptr = new_nullpointerexception();
3691 #if defined(USE_THREADS)
3692 builtin_monitorexit(obj);
3699 /* JavaVM Interface ***********************************************************/
3701 /* GetJavaVM *******************************************************************
3703 Returns the Java VM interface (used in the Invocation API)
3704 associated with the current thread. The result is placed at the
3705 location pointed to by the second argument, vm.
3707 *******************************************************************************/
3709 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
3711 STATS(jniinvokation();)
3718 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3720 STATS(jniinvokation();)
3721 log_text("JNI-Call: GetStringRegion");
3725 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3727 STATS(jniinvokation();)
3728 log_text("JNI-Call: GetStringUTFRegion");
3732 /* GetPrimitiveArrayCritical ***************************************************
3734 Obtain a direct pointer to array elements.
3736 *******************************************************************************/
3738 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3740 java_objectheader *s;
3741 arraydescriptor *desc;
3743 STATS(jniinvokation();)
3745 s = (java_objectheader *) array;
3746 desc = s->vftbl->arraydesc;
3752 *isCopy = JNI_FALSE;
3754 /* TODO add to global refs */
3756 return ((u1 *) s) + desc->dataoffset;
3760 /* ReleasePrimitiveArrayCritical ***********************************************
3762 No specific documentation.
3764 *******************************************************************************/
3766 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
3769 STATS(jniinvokation();)
3771 log_text("JNI-Call: ReleasePrimitiveArrayCritical: IMPLEMENT ME!!!");
3773 /* TODO remove from global refs */
3777 /* GetStringCritical ***********************************************************
3779 The semantics of these two functions are similar to the existing
3780 Get/ReleaseStringChars functions.
3782 *******************************************************************************/
3784 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
3786 STATS(jniinvokation();)
3788 return GetStringChars(env, string, isCopy);
3792 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
3794 STATS(jniinvokation();)
3796 ReleaseStringChars(env, string, cstring);
3800 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3802 STATS(jniinvokation();)
3803 log_text("JNI-Call: NewWeakGlobalRef");
3809 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
3811 STATS(jniinvokation();)
3812 log_text("JNI-Call: DeleteWeakGlobalRef");
3818 /** Creates a new global reference to the object referred to by the obj argument **/
3820 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
3825 STATS(jniinvokation();)
3827 MonitorEnter(env, *global_ref_table);
3829 refcount = CallObjectMethod(env, *global_ref_table, getmid, lobj);
3830 val = (refcount == NULL) ? 0 : CallIntMethod(env, refcount, intvalue);
3831 newval = NewObject(env, intclass, newint, val + 1);
3833 if (newval != NULL) {
3834 CallObjectMethod(env, *global_ref_table, putmid, lobj, newval);
3835 MonitorExit(env, *global_ref_table);
3839 log_text("JNI-NewGlobalRef: unable to create new java.lang.Integer");
3840 MonitorExit(env, *global_ref_table);
3845 /************* Deletes the global reference pointed to by globalRef **************/
3847 void DeleteGlobalRef(JNIEnv* env, jobject gref)
3851 STATS(jniinvokation();)
3853 MonitorEnter(env, *global_ref_table);
3854 refcount = CallObjectMethod(env, *global_ref_table, getmid, gref);
3856 if (refcount == NULL) {
3857 log_text("JNI-DeleteGlobalRef: unable to find global reference");
3861 val = CallIntMethod(env, refcount, intvalue);
3865 CallObjectMethod(env, *global_ref_table, removemid,refcount);
3868 jobject newval = NewObject(env, intclass, newint, val);
3870 if (newval != NULL) {
3871 CallObjectMethod(env,*global_ref_table, putmid,newval);
3874 log_text("JNI-DeleteGlobalRef: unable to create new java.lang.Integer");
3878 MonitorExit(env,*global_ref_table);
3882 /* ExceptionCheck **************************************************************
3884 Returns JNI_TRUE when there is a pending exception; otherwise,
3887 *******************************************************************************/
3889 jboolean ExceptionCheck(JNIEnv *env)
3891 STATS(jniinvokation();)
3892 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
3896 /* New JNI 1.4 functions ******************************************************/
3898 /* NewDirectByteBuffer *********************************************************
3900 Allocates and returns a direct java.nio.ByteBuffer referring to the
3901 block of memory starting at the memory address address and
3902 extending capacity bytes.
3904 *******************************************************************************/
3906 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3908 STATS(jniinvokation();)
3909 log_text("NewDirectByteBuffer: IMPLEMENT ME!");
3915 /* GetDirectBufferAddress ******************************************************
3917 Fetches and returns the starting address of the memory region
3918 referenced by the given direct java.nio.Buffer.
3920 *******************************************************************************/
3922 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
3924 STATS(jniinvokation();)
3925 log_text("GetDirectBufferAddress: IMPLEMENT ME!");
3931 /* GetDirectBufferCapacity *****************************************************
3933 Fetches and returns the capacity in bytes of the memory region
3934 referenced by the given direct java.nio.Buffer.
3936 *******************************************************************************/
3938 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3940 STATS(jniinvokation();)
3941 log_text("GetDirectBufferCapacity: IMPLEMENT ME!");
3947 jint DestroyJavaVM(JavaVM *vm)
3949 STATS(jniinvokation();)
3950 log_text("DestroyJavaVM called");
3956 /* AttachCurrentThread *********************************************************
3958 Attaches the current thread to a Java VM. Returns a JNI interface
3959 pointer in the JNIEnv argument.
3961 Trying to attach a thread that is already attached is a no-op.
3963 A native thread cannot be attached simultaneously to two Java VMs.
3965 When a thread is attached to the VM, the context class loader is
3966 the bootstrap loader.
3968 *******************************************************************************/
3970 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
3972 STATS(jniinvokation();)
3974 log_text("AttachCurrentThread called");
3976 #if !defined(HAVE___THREAD)
3977 /* cacao_thread_attach();*/
3979 #error "No idea how to implement that. Perhaps Stefan knows"
3988 jint DetachCurrentThread(JavaVM *vm)
3990 STATS(jniinvokation();)
3991 log_text("DetachCurrentThread called");
3997 /* GetEnv **********************************************************************
3999 If the current thread is not attached to the VM, sets *env to NULL,
4000 and returns JNI_EDETACHED. If the specified version is not
4001 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
4002 sets *env to the appropriate interface, and returns JNI_OK.
4004 *******************************************************************************/
4006 jint GetEnv(JavaVM *vm, void **env, jint version)
4008 STATS(jniinvokation();)
4010 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4011 if (thread_getself() == NULL) {
4013 return JNI_EDETACHED;
4017 if ((version != JNI_VERSION_1_1) && (version != JNI_VERSION_1_2) &&
4018 (version != JNI_VERSION_1_4)) {
4020 return JNI_EVERSION;
4029 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4031 STATS(jniinvokation();)
4032 log_text("AttachCurrentThreadAsDaemon called");
4037 /************* JNI Initialization ****************************************************/
4039 jobject jni_init1(JNIEnv* env, jobject lobj) {
4040 #if defined(USE_THREADS)
4041 while (initrunning) {yieldThread();} /* wait until init is done */
4043 if (global_ref_table == NULL) {
4046 #if defined(USE_THREADS)
4048 /* wait until jni_init is done */
4049 MonitorEnter(env, *global_ref_table) ;
4050 MonitorExit(env, *global_ref_table);
4053 return NewGlobalRef(env, lobj);
4055 void jni_init2(JNIEnv* env, jobject gref) {
4056 log_text("DeleteGlobalref called before NewGlobalref");
4057 #if defined(USE_THREADS)
4058 while (initrunning) {yieldThread();} /* wait until init is done */
4060 if (global_ref_table == NULL) {
4063 #if defined(USE_THREADS)
4065 /* wait until jni_init is done */
4066 MonitorEnter(env, *global_ref_table) ;
4067 MonitorExit(env, *global_ref_table);
4070 DeleteGlobalRef(env, gref);
4080 /* initalize global reference table */
4081 ihmclass = FindClass(NULL, "java/util/IdentityHashMap");
4083 if (ihmclass == NULL) {
4084 log_text("JNI-Init: unable to find java.util.IdentityHashMap");
4087 mid = GetMethodID(NULL, ihmclass, "<init>","()V");
4089 log_text("JNI-Init: unable to find constructor in java.util.IdentityHashMap");
4092 global_ref_table = (jobject*)heap_allocate(sizeof(jobject),true,NULL);
4094 *global_ref_table = NewObject(NULL,ihmclass,mid);
4096 if (*global_ref_table == NULL) {
4097 log_text("JNI-Init: unable to create new global_ref_table");
4100 initrunning = false;
4102 getmid = GetMethodID(NULL, ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
4104 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
4107 getmid = GetMethodID(NULL ,ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
4108 if (getmid == NULL) {
4109 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
4112 putmid = GetMethodID(NULL, ihmclass, "put","(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
4113 if (putmid == NULL) {
4114 log_text("JNI-Init: unable to find method \"put\" in java.util.IdentityHashMap");
4117 intclass = FindClass(NULL, "java/lang/Integer");
4118 if (intclass == NULL) {
4119 log_text("JNI-Init: unable to find java.lang.Integer");
4122 newint = GetMethodID(NULL, intclass, "<init>","(I)V");
4123 if (newint == NULL) {
4124 log_text("JNI-Init: unable to find constructor in java.lang.Integer");
4127 intvalue = GetMethodID(NULL, intclass, "intValue","()I");
4128 if (intvalue == NULL) {
4129 log_text("JNI-Init: unable to find method \"intValue\" in java.lang.Integer");
4132 removemid = GetMethodID(NULL, ihmclass, "remove","(Ljava/lang/Object;)Ljava/lang/Object;");
4133 if (removemid == NULL) {
4134 log_text("JNI-DeleteGlobalRef: unable to find method \"remove\" in java.lang.Object");
4137 /* set NewGlobalRef, DeleteGlobalRef envTable entry to real implementation */
4139 JNI_JNIEnvTable.NewGlobalRef = &NewGlobalRef;
4140 JNI_JNIEnvTable.DeleteGlobalRef = &DeleteGlobalRef;
4144 /* JNI invocation table *******************************************************/
4146 const struct JNIInvokeInterface JNI_JavaVMTable = {
4152 AttachCurrentThread,
4153 DetachCurrentThread,
4155 AttachCurrentThreadAsDaemon
4159 /* JNI function table *********************************************************/
4161 struct JNINativeInterface JNI_JNIEnvTable = {
4170 &FromReflectedMethod,
4171 &FromReflectedField,
4186 &jni_init1, /* &NewGlobalRef, initialize Global_Ref_Table*/
4187 &jni_init2, /* &DeleteGlobalRef,*/
4191 &EnsureLocalCapacity,
4207 &CallBooleanMethodV,
4208 &CallBooleanMethodA,
4234 &CallNonvirtualObjectMethod,
4235 &CallNonvirtualObjectMethodV,
4236 &CallNonvirtualObjectMethodA,
4237 &CallNonvirtualBooleanMethod,
4238 &CallNonvirtualBooleanMethodV,
4239 &CallNonvirtualBooleanMethodA,
4240 &CallNonvirtualByteMethod,
4241 &CallNonvirtualByteMethodV,
4242 &CallNonvirtualByteMethodA,
4243 &CallNonvirtualCharMethod,
4244 &CallNonvirtualCharMethodV,
4245 &CallNonvirtualCharMethodA,
4246 &CallNonvirtualShortMethod,
4247 &CallNonvirtualShortMethodV,
4248 &CallNonvirtualShortMethodA,
4249 &CallNonvirtualIntMethod,
4250 &CallNonvirtualIntMethodV,
4251 &CallNonvirtualIntMethodA,
4252 &CallNonvirtualLongMethod,
4253 &CallNonvirtualLongMethodV,
4254 &CallNonvirtualLongMethodA,
4255 &CallNonvirtualFloatMethod,
4256 &CallNonvirtualFloatMethodV,
4257 &CallNonvirtualFloatMethodA,
4258 &CallNonvirtualDoubleMethod,
4259 &CallNonvirtualDoubleMethodV,
4260 &CallNonvirtualDoubleMethodA,
4261 &CallNonvirtualVoidMethod,
4262 &CallNonvirtualVoidMethodV,
4263 &CallNonvirtualVoidMethodA,
4288 &CallStaticObjectMethod,
4289 &CallStaticObjectMethodV,
4290 &CallStaticObjectMethodA,
4291 &CallStaticBooleanMethod,
4292 &CallStaticBooleanMethodV,
4293 &CallStaticBooleanMethodA,
4294 &CallStaticByteMethod,
4295 &CallStaticByteMethodV,
4296 &CallStaticByteMethodA,
4297 &CallStaticCharMethod,
4298 &CallStaticCharMethodV,
4299 &CallStaticCharMethodA,
4300 &CallStaticShortMethod,
4301 &CallStaticShortMethodV,
4302 &CallStaticShortMethodA,
4303 &CallStaticIntMethod,
4304 &CallStaticIntMethodV,
4305 &CallStaticIntMethodA,
4306 &CallStaticLongMethod,
4307 &CallStaticLongMethodV,
4308 &CallStaticLongMethodA,
4309 &CallStaticFloatMethod,
4310 &CallStaticFloatMethodV,
4311 &CallStaticFloatMethodA,
4312 &CallStaticDoubleMethod,
4313 &CallStaticDoubleMethodV,
4314 &CallStaticDoubleMethodA,
4315 &CallStaticVoidMethod,
4316 &CallStaticVoidMethodV,
4317 &CallStaticVoidMethodA,
4321 &GetStaticObjectField,
4322 &GetStaticBooleanField,
4323 &GetStaticByteField,
4324 &GetStaticCharField,
4325 &GetStaticShortField,
4327 &GetStaticLongField,
4328 &GetStaticFloatField,
4329 &GetStaticDoubleField,
4330 &SetStaticObjectField,
4331 &SetStaticBooleanField,
4332 &SetStaticByteField,
4333 &SetStaticCharField,
4334 &SetStaticShortField,
4336 &SetStaticLongField,
4337 &SetStaticFloatField,
4338 &SetStaticDoubleField,
4343 &ReleaseStringChars,
4346 &GetStringUTFLength,
4348 &ReleaseStringUTFChars,
4353 &GetObjectArrayElement,
4354 &SetObjectArrayElement,
4365 &GetBooleanArrayElements,
4366 &GetByteArrayElements,
4367 &GetCharArrayElements,
4368 &GetShortArrayElements,
4369 &GetIntArrayElements,
4370 &GetLongArrayElements,
4371 &GetFloatArrayElements,
4372 &GetDoubleArrayElements,
4374 &ReleaseBooleanArrayElements,
4375 &ReleaseByteArrayElements,
4376 &ReleaseCharArrayElements,
4377 &ReleaseShortArrayElements,
4378 &ReleaseIntArrayElements,
4379 &ReleaseLongArrayElements,
4380 &ReleaseFloatArrayElements,
4381 &ReleaseDoubleArrayElements,
4383 &GetBooleanArrayRegion,
4384 &GetByteArrayRegion,
4385 &GetCharArrayRegion,
4386 &GetShortArrayRegion,
4388 &GetLongArrayRegion,
4389 &GetFloatArrayRegion,
4390 &GetDoubleArrayRegion,
4391 &SetBooleanArrayRegion,
4392 &SetByteArrayRegion,
4393 &SetCharArrayRegion,
4394 &SetShortArrayRegion,
4396 &SetLongArrayRegion,
4397 &SetFloatArrayRegion,
4398 &SetDoubleArrayRegion,
4408 /* new JNI 1.2 functions */
4411 &GetStringUTFRegion,
4413 &GetPrimitiveArrayCritical,
4414 &ReleasePrimitiveArrayCritical,
4417 &ReleaseStringCritical,
4420 &DeleteWeakGlobalRef,
4424 /* new JNI 1.4 functions */
4426 &NewDirectByteBuffer,
4427 &GetDirectBufferAddress,
4428 &GetDirectBufferCapacity
4432 /* Invocation API Functions ***************************************************/
4434 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4436 Returns a default configuration for the Java VM.
4438 *******************************************************************************/
4440 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4442 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4444 /* GNU classpath currently supports JNI 1.2 */
4446 _vm_args->version = JNI_VERSION_1_2;
4452 /* JNI_GetCreatedJavaVMs *******************************************************
4454 Returns all Java VMs that have been created. Pointers to VMs are written in
4455 the buffer vmBuf in the order they are created. At most bufLen number of
4456 entries will be written. The total number of created VMs is returned in
4459 *******************************************************************************/
4461 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4463 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4469 /* JNI_CreateJavaVM ************************************************************
4471 Loads and initializes a Java VM. The current thread becomes the main thread.
4472 Sets the env argument to the JNI interface pointer of the main thread.
4474 *******************************************************************************/
4476 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4478 *p_vm = (JavaVM *) &JNI_JavaVMTable;
4479 *p_env = (JNIEnv *) &JNI_JNIEnvTable;
4485 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4486 jobject obj, java_objectarray *params)
4492 if (methodID == 0) {
4493 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
4497 argcount = methodID->parseddesc->paramcount;
4499 /* if method is non-static, remove the `this' pointer */
4501 if (!(methodID->flags & ACC_STATIC))
4504 /* the method is an instance method the obj has to be an instance of the
4505 class the method belongs to. For static methods the obj parameter
4508 if (!(methodID->flags & ACC_STATIC) && obj &&
4509 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4511 new_exception_message(string_java_lang_IllegalArgumentException,
4512 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4519 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
4520 log_text("Too many arguments. invokeNativeHelper does not support that");
4525 if (((params == NULL) && (argcount != 0)) ||
4526 (params && (params->header.size != argcount))) {
4528 new_exception(string_java_lang_IllegalArgumentException);
4533 if (!(methodID->flags & ACC_STATIC) && !obj) {
4535 new_exception_message(string_java_lang_NullPointerException,
4536 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4540 if ((methodID->flags & ACC_STATIC) && (obj))
4544 if ((methodID->flags & ACC_ABSTRACT) ||
4545 (methodID->class->flags & ACC_INTERFACE)) {
4546 methodID = get_virtual(obj, methodID);
4550 blk = MNEW(jni_callblock, /*4 */argcount + 2);
4552 if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4556 switch (methodID->parseddesc->returntype.decltype) {
4558 (void) asm_calljavafunction2(methodID, argcount + 1,
4559 (argcount + 1) * sizeof(jni_callblock),
4561 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4564 case PRIMITIVETYPE_INT: {
4566 i = asm_calljavafunction2int(methodID, argcount + 1,
4567 (argcount + 1) * sizeof(jni_callblock),
4570 o = native_new_and_init_int(class_java_lang_Integer, i);
4574 case PRIMITIVETYPE_BYTE: {
4576 i = asm_calljavafunction2int(methodID, argcount + 1,
4577 (argcount + 1) * sizeof(jni_callblock),
4580 /* o = native_new_and_init_int(class_java_lang_Byte, i); */
4581 o = builtin_new(class_java_lang_Byte);
4584 class_resolvemethod(o->vftbl->class,
4591 case PRIMITIVETYPE_CHAR: {
4593 intVal = asm_calljavafunction2int(methodID,
4595 (argcount + 1) * sizeof(jni_callblock),
4597 o = builtin_new(class_java_lang_Character);
4600 class_resolvemethod(o->vftbl->class,
4607 case PRIMITIVETYPE_SHORT: {
4609 intVal = asm_calljavafunction2int(methodID,
4611 (argcount + 1) * sizeof(jni_callblock),
4613 o = builtin_new(class_java_lang_Short);
4616 class_resolvemethod(o->vftbl->class,
4623 case PRIMITIVETYPE_BOOLEAN: {
4625 intVal = asm_calljavafunction2int(methodID,
4627 (argcount + 1) * sizeof(jni_callblock),
4629 o = builtin_new(class_java_lang_Boolean);
4632 class_resolvemethod(o->vftbl->class,
4641 longVal = asm_calljavafunction2long(methodID,
4643 (argcount + 1) * sizeof(jni_callblock),
4645 o = builtin_new(class_java_lang_Long);
4648 class_resolvemethod(o->vftbl->class,
4655 case PRIMITIVETYPE_FLOAT: {
4657 floatVal = asm_calljavafunction2float(methodID,
4659 (argcount + 1) * sizeof(jni_callblock),
4661 o = builtin_new(class_java_lang_Float);
4664 class_resolvemethod(o->vftbl->class,
4671 case PRIMITIVETYPE_DOUBLE: {
4673 doubleVal = asm_calljavafunction2double(methodID,
4675 (argcount + 1) * sizeof(jni_callblock),
4677 o = builtin_new(class_java_lang_Double);
4680 class_resolvemethod(o->vftbl->class,
4688 o = asm_calljavafunction2(methodID, argcount + 1,
4689 (argcount + 1) * sizeof(jni_callblock), blk);
4693 /* if this happens the exception has already been set by */
4694 /* fill_callblock_from_objectarray */
4696 MFREE(blk, jni_callblock, /*4 */ argcount+2);
4697 return (jobject *) 0;
4700 MFREE(blk, jni_callblock, /* 4 */ argcount+2);
4702 if (*exceptionptr) {
4703 java_objectheader *cause;
4705 cause = *exceptionptr;
4707 /* clear exception pointer, we are calling JIT code again */
4709 *exceptionptr = NULL;
4712 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
4713 (java_lang_Throwable *) cause);
4716 return (jobject *) o;
4721 * These are local overrides for various environment variables in Emacs.
4722 * Please do not remove this and leave it at the end of the file, where
4723 * Emacs will automagically detect them.
4724 * ---------------------------------------------------------------------
4727 * indent-tabs-mode: t