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 3066 2005-07-19 12:35:37Z 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(ENABLE_JVMTI)
66 # include "native/jvmti/jvmti.h"
69 #if defined(USE_THREADS)
70 # if defined(NATIVE_THREADS)
71 # include "threads/native/threads.h"
73 # include "threads/green/threads.h"
77 #include "toolbox/logging.h"
78 #include "vm/builtin.h"
79 #include "vm/exceptions.h"
80 #include "vm/global.h"
81 #include "vm/initialize.h"
82 #include "vm/loader.h"
83 #include "vm/options.h"
84 #include "vm/resolve.h"
85 #include "vm/statistics.h"
86 #include "vm/stringlocal.h"
87 #include "vm/tables.h"
88 #include "vm/jit/asmpart.h"
89 #include "vm/jit/jit.h"
90 #include "vm/statistics.h"
93 /* XXX TWISTI hack: define it extern so they can be found in this file */
95 extern const struct JNIInvokeInterface JNI_JavaVMTable;
96 extern struct JNINativeInterface JNI_JNIEnvTable;
98 /* pointers to VM and the environment needed by GetJavaVM and GetEnv */
100 static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
101 void* ptr_env = (void*) &JNI_JNIEnvTable;
104 #define PTR_TO_ITEM(ptr) ((u8)(size_t)(ptr))
106 /* global reference table */
107 static jobject *global_ref_table;
108 static bool initrunning=false;
110 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
111 static jmethodID getmid = NULL;
112 static jmethodID putmid = NULL;
113 static jclass intclass = NULL;
114 static jmethodID intvalue = NULL;
115 static jmethodID newint = NULL;
116 static jclass ihmclass = NULL;
117 static jmethodID removemid = NULL;
119 #define JWCLINITDEBUG(x)
122 /********************* accessing instance-fields **********************************/
124 #define setField(obj,typ,var,val) *((typ*) ((long int) obj + (long int) var->offset))=val;
125 #define getField(obj,typ,var) *((typ*) ((long int) obj + (long int) var->offset))
126 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) \
127 setField(obj, jdatatype, getFieldID_critical(env,clazz,name,sig), val);
130 static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
131 jni_callblock blk[], va_list data,
134 typedesc *paramtypes;
137 paramtypes = descr->paramtypes;
139 /* if method is non-static fill first block and skip `this' pointer */
144 /* the `this' pointer */
145 blk[0].itemtype = TYPE_ADR;
146 blk[0].item = PTR_TO_ITEM(obj);
152 for (; i < descr->paramcount; i++, paramtypes++) {
153 switch (paramtypes->decltype) {
154 /* primitive types */
155 case PRIMITIVETYPE_BYTE:
156 case PRIMITIVETYPE_CHAR:
157 case PRIMITIVETYPE_SHORT:
158 case PRIMITIVETYPE_BOOLEAN:
159 blk[i].itemtype = TYPE_INT;
160 blk[i].item = (s8) va_arg(data, s4);
163 case PRIMITIVETYPE_INT:
164 blk[i].itemtype = TYPE_INT;
165 blk[i].item = (s8) va_arg(data, s4);
168 case PRIMITIVETYPE_LONG:
169 blk[i].itemtype = TYPE_LNG;
170 blk[i].item = (s8) va_arg(data, s8);
173 case PRIMITIVETYPE_FLOAT:
174 blk[i].itemtype = TYPE_FLT;
175 #if defined(__ALPHA__)
176 /* this keeps the assembler function much simpler */
178 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
180 *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
184 case PRIMITIVETYPE_DOUBLE:
185 blk[i].itemtype = TYPE_DBL;
186 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
190 blk[i].itemtype = TYPE_ADR;
191 blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
196 /* The standard doesn't say anything about return value checking, but it */
197 /* appears to be useful. */
199 if (rettype != descr->returntype.decltype)
200 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
204 /* XXX it could be considered if we should do typechecking here in the future */
206 static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
208 java_objectarray *params)
212 typedesc *paramtypes;
217 paramcount = descr->paramcount;
218 paramtypes = descr->paramtypes;
220 /* if method is non-static fill first block and skip `this' pointer */
226 blk[0].itemtype = TYPE_ADR;
227 blk[0].item = PTR_TO_ITEM(obj);
234 for (j = 0; j < paramcount; i++, j++, paramtypes++) {
235 switch (paramtypes->type) {
236 /* primitive types */
241 param = params->data[j];
245 /* internally used data type */
246 blk[i].itemtype = paramtypes->type;
248 /* convert the value according to its declared type */
250 c = param->vftbl->class;
252 switch (paramtypes->decltype) {
253 case PRIMITIVETYPE_BOOLEAN:
254 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
255 blk[i].item = (s8) ((java_lang_Boolean *) param)->value;
260 case PRIMITIVETYPE_BYTE:
261 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
262 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
267 case PRIMITIVETYPE_CHAR:
268 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
269 blk[i].item = (s8) ((java_lang_Character *) param)->value;
274 case PRIMITIVETYPE_SHORT:
275 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
276 blk[i].item = (s8) ((java_lang_Short *) param)->value;
277 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
278 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
283 case PRIMITIVETYPE_INT:
284 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
285 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
286 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
287 blk[i].item = (s8) ((java_lang_Short *) param)->value;
288 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
289 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
294 case PRIMITIVETYPE_LONG:
295 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
296 blk[i].item = (s8) ((java_lang_Long *) param)->value;
297 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
298 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
299 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
300 blk[i].item = (s8) ((java_lang_Short *) param)->value;
301 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
302 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
307 case PRIMITIVETYPE_FLOAT:
308 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
309 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
314 case PRIMITIVETYPE_DOUBLE:
315 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
316 *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Float *) param)->value;
317 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
318 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
325 } /* end declared type switch */
329 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
332 if (params->data[j] != 0) {
333 if (paramtypes->arraydim > 0) {
334 if (!builtin_arrayinstanceof(params->data[j], c->vftbl))
338 if (!builtin_instanceof(params->data[j], c))
342 blk[i].itemtype = TYPE_ADR;
343 blk[i].item = PTR_TO_ITEM(params->data[j]);
348 } /* end param type switch */
350 } /* end param loop */
353 /* *rettype = descr->returntype.decltype; */
358 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
363 static jmethodID get_virtual(jobject obj, jmethodID methodID)
365 if (obj->vftbl->class == methodID->class)
368 return class_resolvemethod(obj->vftbl->class, methodID->name,
369 methodID->descriptor);
373 static jmethodID get_nonvirtual(jclass clazz, jmethodID methodID)
375 if (clazz == methodID->class)
378 /* class_resolvemethod -> classfindmethod? (JOWENN) */
379 return class_resolvemethod(clazz, methodID->name, methodID->descriptor);
383 static jobject callObjectMethod(jobject obj, jmethodID methodID, va_list args)
392 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
396 argcount = methodID->parseddesc->paramcount;
398 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
399 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
400 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
404 if (obj && !builtin_instanceof(obj, methodID->class)) {
405 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
412 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
413 log_text("Too many arguments. CallObjectMethod does not support that");
418 blk = MNEW(jni_callblock, /*4 */argcount+2);
420 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_ADR);
421 /* printf("parameter: obj: %p",blk[0].item); */
422 STATS(jnicallXmethodnvokation();)
423 ret = asm_calljavafunction2(methodID,
425 (argcount + 1) * sizeof(jni_callblock),
427 MFREE(blk, jni_callblock, argcount + 1);
428 /* printf("(CallObjectMethodV)-->%p\n",ret); */
435 core function for integer class methods (bool, byte, short, integer)
436 This is basically needed for i386
438 static jint callIntegerMethod(jobject obj, jmethodID methodID, int retType, va_list args)
444 STATS(jniinvokation();)
447 log_text("JNI-Call: CallObjectMethodV");
448 utf_display(methodID->name);
449 utf_display(methodID->descriptor);
450 printf("\nParmaeter count: %d\n",argcount);
451 utf_display(obj->vftbl->class->name);
455 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
459 argcount = methodID->parseddesc->paramcount;
461 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
462 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
463 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
467 if (obj && !builtin_instanceof(obj, methodID->class)) {
468 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
474 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
475 log_text("Too many arguments. CallIntegerMethod does not support that");
480 blk = MNEW(jni_callblock, /*4 */ argcount+2);
482 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
484 /* printf("parameter: obj: %p",blk[0].item); */
485 STATS(jnicallXmethodnvokation();)
486 ret = asm_calljavafunction2int(methodID,
488 (argcount + 1) * sizeof(jni_callblock),
491 MFREE(blk, jni_callblock, argcount + 1);
492 /* printf("(CallObjectMethodV)-->%p\n",ret); */
498 /*core function for long class functions*/
499 static jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
505 STATS(jniinvokation();)
508 log_text("JNI-Call: CallObjectMethodV");
509 utf_display(methodID->name);
510 utf_display(methodID->descriptor);
511 printf("\nParmaeter count: %d\n",argcount);
512 utf_display(obj->vftbl->class->name);
516 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
520 argcount = methodID->parseddesc->paramcount;
522 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
523 ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
524 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
528 if (obj && !builtin_instanceof(obj,methodID->class)) {
529 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
535 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
536 log_text("Too many arguments. CallObjectMethod does not support that");
541 blk = MNEW(jni_callblock,/* 4 */argcount+2);
543 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_LNG);
545 /* printf("parameter: obj: %p",blk[0].item); */
546 STATS(jnicallXmethodnvokation();)
547 ret = asm_calljavafunction2long(methodID,
549 (argcount + 1) * sizeof(jni_callblock),
552 MFREE(blk, jni_callblock, argcount + 1);
553 /* printf("(CallObjectMethodV)-->%p\n",ret); */
559 /*core function for float class methods (float,double)*/
560 static jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,int retType)
562 int argcount = methodID->parseddesc->paramcount;
566 STATS(jniinvokation();)
569 log_text("JNI-Call: CallObjectMethodV");
570 utf_display(methodID->name);
571 utf_display(methodID->descriptor);
572 printf("\nParmaeter count: %d\n",argcount);
573 utf_display(obj->vftbl->class->name);
579 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
580 log_text("Too many arguments. CallObjectMethod does not support that");
585 blk = MNEW(jni_callblock, /*4 */ argcount+2);
587 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
589 /* printf("parameter: obj: %p",blk[0].item); */
590 STATS(jnicallXmethodnvokation();)
591 ret = asm_calljavafunction2double(methodID,
593 (argcount + 1) * sizeof(jni_callblock),
596 MFREE(blk, jni_callblock, argcount + 1);
597 /* printf("(CallObjectMethodV)-->%p\n",ret); */
603 /*************************** function: jclass_findfield ****************************
605 searches for field with specified name and type in a 'classinfo'-structur
606 if no such field is found NULL is returned
608 ************************************************************************************/
610 static fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
613 STATS(jniinvokation();)
615 /* printf(" FieldCount: %d\n",c->fieldscount);
616 utf_display(c->name); */
617 for (i = 0; i < c->fieldscount; i++) {
618 /* utf_display(c->fields[i].name);
620 utf_display(c->fields[i].descriptor);
622 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
623 return &(c->fields[i]);
626 if (c->super.cls) return jclass_findfield(c->super.cls,name,desc);
632 /* GetVersion ******************************************************************
634 Returns the major version number in the higher 16 bits and the
635 minor version number in the lower 16 bits.
637 *******************************************************************************/
639 jint GetVersion(JNIEnv *env)
641 STATS(jniinvokation();)
643 /* just say we support JNI 1.4 */
645 return JNI_VERSION_1_4;
649 /* Class Operations ***********************************************************/
651 /* DefineClass *****************************************************************
653 Loads a class from a buffer of raw class data. The buffer
654 containing the raw class data is not referenced by the VM after the
655 DefineClass call returns, and it may be discarded if desired.
657 *******************************************************************************/
659 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
660 const jbyte *buf, jsize bufLen)
662 java_lang_ClassLoader *cl;
667 STATS(jniinvokation();)
669 cl = (java_lang_ClassLoader *) loader;
670 s = javastring_new_char(name);
671 ba = (java_bytearray *) buf;
673 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
680 /* FindClass *******************************************************************
682 This function loads a locally-defined class. It searches the
683 directories and zip files specified by the CLASSPATH environment
684 variable for the class with the specified name.
686 *******************************************************************************/
688 jclass FindClass(JNIEnv *env, const char *name)
692 java_objectheader *cl;
694 STATS(jniinvokation();)
696 u = utf_new_char_classname((char *) name);
698 /* check stacktrace for classloader, if one found use it, otherwise use */
699 /* the system classloader */
701 #if defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__)
702 cl = cacao_currentClassLoader();
707 if (!(c = load_class_from_classloader(u, cl)))
713 use_class_as_object(c);
719 /* FromReflectedMethod *********************************************************
721 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
722 object to a method ID.
724 *******************************************************************************/
726 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
732 STATS(jniinvokation();)
737 if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
738 java_lang_reflect_Method *rm;
740 rm = (java_lang_reflect_Method *) method;
741 c = (classinfo *) (rm->declaringClass);
744 } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
745 java_lang_reflect_Constructor *rc;
747 rc = (java_lang_reflect_Constructor *) method;
748 c = (classinfo *) (rc->clazz);
754 if ((slot < 0) || (slot >= c->methodscount)) {
755 /* this usually means a severe internal cacao error or somebody
756 tempered around with the reflected method */
757 log_text("error illegal slot for method in class(FromReflectedMethod)");
761 mi = &(c->methods[slot]);
767 /* GetSuperclass ***************************************************************
769 If clazz represents any class other than the class Object, then
770 this function returns the object that represents the superclass of
771 the class specified by clazz.
773 *******************************************************************************/
775 jclass GetSuperclass(JNIEnv *env, jclass sub)
778 STATS(jniinvokation();)
780 c = ((classinfo *) sub)->super.cls;
785 use_class_as_object(c);
791 /* IsAssignableFrom ************************************************************
793 Determines whether an object of sub can be safely cast to sup.
795 *******************************************************************************/
797 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
799 STATS(jniinvokation();)
800 return Java_java_lang_VMClass_isAssignableFrom(env,
802 (java_lang_Class *) sup,
803 (java_lang_Class *) sub);
807 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
809 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
811 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!!!");
812 STATS(jniinvokation();)
817 /* Throw ***********************************************************************
819 Causes a java.lang.Throwable object to be thrown.
821 *******************************************************************************/
823 jint Throw(JNIEnv *env, jthrowable obj)
825 *exceptionptr = (java_objectheader *) obj;
826 STATS(jniinvokation();)
832 /* ThrowNew ********************************************************************
834 Constructs an exception object from the specified class with the
835 message specified by message and causes that exception to be
838 *******************************************************************************/
840 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
842 java_lang_Throwable *o;
844 STATS(jniinvokation();)
846 s = (java_lang_String *) javastring_new_char(msg);
848 /* instantiate exception object */
850 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
856 *exceptionptr = (java_objectheader *) o;
862 /* ExceptionOccurred ***********************************************************
864 Determines if an exception is being thrown. The exception stays
865 being thrown until either the native code calls ExceptionClear(),
866 or the Java code handles the exception.
868 *******************************************************************************/
870 jthrowable ExceptionOccurred(JNIEnv *env)
872 STATS(jniinvokation();)
873 return (jthrowable) *exceptionptr;
877 /* ExceptionDescribe ***********************************************************
879 Prints an exception and a backtrace of the stack to a system
880 error-reporting channel, such as stderr. This is a convenience
881 routine provided for debugging.
883 *******************************************************************************/
885 void ExceptionDescribe(JNIEnv *env)
887 java_objectheader *e;
889 STATS(jniinvokation();)
894 /* clear exception, because we are calling jit code again */
896 *exceptionptr = NULL;
898 /* get printStackTrace method from exception class */
900 m = class_resolveclassmethod(e->vftbl->class,
907 /* XXX what should we do? */
910 /* print the stacktrace */
912 asm_calljavafunction(m, e, NULL, NULL, NULL);
917 /* ExceptionClear **************************************************************
919 Clears any exception that is currently being thrown. If no
920 exception is currently being thrown, this routine has no effect.
922 *******************************************************************************/
924 void ExceptionClear(JNIEnv *env)
926 STATS(jniinvokation();)
927 *exceptionptr = NULL;
931 /* FatalError ******************************************************************
933 Raises a fatal error and does not expect the VM to recover. This
934 function does not return.
936 *******************************************************************************/
938 void FatalError(JNIEnv *env, const char *msg)
940 STATS(jniinvokation();)
941 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
945 /******************* creates a new local reference frame **************************/
947 jint PushLocalFrame(JNIEnv* env, jint capacity)
949 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
950 STATS(jniinvokation();)
955 /**************** Pops off the current local reference frame **********************/
957 jobject PopLocalFrame(JNIEnv* env, jobject result)
959 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
960 STATS(jniinvokation();)
966 /* DeleteLocalRef **************************************************************
968 Deletes the local reference pointed to by localRef.
970 *******************************************************************************/
972 void DeleteLocalRef(JNIEnv *env, jobject localRef)
974 STATS(jniinvokation();)
976 log_text("JNI-Call: DeleteLocalRef: IMPLEMENT ME!");
980 /* IsSameObject ****************************************************************
982 Tests whether two references refer to the same Java object.
984 *******************************************************************************/
986 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
988 STATS(jniinvokation();)
989 return (ref1 == ref2);
993 /* NewLocalRef *****************************************************************
995 Creates a new local reference that refers to the same object as ref.
997 *******************************************************************************/
999 jobject NewLocalRef(JNIEnv *env, jobject ref)
1001 log_text("JNI-Call: NewLocalRef: IMPLEMENT ME!");
1002 STATS(jniinvokation();)
1006 /***********************************************************************************
1008 Ensures that at least a given number of local references can
1009 be created in the current thread
1011 **********************************************************************************/
1013 jint EnsureLocalCapacity (JNIEnv* env, jint capacity)
1015 STATS(jniinvokation();)
1016 return 0; /* return 0 on success */
1020 /* AllocObject *****************************************************************
1022 Allocates a new Java object without invoking any of the
1023 constructors for the object. Returns a reference to the object.
1025 *******************************************************************************/
1027 jobject AllocObject(JNIEnv *env, jclass clazz)
1029 java_objectheader *o;
1030 STATS(jniinvokation();)
1032 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1034 new_exception_utfmessage(string_java_lang_InstantiationException,
1039 o = builtin_new(clazz);
1045 /* NewObject *******************************************************************
1047 Constructs a new Java object. The method ID indicates which
1048 constructor method to invoke. This ID must be obtained by calling
1049 GetMethodID() with <init> as the method name and void (V) as the
1052 *******************************************************************************/
1054 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1056 java_objectheader *o;
1058 int argcount=methodID->parseddesc->paramcount;
1061 STATS(jniinvokation();)
1065 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
1066 log_text("Too many arguments. NewObject does not support that");
1073 o = builtin_new(clazz);
1078 va_start(vaargs, methodID);
1079 for (i = 0; i < argcount; i++) {
1080 args[i] = va_arg(vaargs, void*);
1084 /* call constructor */
1086 asm_calljavafunction(methodID, o, args[0], args[1], args[2]);
1092 /***********************************************************************************
1094 Constructs a new Java object
1095 arguments that are to be passed to the constructor are placed in va_list args
1097 ***********************************************************************************/
1099 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1101 log_text("JNI-Call: NewObjectV");
1102 STATS(jniinvokation();)
1108 /***********************************************************************************
1110 Constructs a new Java object
1111 arguments that are to be passed to the constructor are placed in
1112 args array of jvalues
1114 ***********************************************************************************/
1116 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1118 log_text("JNI-Call: NewObjectA");
1119 STATS(jniinvokation();)
1125 /* GetObjectClass **************************************************************
1127 Returns the class of an object.
1129 *******************************************************************************/
1131 jclass GetObjectClass(JNIEnv *env, jobject obj)
1134 STATS(jniinvokation();)
1136 if (!obj || !obj->vftbl)
1139 c = obj->vftbl->class;
1140 use_class_as_object(c);
1145 /* IsInstanceOf ****************************************************************
1147 Tests whether an object is an instance of a class.
1149 *******************************************************************************/
1151 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1153 STATS(jniinvokation();)
1155 return Java_java_lang_VMClass_isInstance(env,
1157 (java_lang_Class *) clazz,
1158 (java_lang_Object *) obj);
1162 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1164 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1166 java_lang_reflect_Field *f;
1168 jfieldID fid; /* the JNI-fieldid of the wrapping object */
1169 STATS(jniinvokation();)
1170 /*log_text("JNI-Call: FromReflectedField");*/
1172 f=(java_lang_reflect_Field *)field;
1174 c=(classinfo*)(f->declaringClass);
1175 if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1176 /*this usually means a severe internal cacao error or somebody
1177 tempered around with the reflected method*/
1178 log_text("error illegal slot for field in class(FromReflectedField)");
1181 fid=&(c->fields[f->slot]);
1186 /**********************************************************************************
1188 converts a method ID to a java.lang.reflect.Method or
1189 java.lang.reflect.Constructor object
1191 **********************************************************************************/
1193 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1195 log_text("JNI-Call: ToReflectedMethod");
1196 STATS(jniinvokation();)
1202 /* GetMethodID *****************************************************************
1204 returns the method ID for an instance method
1206 *******************************************************************************/
1208 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1211 STATS(jniinvokation();)
1213 m = class_resolvemethod(clazz,
1214 utf_new_char((char *) name),
1215 utf_new_char((char *) sig));
1217 if (!m || (m->flags & ACC_STATIC)) {
1219 new_exception_message(string_java_lang_NoSuchMethodError, name);
1228 /******************** JNI-functions for calling instance methods ******************/
1230 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1234 STATS(jniinvokation();)
1236 /* log_text("JNI-Call: CallObjectMethod");*/
1238 va_start(vaargs, methodID);
1239 ret = callObjectMethod(obj, methodID, vaargs);
1246 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1248 STATS(jniinvokation();)
1249 return callObjectMethod(obj,methodID,args);
1253 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1255 log_text("JNI-Call: CallObjectMethodA");
1256 STATS(jniinvokation();)
1264 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1268 STATS(jniinvokation();)
1270 /* log_text("JNI-Call: CallBooleanMethod");*/
1272 va_start(vaargs,methodID);
1273 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1279 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1281 STATS(jniinvokation();)
1283 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
1287 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1289 STATS(jniinvokation();)
1290 log_text("JNI-Call: CallBooleanMethodA");
1295 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1299 STATS(jniinvokation();)
1301 /* log_text("JNI-Call: CallVyteMethod");*/
1303 va_start(vaargs,methodID);
1304 ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
1310 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1312 /* log_text("JNI-Call: CallByteMethodV");*/
1313 STATS(jniinvokation();)
1315 return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
1319 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1321 log_text("JNI-Call: CallByteMethodA");
1322 STATS(jniinvokation();)
1328 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1332 STATS(jniinvokation();)
1334 /* log_text("JNI-Call: CallCharMethod");*/
1336 va_start(vaargs,methodID);
1337 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
1344 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1346 STATS(jniinvokation();)
1348 /* log_text("JNI-Call: CallCharMethodV");*/
1349 return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
1353 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1355 STATS(jniinvokation();)
1357 log_text("JNI-Call: CallCharMethodA");
1363 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1367 STATS(jniinvokation();)
1369 /* log_text("JNI-Call: CallShortMethod");*/
1371 va_start(vaargs, methodID);
1372 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
1379 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1381 STATS(jniinvokation();)
1382 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
1386 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1388 STATS(jniinvokation();)
1389 log_text("JNI-Call: CallShortMethodA");
1396 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1400 STATS(jniinvokation();)
1402 va_start(vaargs,methodID);
1403 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
1410 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1412 STATS(jniinvokation();)
1413 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
1417 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1419 STATS(jniinvokation();)
1420 log_text("JNI-Call: CallIntMethodA");
1427 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1431 STATS(jniinvokation();)
1433 va_start(vaargs,methodID);
1434 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1441 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1443 STATS(jniinvokation();)
1444 return callLongMethod(obj,get_virtual(obj, methodID),args);
1448 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1450 STATS(jniinvokation();)
1451 log_text("JNI-Call: CallLongMethodA");
1458 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1463 STATS(jniinvokation();)
1464 /* log_text("JNI-Call: CallFloatMethod");*/
1466 va_start(vaargs,methodID);
1467 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
1474 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1476 STATS(jniinvokation();)
1477 log_text("JNI-Call: CallFloatMethodV");
1478 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
1482 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1484 STATS(jniinvokation();)
1485 log_text("JNI-Call: CallFloatMethodA");
1492 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1496 STATS(jniinvokation();)
1498 /* log_text("JNI-Call: CallDoubleMethod");*/
1500 va_start(vaargs,methodID);
1501 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
1508 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1510 STATS(jniinvokation();)
1511 log_text("JNI-Call: CallDoubleMethodV");
1512 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
1516 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1518 STATS(jniinvokation();)
1519 log_text("JNI-Call: CallDoubleMethodA");
1525 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1528 STATS(jniinvokation();)
1530 va_start(vaargs,methodID);
1531 (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
1536 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1538 log_text("JNI-Call: CallVoidMethodV");
1539 STATS(jniinvokation();)
1540 (void)callIntegerMethod(obj,get_virtual(obj,methodID),TYPE_VOID,args);
1544 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1546 STATS(jniinvokation();)
1547 log_text("JNI-Call: CallVoidMethodA");
1552 jobject CallNonvirtualObjectMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1554 STATS(jniinvokation();)
1555 log_text("JNI-Call: CallNonvirtualObjectMethod");
1561 jobject CallNonvirtualObjectMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1563 STATS(jniinvokation();)
1564 log_text("JNI-Call: CallNonvirtualObjectMethodV");
1570 jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1572 STATS(jniinvokation();)
1573 log_text("JNI-Call: CallNonvirtualObjectMethodA");
1580 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1584 STATS(jniinvokation();)
1586 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1588 va_start(vaargs,methodID);
1589 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1596 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1598 STATS(jniinvokation();)
1599 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1600 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
1604 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1606 STATS(jniinvokation();)
1607 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1614 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1619 STATS(jniinvokation();)
1620 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1622 va_start(vaargs,methodID);
1623 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
1629 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1631 STATS(jniinvokation();)
1632 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1633 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
1638 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1640 STATS(jniinvokation();)
1641 log_text("JNI-Call: CallNonvirtualByteMethodA");
1648 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1653 STATS(jniinvokation();)
1654 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1656 va_start(vaargs,methodID);
1657 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
1663 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1665 STATS(jniinvokation();)
1666 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1667 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
1671 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1673 STATS(jniinvokation();)
1674 log_text("JNI-Call: CallNonvirtualCharMethodA");
1681 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1685 STATS(jniinvokation();)
1687 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1689 va_start(vaargs,methodID);
1690 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
1696 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1698 STATS(jniinvokation();)
1699 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1700 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
1704 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1706 STATS(jniinvokation();)
1707 log_text("JNI-Call: CallNonvirtualShortMethodA");
1714 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1719 STATS(jniinvokation();)
1721 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1723 va_start(vaargs,methodID);
1724 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
1730 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1732 STATS(jniinvokation();)
1733 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1734 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
1738 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1740 STATS(jniinvokation();)
1741 log_text("JNI-Call: CallNonvirtualIntMethodA");
1748 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1750 STATS(jniinvokation();)
1751 log_text("JNI-Call: CallNonvirtualLongMethod");
1757 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1759 STATS(jniinvokation();)
1760 log_text("JNI-Call: CallNonvirtualLongMethodV");
1766 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1768 STATS(jniinvokation();)
1769 log_text("JNI-Call: CallNonvirtualLongMethodA");
1776 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1780 STATS(jniinvokation();)
1782 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1785 va_start(vaargs,methodID);
1786 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
1793 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1795 STATS(jniinvokation();)
1796 log_text("JNI-Call: CallNonvirtualFloatMethodV");
1797 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
1801 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1803 STATS(jniinvokation();)
1804 log_text("JNI-Call: CallNonvirtualFloatMethodA");
1811 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1815 STATS(jniinvokation();)
1816 log_text("JNI-Call: CallNonvirtualDoubleMethod");
1818 va_start(vaargs,methodID);
1819 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
1826 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1828 STATS(jniinvokation();)
1829 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
1830 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
1834 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1836 STATS(jniinvokation();)
1837 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
1844 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1847 STATS(jniinvokation();)
1849 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
1851 va_start(vaargs,methodID);
1852 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
1858 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1860 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
1861 STATS(jniinvokation();)
1863 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
1868 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1870 STATS(jniinvokation();)
1871 log_text("JNI-Call: CallNonvirtualVoidMethodA");
1874 /************************* JNI-functions for accessing fields ************************/
1876 jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
1880 STATS(jniinvokation();)
1882 /* log_text("========================= searching for:");
1885 f = jclass_findfield(clazz,
1886 utf_new_char ((char*) name),
1887 utf_new_char ((char*) sig)
1891 /*utf_display(clazz->name);
1894 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
1899 /*************************** retrieve fieldid, abort on error ************************/
1901 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
1903 jfieldID id = GetFieldID(env, clazz, name, sig);
1904 STATS(jniinvokation();)
1908 utf_display(clazz->name);
1909 log_text("\nfield:");
1914 log_text("setfield_critical failed");
1920 jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
1923 jobject dbg,dretval,*dpretval;
1924 long int dli1, dli2, dli3;
1926 printf("GetObjectField(1): thread: %s obj: %p name: %s desc: %s \n",GetStringUTFChars(env,
1927 ((threadobject *) THREADOBJECT)->o
1929 ,obj,((fieldinfo*)fieldID)->name->text,(fieldID->descriptor)->text);
1931 dbg = getField(obj,jobject,fieldID);
1932 dli1 = (long int) obj;
1933 dli2 = (long int) fieldID->offset;
1935 dpretval = (jobject*) dli3;
1936 dretval = *dpretval;
1941 tmp = FindClass(env, "java/lang/Object");
1942 mid = GetMethodID(env,tmp,"toString","()Ljava/lang/String;");
1943 jstr = CallObjectMethod(env,dbg,mid);*/
1945 /* printf("GetObjectField(2): retval %p (obj: %#lx + offset: %#lx = %#lx (jobject*) %p (jobject) %p\n"
1946 ,dbg, dli1, dli2, dli3,dpretval, dretval);*/
1950 STATS(jniinvokation();)
1952 return getField(obj,jobject,fieldID);
1955 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
1957 STATS(jniinvokation();)
1958 return getField(obj,jboolean,fieldID);
1962 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
1964 STATS(jniinvokation();)
1965 return getField(obj,jbyte,fieldID);
1969 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
1971 STATS(jniinvokation();)
1972 return getField(obj,jchar,fieldID);
1976 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
1978 STATS(jniinvokation();)
1979 return getField(obj,jshort,fieldID);
1983 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
1985 STATS(jniinvokation();)
1986 return getField(obj,jint,fieldID);
1990 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
1992 STATS(jniinvokation();)
1993 return getField(obj,jlong,fieldID);
1997 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
1999 STATS(jniinvokation();)
2000 return getField(obj,jfloat,fieldID);
2004 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
2006 STATS(jniinvokation();)
2007 return getField(obj,jdouble,fieldID);
2010 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
2012 STATS(jniinvokation();)
2013 setField(obj,jobject,fieldID,val);
2017 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
2019 STATS(jniinvokation();)
2020 setField(obj,jboolean,fieldID,val);
2024 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
2026 STATS(jniinvokation();)
2027 setField(obj,jbyte,fieldID,val);
2031 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
2033 STATS(jniinvokation();)
2034 setField(obj,jchar,fieldID,val);
2038 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
2040 STATS(jniinvokation();)
2041 setField(obj,jshort,fieldID,val);
2045 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
2047 STATS(jniinvokation();)
2048 setField(obj,jint,fieldID,val);
2052 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
2054 STATS(jniinvokation();)
2055 setField(obj,jlong,fieldID,val);
2059 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
2061 STATS(jniinvokation();)
2062 setField(obj,jfloat,fieldID,val);
2066 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
2068 STATS(jniinvokation();)
2069 setField(obj,jdouble,fieldID,val);
2073 /**************** JNI-functions for calling static methods **********************/
2075 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2078 STATS(jniinvokation();)
2080 m = class_resolvemethod(clazz,
2081 utf_new_char((char *) name),
2082 utf_new_char((char *) sig));
2084 if (!m || !(m->flags & ACC_STATIC)) {
2086 new_exception_message(string_java_lang_NoSuchMethodError, name);
2095 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2099 STATS(jniinvokation();)
2101 /* log_text("JNI-Call: CallStaticObjectMethod");*/
2103 va_start(vaargs, methodID);
2104 ret = callObjectMethod(0, methodID, vaargs);
2111 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2113 STATS(jniinvokation();)
2114 /* log_text("JNI-Call: CallStaticObjectMethodV"); */
2116 return callObjectMethod(0,methodID,args);
2120 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2122 STATS(jniinvokation();)
2123 log_text("JNI-Call: CallStaticObjectMethodA");
2129 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2133 STATS(jniinvokation();)
2135 va_start(vaargs, methodID);
2136 ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
2143 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2145 STATS(jniinvokation();)
2146 return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
2150 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2152 STATS(jniinvokation();)
2153 log_text("JNI-Call: CallStaticBooleanMethodA");
2159 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2163 STATS(jniinvokation();)
2165 /* log_text("JNI-Call: CallStaticByteMethod");*/
2167 va_start(vaargs, methodID);
2168 ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
2175 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2177 STATS(jniinvokation();)
2178 return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
2182 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2184 STATS(jniinvokation();)
2185 log_text("JNI-Call: CallStaticByteMethodA");
2191 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2195 STATS(jniinvokation();)
2197 /* log_text("JNI-Call: CallStaticByteMethod");*/
2199 va_start(vaargs, methodID);
2200 ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
2207 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2209 STATS(jniinvokation();)
2210 return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
2214 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2216 STATS(jniinvokation();)
2217 log_text("JNI-Call: CallStaticCharMethodA");
2224 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2228 STATS(jniinvokation();)
2230 /* log_text("JNI-Call: CallStaticByteMethod");*/
2232 va_start(vaargs, methodID);
2233 ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
2240 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2242 STATS(jniinvokation();)
2243 /*log_text("JNI-Call: CallStaticShortMethodV");*/
2244 return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
2248 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2250 STATS(jniinvokation();)
2251 log_text("JNI-Call: CallStaticShortMethodA");
2258 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2262 STATS(jniinvokation();)
2264 /* log_text("JNI-Call: CallStaticIntMethod");*/
2266 va_start(vaargs, methodID);
2267 ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
2274 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2276 STATS(jniinvokation();)
2277 log_text("JNI-Call: CallStaticIntMethodV");
2279 return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
2283 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2285 STATS(jniinvokation();)
2286 log_text("JNI-Call: CallStaticIntMethodA");
2293 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2297 STATS(jniinvokation();)
2299 /* log_text("JNI-Call: CallStaticLongMethod");*/
2301 va_start(vaargs, methodID);
2302 ret = callLongMethod(0, methodID, vaargs);
2309 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2311 STATS(jniinvokation();)
2312 log_text("JNI-Call: CallStaticLongMethodV");
2314 return callLongMethod(0,methodID,args);
2318 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2320 STATS(jniinvokation();)
2321 log_text("JNI-Call: CallStaticLongMethodA");
2328 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2332 STATS(jniinvokation();)
2334 /* log_text("JNI-Call: CallStaticLongMethod");*/
2336 va_start(vaargs, methodID);
2337 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
2344 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2346 STATS(jniinvokation();)
2348 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
2353 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2355 STATS(jniinvokation();)
2356 log_text("JNI-Call: CallStaticFloatMethodA");
2363 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2367 STATS(jniinvokation();)
2369 /* log_text("JNI-Call: CallStaticDoubleMethod");*/
2371 va_start(vaargs,methodID);
2372 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
2379 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2381 STATS(jniinvokation();)
2382 log_text("JNI-Call: CallStaticDoubleMethodV");
2384 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
2388 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2390 STATS(jniinvokation();)
2391 log_text("JNI-Call: CallStaticDoubleMethodA");
2397 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2400 STATS(jniinvokation();)
2402 va_start(vaargs, methodID);
2403 (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
2408 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2410 log_text("JNI-Call: CallStaticVoidMethodV");
2411 STATS(jniinvokation();)
2412 (void)callIntegerMethod(0, methodID, TYPE_VOID, args);
2416 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2418 STATS(jniinvokation();)
2419 log_text("JNI-Call: CallStaticVoidMethodA");
2423 /* Accessing Static Fields ****************************************************/
2425 /* GetStaticFieldID ************************************************************
2427 Returns the field ID for a static field of a class. The field is
2428 specified by its name and signature. The GetStatic<type>Field and
2429 SetStatic<type>Field families of accessor functions use field IDs
2430 to retrieve static fields.
2432 *******************************************************************************/
2434 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2437 STATS(jniinvokation();)
2439 f = jclass_findfield(clazz,
2440 utf_new_char((char *) name),
2441 utf_new_char((char *) sig));
2444 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2450 /* GetStatic<type>Field ********************************************************
2452 This family of accessor routines returns the value of a static
2455 *******************************************************************************/
2457 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2459 STATS(jniinvokation();)
2460 JWCLINITDEBUG(printf("GetStaticObjectField: calling initialize_class %s\n",clazz->name->text);)
2461 if (!initialize_class(clazz))
2464 return fieldID->value.a;
2468 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2470 STATS(jniinvokation();)
2471 JWCLINITDEBUG(printf("GetStaticBooleanField: calling initialize_class %s\n",clazz->name->text);)
2473 if (!initialize_class(clazz))
2476 return fieldID->value.i;
2480 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2482 STATS(jniinvokation();)
2483 JWCLINITDEBUG(printf("GetStaticByteField: calling initialize_class %s\n",clazz->name->text);)
2485 if (!initialize_class(clazz))
2488 return fieldID->value.i;
2492 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2494 STATS(jniinvokation();)
2495 JWCLINITDEBUG(printf("GetStaticCharField: calling initialize_class %s\n",clazz->name->text);)
2497 if (!initialize_class(clazz))
2500 return fieldID->value.i;
2504 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2506 STATS(jniinvokation();)
2507 JWCLINITDEBUG(printf("GetStaticShorttField: calling initialize_class %s\n",clazz->name->text);)
2508 if (!initialize_class(clazz))
2511 return fieldID->value.i;
2515 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2517 STATS(jniinvokation();)
2518 JWCLINITDEBUG(printf("GetStaticIntField: calling initialize_class %s\n",clazz->name->text);)
2519 if (!initialize_class(clazz))
2522 return fieldID->value.i;
2526 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2528 STATS(jniinvokation();)
2529 JWCLINITDEBUG(printf("GetStaticLongField: calling initialize_class %s\n",clazz->name->text);)
2530 if (!initialize_class(clazz))
2533 return fieldID->value.l;
2537 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2539 STATS(jniinvokation();)
2540 JWCLINITDEBUG(printf("GetStaticFloatField: calling initialize_class %s\n",clazz->name->text);)
2541 if (!initialize_class(clazz))
2544 return fieldID->value.f;
2548 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2550 STATS(jniinvokation();)
2551 JWCLINITDEBUG(printf("GetStaticDoubleField: calling initialize_class %s\n",clazz->name->text);)
2552 if (!initialize_class(clazz))
2555 return fieldID->value.d;
2559 /* SetStatic<type>Field *******************************************************
2561 This family of accessor routines sets the value of a static field
2564 *******************************************************************************/
2566 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2568 STATS(jniinvokation();)
2569 JWCLINITDEBUG(printf("SetStaticObjectField: calling initialize_class %s\n",clazz->name->text);)
2570 if (!initialize_class(clazz))
2573 fieldID->value.a = value;
2577 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2579 STATS(jniinvokation();)
2580 JWCLINITDEBUG(printf("SetStaticBooleanField: calling initialize_class %s\n",clazz->name->text);)
2581 if (!initialize_class(clazz))
2584 fieldID->value.i = value;
2588 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2590 STATS(jniinvokation();)
2591 JWCLINITDEBUG(printf("SetStaticByteField: calling initialize_class %s\n",clazz->name->text);)
2592 if (!initialize_class(clazz))
2595 fieldID->value.i = value;
2599 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2601 STATS(jniinvokation();)
2602 JWCLINITDEBUG(printf("SetStaticCharField: calling initialize_class %s\n",clazz->name->text);)
2603 if (!initialize_class(clazz))
2606 fieldID->value.i = value;
2610 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2612 STATS(jniinvokation();)
2613 JWCLINITDEBUG(printf("SetStaticShortField: calling initialize_class %s\n",clazz->name->text);)
2614 if (!initialize_class(clazz))
2617 fieldID->value.i = value;
2621 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2623 STATS(jniinvokation();)
2624 JWCLINITDEBUG(printf("SetStaticIntField: calling initialize_class %s\n",clazz->name->text);)
2625 if (!initialize_class(clazz))
2628 fieldID->value.i = value;
2632 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2634 STATS(jniinvokation();)
2635 JWCLINITDEBUG(printf("SetStaticLongField: calling initialize_class %s\n",clazz->name->text);)
2636 if (!initialize_class(clazz))
2639 fieldID->value.l = value;
2643 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2645 STATS(jniinvokation();)
2646 JWCLINITDEBUG(printf("SetStaticFloatField: calling initialize_class %s\n",clazz->name->text);)
2647 if (!initialize_class(clazz))
2650 fieldID->value.f = value;
2654 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2656 STATS(jniinvokation();)
2657 JWCLINITDEBUG(printf("SetStaticDoubleField: calling initialize_class %s\n",clazz->name->text);)
2658 if (!initialize_class(clazz))
2661 fieldID->value.d = value;
2665 /* String Operations **********************************************************/
2667 /* NewString *******************************************************************
2669 Create new java.lang.String object from an array of Unicode
2672 *******************************************************************************/
2674 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
2676 java_lang_String *s;
2680 STATS(jniinvokation();)
2682 s = (java_lang_String *) builtin_new(class_java_lang_String);
2683 a = builtin_newarray_char(len);
2685 /* javastring or characterarray could not be created */
2690 for (i = 0; i < len; i++)
2691 a->data[i] = buf[i];
2701 static jchar emptyStringJ[]={0,0};
2703 /* GetStringLength *************************************************************
2705 Returns the length (the count of Unicode characters) of a Java
2708 *******************************************************************************/
2710 jsize GetStringLength(JNIEnv *env, jstring str)
2712 return ((java_lang_String *) str)->count;
2716 /******************** convertes javastring to u2-array ****************************/
2718 u2 *javastring_tou2(jstring so)
2720 java_lang_String *s;
2725 STATS(jniinvokation();)
2727 s = (java_lang_String *) so;
2737 /* allocate memory */
2739 stringbuffer = MNEW(u2, s->count + 1);
2743 for (i = 0; i < s->count; i++)
2744 stringbuffer[i] = a->data[s->offset + i];
2746 /* terminate string */
2748 stringbuffer[i] = '\0';
2750 return stringbuffer;
2754 /* GetStringChars **************************************************************
2756 Returns a pointer to the array of Unicode characters of the
2757 string. This pointer is valid until ReleaseStringchars() is called.
2759 *******************************************************************************/
2761 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2765 STATS(jniinvokation();)
2767 jc = javastring_tou2(str);
2779 return emptyStringJ;
2783 /* ReleaseStringChars **********************************************************
2785 Informs the VM that the native code no longer needs access to
2786 chars. The chars argument is a pointer obtained from string using
2789 *******************************************************************************/
2791 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2793 STATS(jniinvokation();)
2795 if (chars == emptyStringJ)
2798 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
2802 /* NewStringUTF ****************************************************************
2804 Constructs a new java.lang.String object from an array of UTF-8 characters.
2806 *******************************************************************************/
2808 jstring NewStringUTF(JNIEnv *env, const char *bytes)
2810 STATS(jniinvokation();)
2811 return (jstring) javastring_new(utf_new_char(bytes));
2815 /****************** returns the utf8 length in bytes of a string *******************/
2817 jsize GetStringUTFLength (JNIEnv *env, jstring string)
2819 java_lang_String *s = (java_lang_String*) string;
2820 STATS(jniinvokation();)
2822 return (jsize) u2_utflength(s->value->data, s->count);
2826 /* GetStringUTFChars ***********************************************************
2828 Returns a pointer to an array of UTF-8 characters of the
2829 string. This array is valid until it is released by
2830 ReleaseStringUTFChars().
2832 *******************************************************************************/
2834 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
2837 STATS(jniinvokation();)
2845 u = javastring_toutf((java_lang_String *) string, false);
2854 /* ReleaseStringUTFChars *******************************************************
2856 Informs the VM that the native code no longer needs access to
2857 utf. The utf argument is a pointer derived from string using
2858 GetStringUTFChars().
2860 *******************************************************************************/
2862 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2864 STATS(jniinvokation();)
2866 /* XXX we don't release utf chars right now, perhaps that should be done
2867 later. Since there is always one reference the garbage collector will
2872 /* Array Operations ***********************************************************/
2874 /* GetArrayLength **************************************************************
2876 Returns the number of elements in the array.
2878 *******************************************************************************/
2880 jsize GetArrayLength(JNIEnv *env, jarray array)
2882 STATS(jniinvokation();)
2888 /* NewObjectArray **************************************************************
2890 Constructs a new array holding objects in class elementClass. All
2891 elements are initially set to initialElement.
2893 *******************************************************************************/
2895 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
2897 java_objectarray *oa;
2899 STATS(jniinvokation();)
2902 *exceptionptr = new_negativearraysizeexception();
2906 oa = builtin_anewarray(length, elementClass);
2911 /* set all elements to initialElement */
2913 for (i = 0; i < length; i++)
2914 oa->data[i] = initialElement;
2920 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
2923 STATS(jniinvokation();)
2925 if (index < array->header.size)
2926 j = array->data[index];
2928 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2934 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
2936 STATS(jniinvokation();)
2937 if (index >= array->header.size)
2938 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2941 /* check if the class of value is a subclass of the element class of the array */
2942 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
2943 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
2946 array->data[index] = val;
2952 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
2954 java_booleanarray *j;
2955 STATS(jniinvokation();)
2958 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2962 j = builtin_newarray_boolean(len);
2968 jbyteArray NewByteArray(JNIEnv *env, jsize len)
2971 STATS(jniinvokation();)
2974 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2978 j = builtin_newarray_byte(len);
2984 jcharArray NewCharArray(JNIEnv *env, jsize len)
2987 STATS(jniinvokation();)
2990 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2994 j = builtin_newarray_char(len);
3000 jshortArray NewShortArray(JNIEnv *env, jsize len)
3003 STATS(jniinvokation();)
3006 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
3010 j = builtin_newarray_short(len);
3016 jintArray NewIntArray(JNIEnv *env, jsize len)
3019 STATS(jniinvokation();)
3022 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
3026 j = builtin_newarray_int(len);
3032 jlongArray NewLongArray(JNIEnv *env, jsize len)
3035 STATS(jniinvokation();)
3038 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
3042 j = builtin_newarray_long(len);
3048 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3051 STATS(jniinvokation();)
3054 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
3058 j = builtin_newarray_float(len);
3064 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3066 java_doublearray *j;
3067 STATS(jniinvokation();)
3070 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
3074 j = builtin_newarray_double(len);
3080 /* Get<PrimitiveType>ArrayElements *********************************************
3082 A family of functions that returns the body of the primitive array.
3084 *******************************************************************************/
3086 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3089 STATS(jniinvokation();)
3092 *isCopy = JNI_FALSE;
3098 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3100 STATS(jniinvokation();)
3103 *isCopy = JNI_FALSE;
3109 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3111 STATS(jniinvokation();)
3114 *isCopy = JNI_FALSE;
3120 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3122 STATS(jniinvokation();)
3125 *isCopy = JNI_FALSE;
3131 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3133 STATS(jniinvokation();)
3136 *isCopy = JNI_FALSE;
3142 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3144 STATS(jniinvokation();)
3147 *isCopy = JNI_FALSE;
3153 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3155 STATS(jniinvokation();)
3158 *isCopy = JNI_FALSE;
3164 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3167 STATS(jniinvokation();)
3170 *isCopy = JNI_FALSE;
3176 /* Release<PrimitiveType>ArrayElements *****************************************
3178 A family of functions that informs the VM that the native code no
3179 longer needs access to elems. The elems argument is a pointer
3180 derived from array using the corresponding
3181 Get<PrimitiveType>ArrayElements() function. If necessary, this
3182 function copies back all changes made to elems to the original
3185 *******************************************************************************/
3187 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3188 jboolean *elems, jint mode)
3190 STATS(jniinvokation();)
3192 if (elems != array->data) {
3195 MCOPY(array->data, elems, jboolean, array->header.size);
3198 MCOPY(array->data, elems, jboolean, array->header.size);
3199 /* XXX TWISTI how should it be freed? */
3202 /* XXX TWISTI how should it be freed? */
3209 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
3212 STATS(jniinvokation();)
3214 if (elems != array->data) {
3217 MCOPY(array->data, elems, jboolean, array->header.size);
3220 MCOPY(array->data, elems, jboolean, array->header.size);
3221 /* XXX TWISTI how should it be freed? */
3224 /* XXX TWISTI how should it be freed? */
3231 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
3234 STATS(jniinvokation();)
3236 if (elems != array->data) {
3239 MCOPY(array->data, elems, jboolean, array->header.size);
3242 MCOPY(array->data, elems, jboolean, array->header.size);
3243 /* XXX TWISTI how should it be freed? */
3246 /* XXX TWISTI how should it be freed? */
3253 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
3256 STATS(jniinvokation();)
3258 if (elems != array->data) {
3261 MCOPY(array->data, elems, jboolean, array->header.size);
3264 MCOPY(array->data, elems, jboolean, array->header.size);
3265 /* XXX TWISTI how should it be freed? */
3268 /* XXX TWISTI how should it be freed? */
3275 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
3278 STATS(jniinvokation();)
3280 if (elems != array->data) {
3283 MCOPY(array->data, elems, jboolean, array->header.size);
3286 MCOPY(array->data, elems, jboolean, array->header.size);
3287 /* XXX TWISTI how should it be freed? */
3290 /* XXX TWISTI how should it be freed? */
3297 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
3300 STATS(jniinvokation();)
3302 if (elems != array->data) {
3305 MCOPY(array->data, elems, jboolean, array->header.size);
3308 MCOPY(array->data, elems, jboolean, array->header.size);
3309 /* XXX TWISTI how should it be freed? */
3312 /* XXX TWISTI how should it be freed? */
3319 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
3322 STATS(jniinvokation();)
3324 if (elems != array->data) {
3327 MCOPY(array->data, elems, jboolean, array->header.size);
3330 MCOPY(array->data, elems, jboolean, array->header.size);
3331 /* XXX TWISTI how should it be freed? */
3334 /* XXX TWISTI how should it be freed? */
3341 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3342 jdouble *elems, jint mode)
3344 STATS(jniinvokation();)
3346 if (elems != array->data) {
3349 MCOPY(array->data, elems, jboolean, array->header.size);
3352 MCOPY(array->data, elems, jboolean, array->header.size);
3353 /* XXX TWISTI how should it be freed? */
3356 /* XXX TWISTI how should it be freed? */
3363 /* Get<PrimitiveType>ArrayRegion **********************************************
3365 A family of functions that copies a region of a primitive array
3368 *******************************************************************************/
3370 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3371 jsize len, jboolean *buf)
3373 STATS(jniinvokation();)
3375 if (start < 0 || len < 0 || start + len > array->header.size)
3377 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3380 MCOPY(buf, &array->data[start], jboolean, len);
3384 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3387 STATS(jniinvokation();)
3389 if (start < 0 || len < 0 || start + len > array->header.size)
3391 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3394 MCOPY(buf, &array->data[start], jbyte, len);
3398 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3401 STATS(jniinvokation();)
3403 if (start < 0 || len < 0 || start + len > array->header.size)
3405 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3408 MCOPY(buf, &array->data[start], jchar, len);
3412 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3413 jsize len, jshort *buf)
3415 STATS(jniinvokation();)
3417 if (start < 0 || len < 0 || start + len > array->header.size)
3419 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3422 MCOPY(buf, &array->data[start], jshort, len);
3426 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3429 STATS(jniinvokation();)
3431 if (start < 0 || len < 0 || start + len > array->header.size)
3433 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3436 MCOPY(buf, &array->data[start], jint, len);
3440 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
3443 STATS(jniinvokation();)
3445 if (start < 0 || len < 0 || start + len > array->header.size)
3447 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3450 MCOPY(buf, &array->data[start], jlong, len);
3454 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3455 jsize len, jfloat *buf)
3457 STATS(jniinvokation();)
3459 if (start < 0 || len < 0 || start + len > array->header.size)
3461 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3464 MCOPY(buf, &array->data[start], jfloat, len);
3468 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3469 jsize len, jdouble *buf)
3471 STATS(jniinvokation();)
3473 if (start < 0 || len < 0 || start+len>array->header.size)
3475 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3478 MCOPY(buf, &array->data[start], jdouble, len);
3482 /* Set<PrimitiveType>ArrayRegion **********************************************
3484 A family of functions that copies back a region of a primitive
3485 array from a buffer.
3487 *******************************************************************************/
3489 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3490 jsize len, jboolean *buf)
3492 STATS(jniinvokation();)
3494 if (start < 0 || len < 0 || start + len > array->header.size)
3496 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3499 MCOPY(&array->data[start], buf, jboolean, len);
3503 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3506 STATS(jniinvokation();)
3508 if (start < 0 || len < 0 || start + len > array->header.size)
3510 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3513 MCOPY(&array->data[start], buf, jbyte, len);
3517 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3520 STATS(jniinvokation();)
3522 if (start < 0 || len < 0 || start + len > array->header.size)
3524 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3527 MCOPY(&array->data[start], buf, jchar, len);
3532 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3533 jsize len, jshort *buf)
3535 STATS(jniinvokation();)
3537 if (start < 0 || len < 0 || start + len > array->header.size)
3539 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3542 MCOPY(&array->data[start], buf, jshort, len);
3546 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3549 STATS(jniinvokation();)
3551 if (start < 0 || len < 0 || start + len > array->header.size)
3553 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3556 MCOPY(&array->data[start], buf, jint, len);
3561 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
3564 STATS(jniinvokation();)
3566 if (start < 0 || len < 0 || start + len > array->header.size)
3568 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3571 MCOPY(&array->data[start], buf, jlong, len);
3576 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3577 jsize len, jfloat *buf)
3579 STATS(jniinvokation();)
3581 if (start < 0 || len < 0 || start + len > array->header.size)
3583 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3586 MCOPY(&array->data[start], buf, jfloat, len);
3591 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3592 jsize len, jdouble *buf)
3594 STATS(jniinvokation();)
3596 if (start < 0 || len < 0 || start + len > array->header.size)
3598 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3601 MCOPY(&array->data[start], buf, jdouble, len);
3605 /* Registering Native Methods *************************************************/
3607 /* RegisterNatives *************************************************************
3609 Registers native methods with the class specified by the clazz
3610 argument. The methods parameter specifies an array of
3611 JNINativeMethod structures that contain the names, signatures, and
3612 function pointers of the native methods. The nMethods parameter
3613 specifies the number of native methods in the array.
3615 *******************************************************************************/
3617 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
3620 STATS(jniinvokation();)
3622 log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
3628 /* UnregisterNatives ***********************************************************
3630 Unregisters native methods of a class. The class goes back to the
3631 state before it was linked or registered with its native method
3634 This function should not be used in normal native code. Instead, it
3635 provides special programs a way to reload and relink native
3638 *******************************************************************************/
3640 jint UnregisterNatives(JNIEnv *env, jclass clazz)
3642 STATS(jniinvokation();)
3644 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3646 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3652 /* Monitor Operations *********************************************************/
3654 /* MonitorEnter ****************************************************************
3656 Enters the monitor associated with the underlying Java object
3659 *******************************************************************************/
3661 jint MonitorEnter(JNIEnv *env, jobject obj)
3663 STATS(jniinvokation();)
3665 *exceptionptr = new_nullpointerexception();
3669 #if defined(USE_THREADS)
3670 builtin_monitorenter(obj);
3677 /* MonitorExit *****************************************************************
3679 The current thread must be the owner of the monitor associated with
3680 the underlying Java object referred to by obj. The thread
3681 decrements the counter indicating the number of times it has
3682 entered this monitor. If the value of the counter becomes zero, the
3683 current thread releases the monitor.
3685 *******************************************************************************/
3687 jint MonitorExit(JNIEnv *env, jobject obj)
3689 STATS(jniinvokation();)
3691 *exceptionptr = new_nullpointerexception();
3695 #if defined(USE_THREADS)
3696 builtin_monitorexit(obj);
3703 /* JavaVM Interface ***********************************************************/
3705 /* GetJavaVM *******************************************************************
3707 Returns the Java VM interface (used in the Invocation API)
3708 associated with the current thread. The result is placed at the
3709 location pointed to by the second argument, vm.
3711 *******************************************************************************/
3713 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
3715 STATS(jniinvokation();)
3722 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3724 STATS(jniinvokation();)
3725 log_text("JNI-Call: GetStringRegion");
3729 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3731 STATS(jniinvokation();)
3732 log_text("JNI-Call: GetStringUTFRegion");
3736 /* GetPrimitiveArrayCritical ***************************************************
3738 Obtain a direct pointer to array elements.
3740 *******************************************************************************/
3742 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3744 java_objectheader *s;
3745 arraydescriptor *desc;
3747 STATS(jniinvokation();)
3749 s = (java_objectheader *) array;
3750 desc = s->vftbl->arraydesc;
3756 *isCopy = JNI_FALSE;
3758 /* TODO add to global refs */
3760 return ((u1 *) s) + desc->dataoffset;
3764 /* ReleasePrimitiveArrayCritical ***********************************************
3766 No specific documentation.
3768 *******************************************************************************/
3770 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
3773 STATS(jniinvokation();)
3775 log_text("JNI-Call: ReleasePrimitiveArrayCritical: IMPLEMENT ME!!!");
3777 /* TODO remove from global refs */
3781 /* GetStringCritical ***********************************************************
3783 The semantics of these two functions are similar to the existing
3784 Get/ReleaseStringChars functions.
3786 *******************************************************************************/
3788 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
3790 STATS(jniinvokation();)
3792 return GetStringChars(env, string, isCopy);
3796 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
3798 STATS(jniinvokation();)
3800 ReleaseStringChars(env, string, cstring);
3804 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3806 STATS(jniinvokation();)
3807 log_text("JNI-Call: NewWeakGlobalRef");
3813 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
3815 STATS(jniinvokation();)
3816 log_text("JNI-Call: DeleteWeakGlobalRef");
3822 /** Creates a new global reference to the object referred to by the obj argument **/
3824 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
3829 STATS(jniinvokation();)
3831 MonitorEnter(env, *global_ref_table);
3833 refcount = CallObjectMethod(env, *global_ref_table, getmid, lobj);
3834 val = (refcount == NULL) ? 0 : CallIntMethod(env, refcount, intvalue);
3835 newval = NewObject(env, intclass, newint, val + 1);
3837 if (newval != NULL) {
3838 CallObjectMethod(env, *global_ref_table, putmid, lobj, newval);
3839 MonitorExit(env, *global_ref_table);
3843 log_text("JNI-NewGlobalRef: unable to create new java.lang.Integer");
3844 MonitorExit(env, *global_ref_table);
3849 /************* Deletes the global reference pointed to by globalRef **************/
3851 void DeleteGlobalRef(JNIEnv* env, jobject gref)
3855 STATS(jniinvokation();)
3857 MonitorEnter(env, *global_ref_table);
3858 refcount = CallObjectMethod(env, *global_ref_table, getmid, gref);
3860 if (refcount == NULL) {
3861 log_text("JNI-DeleteGlobalRef: unable to find global reference");
3865 val = CallIntMethod(env, refcount, intvalue);
3869 CallObjectMethod(env, *global_ref_table, removemid,refcount);
3872 jobject newval = NewObject(env, intclass, newint, val);
3874 if (newval != NULL) {
3875 CallObjectMethod(env,*global_ref_table, putmid,newval);
3878 log_text("JNI-DeleteGlobalRef: unable to create new java.lang.Integer");
3882 MonitorExit(env,*global_ref_table);
3886 /* ExceptionCheck **************************************************************
3888 Returns JNI_TRUE when there is a pending exception; otherwise,
3891 *******************************************************************************/
3893 jboolean ExceptionCheck(JNIEnv *env)
3895 STATS(jniinvokation();)
3896 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
3900 /* New JNI 1.4 functions ******************************************************/
3902 /* NewDirectByteBuffer *********************************************************
3904 Allocates and returns a direct java.nio.ByteBuffer referring to the
3905 block of memory starting at the memory address address and
3906 extending capacity bytes.
3908 *******************************************************************************/
3910 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3912 STATS(jniinvokation();)
3913 log_text("NewDirectByteBuffer: IMPLEMENT ME!");
3919 /* GetDirectBufferAddress ******************************************************
3921 Fetches and returns the starting address of the memory region
3922 referenced by the given direct java.nio.Buffer.
3924 *******************************************************************************/
3926 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
3928 STATS(jniinvokation();)
3929 log_text("GetDirectBufferAddress: IMPLEMENT ME!");
3935 /* GetDirectBufferCapacity *****************************************************
3937 Fetches and returns the capacity in bytes of the memory region
3938 referenced by the given direct java.nio.Buffer.
3940 *******************************************************************************/
3942 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3944 STATS(jniinvokation();)
3945 log_text("GetDirectBufferCapacity: IMPLEMENT ME!");
3951 jint DestroyJavaVM(JavaVM *vm)
3953 STATS(jniinvokation();)
3954 log_text("DestroyJavaVM called");
3960 /* AttachCurrentThread *********************************************************
3962 Attaches the current thread to a Java VM. Returns a JNI interface
3963 pointer in the JNIEnv argument.
3965 Trying to attach a thread that is already attached is a no-op.
3967 A native thread cannot be attached simultaneously to two Java VMs.
3969 When a thread is attached to the VM, the context class loader is
3970 the bootstrap loader.
3972 *******************************************************************************/
3974 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
3976 STATS(jniinvokation();)
3978 log_text("AttachCurrentThread called");
3980 #if !defined(HAVE___THREAD)
3981 /* cacao_thread_attach();*/
3983 #error "No idea how to implement that. Perhaps Stefan knows"
3992 jint DetachCurrentThread(JavaVM *vm)
3994 STATS(jniinvokation();)
3995 log_text("DetachCurrentThread called");
4001 /* GetEnv **********************************************************************
4003 If the current thread is not attached to the VM, sets *env to NULL,
4004 and returns JNI_EDETACHED. If the specified version is not
4005 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
4006 sets *env to the appropriate interface, and returns JNI_OK.
4008 *******************************************************************************/
4010 jint GetEnv(JavaVM *vm, void **env, jint version)
4012 STATS(jniinvokation();)
4014 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4015 if (thread_getself() == NULL) {
4018 return JNI_EDETACHED;
4022 if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
4023 (version == JNI_VERSION_1_4)) {
4029 #if defined(ENABLE_JVMTI)
4030 if (version == JVMTI_VERSION_1_0) {
4031 *env = (void *) new_jvmtienv();
4040 return JNI_EVERSION;
4045 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4047 STATS(jniinvokation();)
4048 log_text("AttachCurrentThreadAsDaemon called");
4053 /************* JNI Initialization ****************************************************/
4055 jobject jni_init1(JNIEnv* env, jobject lobj) {
4056 #if defined(USE_THREADS)
4057 while (initrunning) {yieldThread();} /* wait until init is done */
4059 if (global_ref_table == NULL) {
4062 #if defined(USE_THREADS)
4064 /* wait until jni_init is done */
4065 MonitorEnter(env, *global_ref_table) ;
4066 MonitorExit(env, *global_ref_table);
4069 return NewGlobalRef(env, lobj);
4071 void jni_init2(JNIEnv* env, jobject gref) {
4072 log_text("DeleteGlobalref called before NewGlobalref");
4073 #if defined(USE_THREADS)
4074 while (initrunning) {yieldThread();} /* wait until init is done */
4076 if (global_ref_table == NULL) {
4079 #if defined(USE_THREADS)
4081 /* wait until jni_init is done */
4082 MonitorEnter(env, *global_ref_table) ;
4083 MonitorExit(env, *global_ref_table);
4086 DeleteGlobalRef(env, gref);
4096 /* initalize global reference table */
4097 ihmclass = FindClass(NULL, "java/util/IdentityHashMap");
4099 if (ihmclass == NULL) {
4100 log_text("JNI-Init: unable to find java.util.IdentityHashMap");
4103 mid = GetMethodID(NULL, ihmclass, "<init>","()V");
4105 log_text("JNI-Init: unable to find constructor in java.util.IdentityHashMap");
4108 global_ref_table = (jobject*)heap_allocate(sizeof(jobject),true,NULL);
4110 *global_ref_table = NewObject(NULL,ihmclass,mid);
4112 if (*global_ref_table == NULL) {
4113 log_text("JNI-Init: unable to create new global_ref_table");
4116 initrunning = false;
4118 getmid = GetMethodID(NULL, ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
4120 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
4123 getmid = GetMethodID(NULL ,ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
4124 if (getmid == NULL) {
4125 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
4128 putmid = GetMethodID(NULL, ihmclass, "put","(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
4129 if (putmid == NULL) {
4130 log_text("JNI-Init: unable to find method \"put\" in java.util.IdentityHashMap");
4133 intclass = FindClass(NULL, "java/lang/Integer");
4134 if (intclass == NULL) {
4135 log_text("JNI-Init: unable to find java.lang.Integer");
4138 newint = GetMethodID(NULL, intclass, "<init>","(I)V");
4139 if (newint == NULL) {
4140 log_text("JNI-Init: unable to find constructor in java.lang.Integer");
4143 intvalue = GetMethodID(NULL, intclass, "intValue","()I");
4144 if (intvalue == NULL) {
4145 log_text("JNI-Init: unable to find method \"intValue\" in java.lang.Integer");
4148 removemid = GetMethodID(NULL, ihmclass, "remove","(Ljava/lang/Object;)Ljava/lang/Object;");
4149 if (removemid == NULL) {
4150 log_text("JNI-DeleteGlobalRef: unable to find method \"remove\" in java.lang.Object");
4153 /* set NewGlobalRef, DeleteGlobalRef envTable entry to real implementation */
4155 JNI_JNIEnvTable.NewGlobalRef = &NewGlobalRef;
4156 JNI_JNIEnvTable.DeleteGlobalRef = &DeleteGlobalRef;
4160 /* JNI invocation table *******************************************************/
4162 const struct JNIInvokeInterface JNI_JavaVMTable = {
4168 AttachCurrentThread,
4169 DetachCurrentThread,
4171 AttachCurrentThreadAsDaemon
4175 /* JNI function table *********************************************************/
4177 struct JNINativeInterface JNI_JNIEnvTable = {
4186 &FromReflectedMethod,
4187 &FromReflectedField,
4202 &jni_init1, /* &NewGlobalRef, initialize Global_Ref_Table*/
4203 &jni_init2, /* &DeleteGlobalRef,*/
4207 &EnsureLocalCapacity,
4223 &CallBooleanMethodV,
4224 &CallBooleanMethodA,
4250 &CallNonvirtualObjectMethod,
4251 &CallNonvirtualObjectMethodV,
4252 &CallNonvirtualObjectMethodA,
4253 &CallNonvirtualBooleanMethod,
4254 &CallNonvirtualBooleanMethodV,
4255 &CallNonvirtualBooleanMethodA,
4256 &CallNonvirtualByteMethod,
4257 &CallNonvirtualByteMethodV,
4258 &CallNonvirtualByteMethodA,
4259 &CallNonvirtualCharMethod,
4260 &CallNonvirtualCharMethodV,
4261 &CallNonvirtualCharMethodA,
4262 &CallNonvirtualShortMethod,
4263 &CallNonvirtualShortMethodV,
4264 &CallNonvirtualShortMethodA,
4265 &CallNonvirtualIntMethod,
4266 &CallNonvirtualIntMethodV,
4267 &CallNonvirtualIntMethodA,
4268 &CallNonvirtualLongMethod,
4269 &CallNonvirtualLongMethodV,
4270 &CallNonvirtualLongMethodA,
4271 &CallNonvirtualFloatMethod,
4272 &CallNonvirtualFloatMethodV,
4273 &CallNonvirtualFloatMethodA,
4274 &CallNonvirtualDoubleMethod,
4275 &CallNonvirtualDoubleMethodV,
4276 &CallNonvirtualDoubleMethodA,
4277 &CallNonvirtualVoidMethod,
4278 &CallNonvirtualVoidMethodV,
4279 &CallNonvirtualVoidMethodA,
4304 &CallStaticObjectMethod,
4305 &CallStaticObjectMethodV,
4306 &CallStaticObjectMethodA,
4307 &CallStaticBooleanMethod,
4308 &CallStaticBooleanMethodV,
4309 &CallStaticBooleanMethodA,
4310 &CallStaticByteMethod,
4311 &CallStaticByteMethodV,
4312 &CallStaticByteMethodA,
4313 &CallStaticCharMethod,
4314 &CallStaticCharMethodV,
4315 &CallStaticCharMethodA,
4316 &CallStaticShortMethod,
4317 &CallStaticShortMethodV,
4318 &CallStaticShortMethodA,
4319 &CallStaticIntMethod,
4320 &CallStaticIntMethodV,
4321 &CallStaticIntMethodA,
4322 &CallStaticLongMethod,
4323 &CallStaticLongMethodV,
4324 &CallStaticLongMethodA,
4325 &CallStaticFloatMethod,
4326 &CallStaticFloatMethodV,
4327 &CallStaticFloatMethodA,
4328 &CallStaticDoubleMethod,
4329 &CallStaticDoubleMethodV,
4330 &CallStaticDoubleMethodA,
4331 &CallStaticVoidMethod,
4332 &CallStaticVoidMethodV,
4333 &CallStaticVoidMethodA,
4337 &GetStaticObjectField,
4338 &GetStaticBooleanField,
4339 &GetStaticByteField,
4340 &GetStaticCharField,
4341 &GetStaticShortField,
4343 &GetStaticLongField,
4344 &GetStaticFloatField,
4345 &GetStaticDoubleField,
4346 &SetStaticObjectField,
4347 &SetStaticBooleanField,
4348 &SetStaticByteField,
4349 &SetStaticCharField,
4350 &SetStaticShortField,
4352 &SetStaticLongField,
4353 &SetStaticFloatField,
4354 &SetStaticDoubleField,
4359 &ReleaseStringChars,
4362 &GetStringUTFLength,
4364 &ReleaseStringUTFChars,
4369 &GetObjectArrayElement,
4370 &SetObjectArrayElement,
4381 &GetBooleanArrayElements,
4382 &GetByteArrayElements,
4383 &GetCharArrayElements,
4384 &GetShortArrayElements,
4385 &GetIntArrayElements,
4386 &GetLongArrayElements,
4387 &GetFloatArrayElements,
4388 &GetDoubleArrayElements,
4390 &ReleaseBooleanArrayElements,
4391 &ReleaseByteArrayElements,
4392 &ReleaseCharArrayElements,
4393 &ReleaseShortArrayElements,
4394 &ReleaseIntArrayElements,
4395 &ReleaseLongArrayElements,
4396 &ReleaseFloatArrayElements,
4397 &ReleaseDoubleArrayElements,
4399 &GetBooleanArrayRegion,
4400 &GetByteArrayRegion,
4401 &GetCharArrayRegion,
4402 &GetShortArrayRegion,
4404 &GetLongArrayRegion,
4405 &GetFloatArrayRegion,
4406 &GetDoubleArrayRegion,
4407 &SetBooleanArrayRegion,
4408 &SetByteArrayRegion,
4409 &SetCharArrayRegion,
4410 &SetShortArrayRegion,
4412 &SetLongArrayRegion,
4413 &SetFloatArrayRegion,
4414 &SetDoubleArrayRegion,
4424 /* new JNI 1.2 functions */
4427 &GetStringUTFRegion,
4429 &GetPrimitiveArrayCritical,
4430 &ReleasePrimitiveArrayCritical,
4433 &ReleaseStringCritical,
4436 &DeleteWeakGlobalRef,
4440 /* new JNI 1.4 functions */
4442 &NewDirectByteBuffer,
4443 &GetDirectBufferAddress,
4444 &GetDirectBufferCapacity
4448 /* Invocation API Functions ***************************************************/
4450 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4452 Returns a default configuration for the Java VM.
4454 *******************************************************************************/
4456 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4458 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4460 /* GNU classpath currently supports JNI 1.2 */
4462 _vm_args->version = JNI_VERSION_1_2;
4468 /* JNI_GetCreatedJavaVMs *******************************************************
4470 Returns all Java VMs that have been created. Pointers to VMs are written in
4471 the buffer vmBuf in the order they are created. At most bufLen number of
4472 entries will be written. The total number of created VMs is returned in
4475 *******************************************************************************/
4477 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4479 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4485 /* JNI_CreateJavaVM ************************************************************
4487 Loads and initializes a Java VM. The current thread becomes the main thread.
4488 Sets the env argument to the JNI interface pointer of the main thread.
4490 *******************************************************************************/
4492 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4494 const struct JNIInvokeInterface *vm;
4495 struct JNINativeInterface *env;
4497 vm = &JNI_JavaVMTable;
4498 env = &JNI_JNIEnvTable;
4500 *p_vm = (JavaVM *) vm;
4501 *p_env = (JNIEnv *) env;
4507 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4508 jobject obj, java_objectarray *params)
4514 if (methodID == 0) {
4515 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
4519 argcount = methodID->parseddesc->paramcount;
4521 /* if method is non-static, remove the `this' pointer */
4523 if (!(methodID->flags & ACC_STATIC))
4526 /* the method is an instance method the obj has to be an instance of the
4527 class the method belongs to. For static methods the obj parameter
4530 if (!(methodID->flags & ACC_STATIC) && obj &&
4531 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4533 new_exception_message(string_java_lang_IllegalArgumentException,
4534 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4541 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
4542 log_text("Too many arguments. invokeNativeHelper does not support that");
4547 if (((params == NULL) && (argcount != 0)) ||
4548 (params && (params->header.size != argcount))) {
4550 new_exception(string_java_lang_IllegalArgumentException);
4555 if (!(methodID->flags & ACC_STATIC) && !obj) {
4557 new_exception_message(string_java_lang_NullPointerException,
4558 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4562 if ((methodID->flags & ACC_STATIC) && (obj))
4566 if ((methodID->flags & ACC_ABSTRACT) ||
4567 (methodID->class->flags & ACC_INTERFACE)) {
4568 methodID = get_virtual(obj, methodID);
4572 blk = MNEW(jni_callblock, /*4 */argcount + 2);
4574 if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4578 switch (methodID->parseddesc->returntype.decltype) {
4580 (void) asm_calljavafunction2(methodID, argcount + 1,
4581 (argcount + 1) * sizeof(jni_callblock),
4583 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4586 case PRIMITIVETYPE_INT: {
4588 i = asm_calljavafunction2int(methodID, argcount + 1,
4589 (argcount + 1) * sizeof(jni_callblock),
4592 o = native_new_and_init_int(class_java_lang_Integer, i);
4596 case PRIMITIVETYPE_BYTE: {
4598 i = asm_calljavafunction2int(methodID, argcount + 1,
4599 (argcount + 1) * sizeof(jni_callblock),
4602 /* o = native_new_and_init_int(class_java_lang_Byte, i); */
4603 o = builtin_new(class_java_lang_Byte);
4606 class_resolvemethod(o->vftbl->class,
4613 case PRIMITIVETYPE_CHAR: {
4615 intVal = asm_calljavafunction2int(methodID,
4617 (argcount + 1) * sizeof(jni_callblock),
4619 o = builtin_new(class_java_lang_Character);
4622 class_resolvemethod(o->vftbl->class,
4629 case PRIMITIVETYPE_SHORT: {
4631 intVal = asm_calljavafunction2int(methodID,
4633 (argcount + 1) * sizeof(jni_callblock),
4635 o = builtin_new(class_java_lang_Short);
4638 class_resolvemethod(o->vftbl->class,
4645 case PRIMITIVETYPE_BOOLEAN: {
4647 intVal = asm_calljavafunction2int(methodID,
4649 (argcount + 1) * sizeof(jni_callblock),
4651 o = builtin_new(class_java_lang_Boolean);
4654 class_resolvemethod(o->vftbl->class,
4663 longVal = asm_calljavafunction2long(methodID,
4665 (argcount + 1) * sizeof(jni_callblock),
4667 o = builtin_new(class_java_lang_Long);
4670 class_resolvemethod(o->vftbl->class,
4677 case PRIMITIVETYPE_FLOAT: {
4679 floatVal = asm_calljavafunction2float(methodID,
4681 (argcount + 1) * sizeof(jni_callblock),
4683 o = builtin_new(class_java_lang_Float);
4686 class_resolvemethod(o->vftbl->class,
4693 case PRIMITIVETYPE_DOUBLE: {
4695 doubleVal = asm_calljavafunction2double(methodID,
4697 (argcount + 1) * sizeof(jni_callblock),
4699 o = builtin_new(class_java_lang_Double);
4702 class_resolvemethod(o->vftbl->class,
4710 o = asm_calljavafunction2(methodID, argcount + 1,
4711 (argcount + 1) * sizeof(jni_callblock), blk);
4715 /* if this happens the exception has already been set by */
4716 /* fill_callblock_from_objectarray */
4718 MFREE(blk, jni_callblock, /*4 */ argcount+2);
4719 return (jobject *) 0;
4722 MFREE(blk, jni_callblock, /* 4 */ argcount+2);
4724 if (*exceptionptr) {
4725 java_objectheader *cause;
4727 cause = *exceptionptr;
4729 /* clear exception pointer, we are calling JIT code again */
4731 *exceptionptr = NULL;
4734 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
4735 (java_lang_Throwable *) cause);
4738 return (jobject *) o;
4743 * These are local overrides for various environment variables in Emacs.
4744 * Please do not remove this and leave it at the end of the file, where
4745 * Emacs will automagically detect them.
4746 * ---------------------------------------------------------------------
4749 * indent-tabs-mode: t