1 /* 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
29 Changes: Joseph Wenninger, Martin Platter
31 $Id: jni.c 1853 2005-01-04 12:07:41Z twisti $
39 #include "mm/memory.h"
40 #include "native/jni.h"
41 #include "native/native.h"
42 #include "native/include/java_lang_Byte.h"
43 #include "native/include/java_lang_Character.h"
44 #include "native/include/java_lang_Short.h"
45 #include "native/include/java_lang_Integer.h"
46 #include "native/include/java_lang_Boolean.h"
47 #include "native/include/java_lang_Long.h"
48 #include "native/include/java_lang_Float.h"
49 #include "native/include/java_lang_Double.h"
50 #include "native/include/java_lang_Throwable.h"
52 #if defined(USE_THREADS)
53 # if defined(NATIVE_THREADS)
54 # include "threads/native/threads.h"
56 # include "threads/green/threads.h"
60 #include "toolbox/logging.h"
61 #include "vm/builtin.h"
62 #include "vm/exceptions.h"
63 #include "vm/global.h"
64 #include "vm/loader.h"
65 #include "vm/options.h"
66 #include "vm/statistics.h"
67 #include "vm/tables.h"
68 #include "vm/jit/asmpart.h"
69 #include "vm/jit/jit.h"
72 /* XXX TWISTI hack: define it extern to be found in this file */
73 extern struct _JavaVM JNI_javaVMTable;
74 extern struct JNI_Table JNI_envTable;
77 #define PTR_TO_ITEM(ptr) ((u8)(size_t)(ptr))
79 static utf* utf_char = 0;
80 static utf* utf_bool = 0;
81 static utf* utf_byte =0;
82 static utf* utf_short = 0;
83 static utf* utf_int = 0;
84 static utf* utf_long = 0;
85 static utf* utf_float = 0;
86 static utf* utf_double = 0;
88 /* global reference table */
89 static jobject *global_ref_table;
90 static bool initrunning=false;
92 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
93 static jmethodID getmid = NULL;
94 static jmethodID putmid = NULL;
95 static jclass intclass = NULL;
96 static jmethodID intvalue = NULL;
97 static jmethodID newint = NULL;
98 static jclass ihmclass = NULL;
99 static jmethodID removemid = NULL;
102 /********************* accessing instance-fields **********************************/
104 #define setField(obj,typ,var,val) *((typ*) ((long int) obj + (long int) var->offset))=val;
105 #define getField(obj,typ,var) *((typ*) ((long int) obj + (long int) var->offset))
106 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) setField(obj,jdatatype,getFieldID_critical(env,clazz,name,sig),val);
110 u4 get_parametercount(methodinfo *m)
112 utf *descr = m->descriptor; /* method-descriptor */
113 char *utf_ptr = descr->text; /* current position in utf-text */
114 char *desc_end = utf_end(descr); /* points behind utf string */
115 u4 parametercount = 0;
118 utf_nextu2(&utf_ptr);
120 /* determine number of parameters */
121 while (*utf_ptr != ')') {
122 get_type(&utf_ptr, desc_end, true);
126 return parametercount;
131 void fill_callblock(void *obj, utf *descr, jni_callblock blk[], va_list data, char ret)
133 char *utf__ptr = descr->text; /* current position in utf-text */
134 char **utf_ptr = &utf__ptr;
135 char *desc_end = utf_end(descr); /* points behind utf string */
141 log_text("fill_callblock");
148 /* determine number of parameters */
150 blk[0].itemtype = TYPE_ADR;
151 blk[0].item = PTR_TO_ITEM(obj);
155 while (**utf_ptr != ')') {
156 if (*utf_ptr >= desc_end)
157 panic("illegal method descriptor");
159 switch (utf_nextu2(utf_ptr)) {
160 /* primitive types */
165 blk[cnt].itemtype = TYPE_INT;
166 blk[cnt].item = (u8) va_arg(data, int);
170 blk[cnt].itemtype = TYPE_INT;
171 dummy = va_arg(data, u4);
172 /*printf("fill_callblock: pos:%d, value:%d\n",cnt,dummy);*/
173 blk[cnt].item = (u8) dummy;
177 blk[cnt].itemtype = TYPE_LNG;
178 blk[cnt].item = (u8) va_arg(data, jlong);
182 blk[cnt].itemtype = TYPE_FLT;
183 *((jfloat *) (&blk[cnt].item)) = (jfloat) va_arg(data, jdouble);
187 blk[cnt].itemtype = TYPE_DBL;
188 *((jdouble *) (&blk[cnt].item)) = (jdouble) va_arg(data, jdouble);
192 panic ("V not allowed as function parameter");
196 while (utf_nextu2(utf_ptr) != ';')
197 blk[cnt].itemtype = TYPE_ADR;
198 blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
205 /* char *start = *utf_ptr; */
207 while ((ch = utf_nextu2(utf_ptr)) == '[')
209 while (utf_nextu2(utf_ptr) != ';') {}
212 ch = utf_nextu2(utf_ptr);
213 blk[cnt].itemtype = TYPE_ADR;
214 blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
221 /*the standard doesn't say anything about return value checking, but it appears to be usefull*/
222 c = utf_nextu2(utf_ptr);
223 c = utf_nextu2(utf_ptr);
224 /*printf("%c %c\n",ret,c);*/
226 if (!((c == 'L') || (c == '[')))
227 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
229 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
233 /* XXX it could be considered if we should do typechecking here in the future */
234 char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_objectarray* params)
236 char *utf__ptr = descr->text; /* current position in utf-text */
237 char **utf_ptr = &utf__ptr;
238 char *desc_end = utf_end(descr); /* points behind utf string */
245 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
249 utf_char=utf_new_char("java/lang/Character");
250 utf_bool=utf_new_char("java/lang/Boolean");
251 utf_byte=utf_new_char("java/lang/Byte");
252 utf_short=utf_new_char("java/lang/Short");
253 utf_int=utf_new_char("java/lang/Integer");
254 utf_long=utf_new_char("java/lang/Long");
255 utf_float=utf_new_char("java/lang/Float");
256 utf_double=utf_new_char("java/lang/Double");
258 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
263 log_text("fill_callblock");
270 /* determine number of parameters */
272 blk[0].itemtype = TYPE_ADR;
273 blk[0].item = PTR_TO_ITEM(obj);
281 while (**utf_ptr != ')') {
282 if (*utf_ptr >= desc_end)
283 panic("illegal method descriptor");
285 /* primitive types */
286 switch (utf_nextu2(utf_ptr)) {
288 param = params->data[cnts];
290 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
293 if (param->vftbl->class->name == utf_byte) {
294 blk[cnt].itemtype = TYPE_INT;
295 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
298 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
304 param = params->data[cnts];
306 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
309 if (param->vftbl->class->name == utf_char) {
310 blk[cnt].itemtype = TYPE_INT;
311 blk[cnt].item = (u8) ((java_lang_Character *) param)->value;
314 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
320 param = params->data[cnts];
322 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
325 if (param->vftbl->class->name == utf_short) {
326 blk[cnt].itemtype = TYPE_INT;
327 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
330 if (param->vftbl->class->name == utf_byte) {
331 blk[cnt].itemtype = TYPE_INT;
332 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
335 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
342 param = params->data[cnts];
344 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
347 if (param->vftbl->class->name == utf_bool) {
348 blk[cnt].itemtype = TYPE_INT;
349 blk[cnt].item = (u8) ((java_lang_Boolean *) param)->value;
352 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
358 /*log_text("fill_callblock_objA: param 'I'");*/
359 param = params->data[cnts];
361 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
364 if (param->vftbl->class->name == utf_int) {
365 blk[cnt].itemtype = TYPE_INT;
366 blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
367 /*printf("INT VALUE :%d\n",((struct java_lang_Integer * )param)->value);*/
369 if (param->vftbl->class->name == utf_short) {
370 blk[cnt].itemtype = TYPE_INT;
371 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
374 if (param->vftbl->class->name == utf_byte) {
375 blk[cnt].itemtype = TYPE_INT;
376 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
379 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
387 param = params->data[cnts];
389 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
392 if (param->vftbl->class->name == utf_long) {
393 blk[cnt].itemtype = TYPE_LNG;
394 blk[cnt].item = (u8) ((java_lang_Long *) param)->value;
397 if (param->vftbl->class->name == utf_int) {
398 blk[cnt].itemtype = TYPE_LNG;
399 blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
402 if (param->vftbl->class->name == utf_short) {
403 blk[cnt].itemtype = TYPE_LNG;
404 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
407 if (param->vftbl->class->name == utf_byte) {
408 blk[cnt].itemtype = TYPE_LNG;
409 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
411 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
421 param = params->data[cnts];
423 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
427 if (param->vftbl->class->name == utf_float) {
428 blk[cnt].itemtype = TYPE_FLT;
429 *((jfloat *) (&blk[cnt].item)) = (jfloat) ((java_lang_Float *) param)->value;
432 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
438 param = params->data[cnts];
440 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
444 if (param->vftbl->class->name == utf_double) {
445 blk[cnt].itemtype = TYPE_DBL;
446 *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
449 if (param->vftbl->class->name == utf_float) {
450 blk[cnt].itemtype = TYPE_DBL;
451 *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
454 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
461 panic("V not allowed as function parameter");
466 char *start = (*utf_ptr) - 1;
469 while (utf_nextu2(utf_ptr) != ';')
470 end = (*utf_ptr) + 1;*/
472 if (!builtin_instanceof(params->data[cnts], class_from_descriptor(start, desc_end, utf_ptr, CLASSLOAD_LOAD))) {
473 if (params->data[cnts] != 0) {
474 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
478 blk[cnt].itemtype = TYPE_ADR;
479 blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
485 char *start = (*utf_ptr) - 1;
489 while ((ch = utf_nextu2(utf_ptr)) == '[')
491 while (utf_nextu2(utf_ptr) != ';') {}
494 end = (*utf_ptr) - 1;
495 ch = utf_nextu2(utf_ptr); */
497 if (!builtin_arrayinstanceof(params->data[cnts], class_from_descriptor(start, desc_end, utf_ptr, CLASSLOAD_LOAD)->vftbl)) {
498 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
502 blk[cnt].itemtype = TYPE_ADR;
503 blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
511 c = utf_nextu2(utf_ptr);
512 c = utf_nextu2(utf_ptr);
513 return c; /*return type needed usage of the right lowlevel methods*/
530 jmethodID get_virtual(jobject obj,jmethodID methodID) {
531 if (obj->vftbl->class==methodID->class) return methodID;
532 return class_resolvemethod (obj->vftbl->class, methodID->name, methodID->descriptor);
535 jmethodID get_nonvirtual(jclass clazz,jmethodID methodID) {
536 if (clazz==methodID->class) return methodID;
537 /*class_resolvemethod -> classfindmethod? (JOWENN)*/
538 return class_resolvemethod (clazz, methodID->name, methodID->descriptor);
543 jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
552 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
556 argcount = get_parametercount(methodID);
558 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
559 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
560 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
564 if (obj && !builtin_instanceof(obj, methodID->class)) {
565 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
572 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
573 log_text("Too many arguments. CallObjectMethod does not support that");
578 blk = MNEW(jni_callblock, /*4 */argcount+2);
580 fill_callblock(obj, methodID->descriptor, blk, args, 'O');
581 /* printf("parameter: obj: %p",blk[0].item); */
582 ret = asm_calljavafunction2(methodID,
584 (argcount + 1) * sizeof(jni_callblock),
586 MFREE(blk, jni_callblock, argcount + 1);
587 /* printf("(CallObjectMethodV)-->%p\n",ret); */
594 core function for integer class methods (bool, byte, short, integer)
595 This is basically needed for i386
597 jint callIntegerMethod(jobject obj, jmethodID methodID, char retType, va_list args)
603 /* printf("%p, %c\n",retType,methodID,retType);*/
606 log_text("JNI-Call: CallObjectMethodV");
607 utf_display(methodID->name);
608 utf_display(methodID->descriptor);
609 printf("\nParmaeter count: %d\n",argcount);
610 utf_display(obj->vftbl->class->name);
614 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
618 argcount = get_parametercount(methodID);
620 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
621 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
622 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
626 if (obj && !builtin_instanceof(obj, methodID->class)) {
627 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
633 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
634 log_text("Too many arguments. CallIntegerMethod does not support that");
639 blk = MNEW(jni_callblock, /*4 */ argcount+2);
641 fill_callblock(obj, methodID->descriptor, blk, args, retType);
643 /* printf("parameter: obj: %p",blk[0].item); */
644 ret = asm_calljavafunction2int(methodID,
646 (argcount + 1) * sizeof(jni_callblock),
649 MFREE(blk, jni_callblock, argcount + 1);
650 /* printf("(CallObjectMethodV)-->%p\n",ret); */
656 /*core function for long class functions*/
657 jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
664 log_text("JNI-Call: CallObjectMethodV");
665 utf_display(methodID->name);
666 utf_display(methodID->descriptor);
667 printf("\nParmaeter count: %d\n",argcount);
668 utf_display(obj->vftbl->class->name);
672 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
676 argcount = get_parametercount(methodID);
678 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
679 ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
680 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
684 if (obj && !builtin_instanceof(obj,methodID->class)) {
685 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
691 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
692 log_text("Too many arguments. CallObjectMethod does not support that");
697 blk = MNEW(jni_callblock,/* 4 */argcount+2);
699 fill_callblock(obj, methodID->descriptor, blk, args, 'J');
701 /* printf("parameter: obj: %p",blk[0].item); */
702 ret = asm_calljavafunction2long(methodID,
704 (argcount + 1) * sizeof(jni_callblock),
707 MFREE(blk, jni_callblock, argcount + 1);
708 /* printf("(CallObjectMethodV)-->%p\n",ret); */
714 /*core function for float class methods (float,double)*/
715 jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,char retType)
717 int argcount = get_parametercount(methodID);
722 log_text("JNI-Call: CallObjectMethodV");
723 utf_display(methodID->name);
724 utf_display(methodID->descriptor);
725 printf("\nParmaeter count: %d\n",argcount);
726 utf_display(obj->vftbl->class->name);
732 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
733 log_text("Too many arguments. CallObjectMethod does not support that");
738 blk = MNEW(jni_callblock, /*4 */ argcount+2);
740 fill_callblock(obj, methodID->descriptor, blk, args, retType);
742 /* printf("parameter: obj: %p",blk[0].item); */
743 ret = asm_calljavafunction2double(methodID,
745 (argcount + 1) * sizeof(jni_callblock),
748 MFREE(blk, jni_callblock, argcount + 1);
749 /* printf("(CallObjectMethodV)-->%p\n",ret); */
755 /*************************** function: jclass_findfield ****************************
757 searches for field with specified name and type in a 'classinfo'-structur
758 if no such field is found NULL is returned
760 ************************************************************************************/
762 fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
765 /* printf(" FieldCount: %d\n",c->fieldscount);
766 utf_display(c->name); */
767 for (i = 0; i < c->fieldscount; i++) {
768 /* utf_display(c->fields[i].name);
770 utf_display(c->fields[i].descriptor);
772 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
773 return &(c->fields[i]);
776 if (c->super) return jclass_findfield(c->super,name,desc);
781 /********************* returns version of native method interface *****************/
783 jint GetVersion (JNIEnv* env)
789 /************** loads a class from a buffer of raw class data *****************/
791 jclass DefineClass(JNIEnv* env, const char *name, jobject loader, const jbyte *buf, jsize len)
797 c = class_new(utf_new_char_classname((char *) name));
799 #if defined(USE_THREADS)
800 /* enter a monitor on the class */
802 builtin_monitorenter((java_objectheader *) c);
809 /* build a classbuffer with the given data */
810 cb = NEW(classbuffer);
813 cb->data = (u1 *) buf;
814 cb->pos = cb->data - 1;
816 r = class_load_intern(cb);
818 /* if return value is NULL, we had a problem and the class is not loaded */
822 /* now free the allocated memory, otherwise we could ran into a DOS */
827 FREE(cb, classbuffer);
833 #if defined(USE_THREADS)
834 /* leave the monitor */
836 builtin_monitorexit((java_objectheader *) c);
839 /* XXX link the class here? */
840 /* if (class_link(c)) */
844 c->classloader = loader;
845 use_class_as_object(r);
852 /*********** loads locally defined class with the specified name **************/
854 jclass FindClass(JNIEnv* env, const char *name)
858 c = class_new(utf_new_char_classname((char *) name));
866 use_class_as_object(c);
872 /*******************************************************************************
874 converts java.lang.reflect.Method or
875 java.lang.reflect.Constructor object to a method ID
877 *******************************************************************************/
879 jmethodID FromReflectedMethod(JNIEnv* env, jobject method)
881 /* log_text("JNI-Call: FromReflectedMethod"); */
887 /*************** return superclass of the class represented by sub ****************/
889 jclass GetSuperclass(JNIEnv* env, jclass sub)
893 c = ((classinfo*) sub)->super;
897 use_class_as_object(c);
903 /* IsAssignableFrom ************************************************************
905 Determines whether an object of sub can be safely cast to sup.
907 *******************************************************************************/
909 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
911 return builtin_isanysubclass(sub, sup);
915 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
917 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
919 /* log_text("JNI-Call: ToReflectedField"); */
925 /***************** throw java.lang.Throwable object ******************************/
927 jint Throw(JNIEnv* env, jthrowable obj)
929 *exceptionptr = (java_objectheader*) obj;
935 /*******************************************************************************
937 create exception object from the class clazz with the
938 specified message and cause it to be thrown
940 *******************************************************************************/
942 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
944 java_lang_Throwable *o;
946 /* instantiate exception object */
947 o = (java_lang_Throwable *) native_new_and_init((classinfo*) clazz);
951 o->detailMessage = (java_lang_String *) javastring_new_char((char *) msg);
953 *exceptionptr = (java_objectheader *) o;
959 /************************* check if exception occured *****************************/
961 jthrowable ExceptionOccurred (JNIEnv* env)
963 return (jthrowable) *exceptionptr;
966 /********** print exception and a backtrace of the stack (for debugging) **********/
968 void ExceptionDescribe (JNIEnv* env)
970 utf_display((*exceptionptr)->vftbl->class->name);
976 /******************* clear any exception currently being thrown *******************/
978 void ExceptionClear (JNIEnv* env)
980 *exceptionptr = NULL;
984 /********** raises a fatal error and does not expect the VM to recover ************/
986 void FatalError (JNIEnv* env, const char *msg)
991 /******************* creates a new local reference frame **************************/
993 jint PushLocalFrame(JNIEnv* env, jint capacity)
1000 /**************** Pops off the current local reference frame **********************/
1002 jobject PopLocalFrame(JNIEnv* env, jobject result)
1004 log_text("JNI-Call: PopLocalFrame");
1011 /*************** Deletes the local reference pointed to by localRef ***************/
1013 void DeleteLocalRef (JNIEnv* env, jobject localRef)
1015 /* log_text("JNI-Call: DeleteLocalRef");*/
1019 /********** Tests whether two references refer to the same Java object ************/
1021 jboolean IsSameObject (JNIEnv* env, jobject obj1, jobject obj2)
1023 return (obj1==obj2);
1026 /***** Creates a new local reference that refers to the same object as ref *******/
1028 jobject NewLocalRef (JNIEnv* env, jobject ref)
1033 /***********************************************************************************
1035 Ensures that at least a given number of local references can
1036 be created in the current thread
1038 **********************************************************************************/
1040 jint EnsureLocalCapacity (JNIEnv* env, jint capacity)
1042 return 0; /* return 0 on success */
1046 /********* Allocates a new Java object without invoking a constructor *************/
1048 jobject AllocObject (JNIEnv* env, jclass clazz)
1050 java_objectheader *o = builtin_new(clazz);
1055 /***********************************************************************************
1057 Constructs a new Java object
1058 arguments that are to be passed to the constructor are placed after methodID
1060 ***********************************************************************************/
1062 jobject NewObject (JNIEnv* env, jclass clazz, jmethodID methodID, ...)
1064 java_objectheader *o;
1066 int argcount=get_parametercount(methodID);
1070 /* log_text("JNI-Call: NewObject"); */
1074 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
1075 log_text("Too many arguments. NewObject does not support that");
1080 o = builtin_new (clazz); /* create object */
1082 if (!o) return NULL;
1084 va_start(vaargs,methodID);
1085 for (i=0;i<argcount;i++) {
1086 args[i]=va_arg(vaargs,void*);
1089 asm_calljavafunction(methodID,o,args[0],args[1],args[2]);
1095 /***********************************************************************************
1097 Constructs a new Java object
1098 arguments that are to be passed to the constructor are placed in va_list args
1100 ***********************************************************************************/
1102 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1104 /* log_text("JNI-Call: NewObjectV"); */
1110 /***********************************************************************************
1112 Constructs a new Java object
1113 arguments that are to be passed to the constructor are placed in
1114 args array of jvalues
1116 ***********************************************************************************/
1118 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1120 /* log_text("JNI-Call: NewObjectA"); */
1126 /************************ returns the class of an object **************************/
1128 jclass GetObjectClass(JNIEnv* env, jobject obj)
1130 classinfo *c = obj->vftbl->class;
1132 use_class_as_object(c);
1138 /************* tests whether an object is an instance of a class ******************/
1140 jboolean IsInstanceOf(JNIEnv* env, jobject obj, jclass clazz)
1142 return builtin_instanceof(obj,clazz);
1146 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1148 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1150 log_text("JNI-Call: FromReflectedField");
1156 /**********************************************************************************
1158 converts a method ID to a java.lang.reflect.Method or
1159 java.lang.reflect.Constructor object
1161 **********************************************************************************/
1163 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1165 log_text("JNI-Call: ToReflectedMethod");
1171 /* GetMethodID *****************************************************************
1173 returns the method ID for an instance method
1175 *******************************************************************************/
1177 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1181 m = class_resolvemethod(clazz,
1182 utf_new_char((char *) name),
1183 utf_new_char((char *) sig));
1185 if (!m || (m->flags & ACC_STATIC)) {
1187 new_exception_message(string_java_lang_NoSuchMethodError, name);
1196 /******************** JNI-functions for calling instance methods ******************/
1198 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1203 /* log_text("JNI-Call: CallObjectMethod");*/
1205 va_start(vaargs, methodID);
1206 ret = callObjectMethod(obj, methodID, vaargs);
1213 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1215 return callObjectMethod(obj,methodID,args);
1219 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1221 log_text("JNI-Call: CallObjectMethodA");
1229 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1234 /* log_text("JNI-Call: CallBooleanMethod");*/
1236 va_start(vaargs,methodID);
1237 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',vaargs);
1243 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1245 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',args);
1249 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1251 log_text("JNI-Call: CallBooleanMethodA");
1256 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1261 /* log_text("JNI-Call: CallVyteMethod");*/
1263 va_start(vaargs,methodID);
1264 ret = callIntegerMethod(obj,get_virtual(obj,methodID),'B',vaargs);
1270 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1272 /* log_text("JNI-Call: CallByteMethodV");*/
1273 return callIntegerMethod(obj,methodID,'B',args);
1277 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1279 log_text("JNI-Call: CallByteMethodA");
1285 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1290 /* log_text("JNI-Call: CallCharMethod");*/
1292 va_start(vaargs,methodID);
1293 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'C', vaargs);
1300 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1302 /* log_text("JNI-Call: CallCharMethodV");*/
1303 return callIntegerMethod(obj,get_virtual(obj,methodID),'C',args);
1307 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1309 log_text("JNI-Call: CallCharMethodA");
1315 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1320 /* log_text("JNI-Call: CallShortMethod");*/
1322 va_start(vaargs, methodID);
1323 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'S', vaargs);
1330 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1332 return callIntegerMethod(obj, get_virtual(obj, methodID), 'S', args);
1336 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1338 log_text("JNI-Call: CallShortMethodA");
1345 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1350 va_start(vaargs,methodID);
1351 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'I', vaargs);
1358 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1360 return callIntegerMethod(obj, get_virtual(obj, methodID), 'I', args);
1364 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1366 log_text("JNI-Call: CallIntMethodA");
1373 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1378 va_start(vaargs,methodID);
1379 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1386 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1388 return callLongMethod(obj,get_virtual(obj, methodID),args);
1392 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1394 log_text("JNI-Call: CallLongMethodA");
1401 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1406 /* log_text("JNI-Call: CallFloatMethod");*/
1408 va_start(vaargs,methodID);
1409 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'F');
1416 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1418 log_text("JNI-Call: CallFloatMethodV");
1419 return callFloatMethod(obj, get_virtual(obj, methodID), args, 'F');
1423 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1425 log_text("JNI-Call: CallFloatMethodA");
1432 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1437 /* log_text("JNI-Call: CallDoubleMethod");*/
1439 va_start(vaargs,methodID);
1440 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'D');
1447 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1449 log_text("JNI-Call: CallDoubleMethodV");
1450 return callFloatMethod(obj, get_virtual(obj, methodID), args, 'D');
1454 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1456 log_text("JNI-Call: CallDoubleMethodA");
1462 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1466 va_start(vaargs,methodID);
1467 (void) callIntegerMethod(obj, get_virtual(obj, methodID), 'V', vaargs);
1472 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1474 log_text("JNI-Call: CallVoidMethodV");
1475 (void)callIntegerMethod(obj,get_virtual(obj,methodID),'V',args);
1479 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1481 log_text("JNI-Call: CallVoidMethodA");
1486 jobject CallNonvirtualObjectMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1488 log_text("JNI-Call: CallNonvirtualObjectMethod");
1494 jobject CallNonvirtualObjectMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1496 log_text("JNI-Call: CallNonvirtualObjectMethodV");
1502 jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1504 log_text("JNI-Call: CallNonvirtualObjectMethodA");
1511 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1516 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1518 va_start(vaargs,methodID);
1519 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',vaargs);
1526 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1528 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1529 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',args);
1533 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1535 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1542 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1547 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1549 va_start(vaargs,methodID);
1550 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',vaargs);
1556 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1558 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1559 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',args);
1564 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1566 log_text("JNI-Call: CallNonvirtualByteMethodA");
1573 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1578 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1580 va_start(vaargs,methodID);
1581 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',vaargs);
1587 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1589 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1590 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',args);
1594 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1596 log_text("JNI-Call: CallNonvirtualCharMethodA");
1603 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1608 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1610 va_start(vaargs,methodID);
1611 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',vaargs);
1617 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1619 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1620 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',args);
1624 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1626 log_text("JNI-Call: CallNonvirtualShortMethodA");
1633 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1639 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1641 va_start(vaargs,methodID);
1642 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',vaargs);
1648 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1650 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1651 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',args);
1655 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1657 log_text("JNI-Call: CallNonvirtualIntMethodA");
1664 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1666 log_text("JNI-Call: CallNonvirtualLongMethod");
1672 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1674 log_text("JNI-Call: CallNonvirtualLongMethodV");
1680 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1682 log_text("JNI-Call: CallNonvirtualLongMethodA");
1689 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1694 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1697 va_start(vaargs,methodID);
1698 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'F');
1705 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1707 log_text("JNI-Call: CallNonvirtualFloatMethodV");
1708 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'F');
1712 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1714 log_text("JNI-Call: CallNonvirtualFloatMethodA");
1721 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1725 log_text("JNI-Call: CallNonvirtualDoubleMethod");
1727 va_start(vaargs,methodID);
1728 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'D');
1735 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1737 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
1738 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'D');
1742 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1744 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
1751 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1755 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
1757 va_start(vaargs,methodID);
1758 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',vaargs);
1764 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1766 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
1768 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',args);
1773 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1775 log_text("JNI-Call: CallNonvirtualVoidMethodA");
1778 /************************* JNI-functions for accessing fields ************************/
1780 jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
1784 /* log_text("========================= searching for:");
1787 f = jclass_findfield(clazz,
1788 utf_new_char ((char*) name),
1789 utf_new_char ((char*) sig)
1793 /*utf_display(clazz->name);
1796 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
1801 /*************************** retrieve fieldid, abort on error ************************/
1803 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
1805 jfieldID id = GetFieldID(env, clazz, name, sig);
1809 utf_display(clazz->name);
1810 log_text("\nfield:");
1815 panic("setfield_critical failed");
1820 jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
1823 jobject dbg,dretval,*dpretval;
1824 long int dli1, dli2, dli3;
1826 printf("GetObjectField(1): thread: %s obj: %p name: %s desc: %s \n",GetStringUTFChars(env,
1827 ((threadobject *) THREADOBJECT)->o
1829 ,obj,((fieldinfo*)fieldID)->name->text,(fieldID->descriptor)->text);
1831 dbg = getField(obj,jobject,fieldID);
1832 dli1 = (long int) obj;
1833 dli2 = (long int) fieldID->offset;
1835 dpretval = (jobject*) dli3;
1836 dretval = *dpretval;
1841 tmp = FindClass(env, "java/lang/Object");
1842 mid = GetMethodID(env,tmp,"toString","()Ljava/lang/String;");
1843 jstr = CallObjectMethod(env,dbg,mid);*/
1845 /* printf("GetObjectField(2): retval %p (obj: %#lx + offset: %#lx = %#lx (jobject*) %p (jobject) %p\n"
1846 ,dbg, dli1, dli2, dli3,dpretval, dretval);*/
1851 return getField(obj,jobject,fieldID);
1854 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
1856 return getField(obj,jboolean,fieldID);
1860 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
1862 return getField(obj,jbyte,fieldID);
1866 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
1868 return getField(obj,jchar,fieldID);
1872 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
1874 return getField(obj,jshort,fieldID);
1878 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
1880 return getField(obj,jint,fieldID);
1884 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
1886 return getField(obj,jlong,fieldID);
1890 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
1892 return getField(obj,jfloat,fieldID);
1896 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
1898 return getField(obj,jdouble,fieldID);
1901 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
1903 setField(obj,jobject,fieldID,val);
1907 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
1909 setField(obj,jboolean,fieldID,val);
1913 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
1915 setField(obj,jbyte,fieldID,val);
1919 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
1921 setField(obj,jchar,fieldID,val);
1925 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
1927 setField(obj,jshort,fieldID,val);
1931 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
1933 setField(obj,jint,fieldID,val);
1937 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
1939 setField(obj,jlong,fieldID,val);
1943 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
1945 setField(obj,jfloat,fieldID,val);
1949 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
1951 setField(obj,jdouble,fieldID,val);
1955 /**************** JNI-functions for calling static methods **********************/
1957 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
1961 m = class_resolvemethod(clazz,
1962 utf_new_char((char *) name),
1963 utf_new_char((char *) sig));
1965 if (!m || !(m->flags & ACC_STATIC)) {
1967 new_exception_message(string_java_lang_NoSuchMethodError, name);
1976 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1981 /* log_text("JNI-Call: CallStaticObjectMethod");*/
1983 va_start(vaargs, methodID);
1984 ret = callObjectMethod(0, methodID, vaargs);
1991 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
1993 /* log_text("JNI-Call: CallStaticObjectMethodV"); */
1995 return callObjectMethod(0,methodID,args);
1999 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2001 log_text("JNI-Call: CallStaticObjectMethodA");
2007 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2012 va_start(vaargs, methodID);
2013 ret = (jboolean) callIntegerMethod(0, methodID, 'Z', vaargs);
2020 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2022 return (jboolean) callIntegerMethod(0, methodID, 'Z', args);
2026 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2028 log_text("JNI-Call: CallStaticBooleanMethodA");
2034 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2039 /* log_text("JNI-Call: CallStaticByteMethod");*/
2041 va_start(vaargs, methodID);
2042 ret = (jbyte) callIntegerMethod(0, methodID, 'B', vaargs);
2049 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2051 return (jbyte) callIntegerMethod(0, methodID, 'B', args);
2055 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2057 log_text("JNI-Call: CallStaticByteMethodA");
2063 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2068 /* log_text("JNI-Call: CallStaticByteMethod");*/
2070 va_start(vaargs, methodID);
2071 ret = (jchar) callIntegerMethod(0, methodID, 'C', vaargs);
2078 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2080 return (jchar) callIntegerMethod(0, methodID, 'C', args);
2084 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2086 log_text("JNI-Call: CallStaticCharMethodA");
2093 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2098 /* log_text("JNI-Call: CallStaticByteMethod");*/
2100 va_start(vaargs, methodID);
2101 ret = (jshort) callIntegerMethod(0, methodID, 'S', vaargs);
2108 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2110 /*log_text("JNI-Call: CallStaticShortMethodV");*/
2111 return (jshort) callIntegerMethod(0, methodID, 'S', args);
2115 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2117 log_text("JNI-Call: CallStaticShortMethodA");
2124 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2129 /* log_text("JNI-Call: CallStaticIntMethod");*/
2131 va_start(vaargs, methodID);
2132 ret = callIntegerMethod(0, methodID, 'I', vaargs);
2139 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2141 log_text("JNI-Call: CallStaticIntMethodV");
2143 return callIntegerMethod(0, methodID, 'I', args);
2147 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2149 log_text("JNI-Call: CallStaticIntMethodA");
2156 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2161 /* log_text("JNI-Call: CallStaticLongMethod");*/
2163 va_start(vaargs, methodID);
2164 ret = callLongMethod(0, methodID, vaargs);
2171 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2173 log_text("JNI-Call: CallStaticLongMethodV");
2175 return callLongMethod(0,methodID,args);
2179 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2181 log_text("JNI-Call: CallStaticLongMethodA");
2188 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2193 /* log_text("JNI-Call: CallStaticLongMethod");*/
2195 va_start(vaargs, methodID);
2196 ret = callFloatMethod(0, methodID, vaargs, 'F');
2203 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2206 return callFloatMethod(0, methodID, args, 'F');
2211 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2213 log_text("JNI-Call: CallStaticFloatMethodA");
2220 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2225 /* log_text("JNI-Call: CallStaticDoubleMethod");*/
2227 va_start(vaargs,methodID);
2228 ret = callFloatMethod(0, methodID, vaargs, 'D');
2235 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2237 log_text("JNI-Call: CallStaticDoubleMethodV");
2239 return callFloatMethod(0, methodID, args, 'D');
2243 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2245 log_text("JNI-Call: CallStaticDoubleMethodA");
2251 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2255 va_start(vaargs, methodID);
2256 (void) callIntegerMethod(0, methodID, 'V', vaargs);
2261 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2263 log_text("JNI-Call: CallStaticVoidMethodV");
2264 (void)callIntegerMethod(0, methodID, 'V', args);
2268 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2270 log_text("JNI-Call: CallStaticVoidMethodA");
2274 /****************** JNI-functions for accessing static fields ********************/
2276 jfieldID GetStaticFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
2280 f = jclass_findfield(clazz,
2281 utf_new_char ((char*) name),
2282 utf_new_char ((char*) sig)
2285 if (!f) *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2291 jobject GetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2294 return fieldID->value.a;
2298 jboolean GetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2301 return fieldID->value.i;
2305 jbyte GetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2308 return fieldID->value.i;
2312 jchar GetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2315 return fieldID->value.i;
2319 jshort GetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2322 return fieldID->value.i;
2326 jint GetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2329 return fieldID->value.i;
2333 jlong GetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2336 return fieldID->value.l;
2340 jfloat GetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2343 return fieldID->value.f;
2347 jdouble GetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2350 return fieldID->value.d;
2355 void SetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2358 fieldID->value.a = value;
2362 void SetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2365 fieldID->value.i = value;
2369 void SetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2372 fieldID->value.i = value;
2376 void SetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2379 fieldID->value.i = value;
2383 void SetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2386 fieldID->value.i = value;
2390 void SetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2393 fieldID->value.i = value;
2397 void SetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2400 fieldID->value.l = value;
2404 void SetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2407 fieldID->value.f = value;
2411 void SetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2414 fieldID->value.d = value;
2418 /***** create new java.lang.String object from an array of Unicode characters ****/
2420 jstring NewString (JNIEnv *env, const jchar *buf, jsize len)
2423 java_lang_String *s;
2426 s = (java_lang_String*) builtin_new (class_java_lang_String);
2427 a = builtin_newarray_char (len);
2429 /* javastring or characterarray could not be created */
2430 if ( (!a) || (!s) ) return NULL;
2433 for (i=0; i<len; i++) a->data[i] = buf[i];
2442 static char emptyString[]="";
2443 static jchar emptyStringJ[]={0,0};
2445 /******************* returns the length of a Java string ***************************/
2447 jsize GetStringLength (JNIEnv *env, jstring str)
2449 return ((java_lang_String*) str)->count;
2453 /******************** convertes javastring to u2-array ****************************/
2455 u2 *javastring_tou2 (jstring so)
2457 java_lang_String *s = (java_lang_String*) so;
2462 if (!s) return NULL;
2465 if (!a) return NULL;
2467 /* allocate memory */
2468 stringbuffer = MNEW( u2 , s->count + 1 );
2471 for (i=0; i<s->count; i++) stringbuffer[i] = a->data[s->offset+i];
2473 /* terminate string */
2474 stringbuffer[i] = '\0';
2476 return stringbuffer;
2479 /********* returns a pointer to an array of Unicode characters of the string *******/
2481 const jchar *GetStringChars (JNIEnv *env, jstring str, jboolean *isCopy)
2483 jchar *jc=javastring_tou2(str);
2486 if (isCopy) *isCopy=JNI_TRUE;
2489 if (isCopy) *isCopy=JNI_TRUE;
2490 return emptyStringJ;
2493 /**************** native code no longer needs access to chars **********************/
2495 void ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars)
2497 if (chars==emptyStringJ) return;
2498 MFREE(((jchar*) chars),jchar,((java_lang_String*) str)->count+1);
2502 /* NewStringUTF ****************************************************************
2504 Constructs a new java.lang.String object from an array of UTF-8 characters.
2506 *******************************************************************************/
2508 jstring NewStringUTF(JNIEnv *env, const char *bytes)
2510 return (jstring) javastring_new(utf_new_char(bytes));
2514 /****************** returns the utf8 length in bytes of a string *******************/
2516 jsize GetStringUTFLength (JNIEnv *env, jstring string)
2518 java_lang_String *s = (java_lang_String*) string;
2520 return (jsize) u2_utflength(s->value->data, s->count);
2524 /************ converts a Javastring to an array of UTF-8 characters ****************/
2526 const char* GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
2530 u = javastring_toutf((java_lang_String *) string, false);
2533 *isCopy = JNI_FALSE;
2543 /***************** native code no longer needs access to utf ***********************/
2545 void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
2547 /*we don't release utf chars right now, perhaps that should be done later. Since there is always one reference
2548 the garbage collector will never get them*/
2550 log_text("JNI-Call: ReleaseStringUTFChars");
2551 utf_display(utf_new_char(chars));
2555 /************************** array operations ***************************************/
2557 jsize GetArrayLength(JNIEnv *env, jarray array)
2563 jobjectArray NewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init)
2565 java_objectarray *j;
2568 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2572 j = builtin_anewarray(len, clazz);
2578 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
2582 if (index < array->header.size)
2583 j = array->data[index];
2585 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2591 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
2593 if (index >= array->header.size)
2594 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2597 /* check if the class of value is a subclass of the element class of the array */
2598 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
2599 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
2602 array->data[index] = val;
2608 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
2610 java_booleanarray *j;
2613 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2617 j = builtin_newarray_boolean(len);
2623 jbyteArray NewByteArray(JNIEnv *env, jsize len)
2628 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2632 j = builtin_newarray_byte(len);
2638 jcharArray NewCharArray(JNIEnv *env, jsize len)
2643 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2647 j = builtin_newarray_char(len);
2653 jshortArray NewShortArray(JNIEnv *env, jsize len)
2658 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2662 j = builtin_newarray_short(len);
2668 jintArray NewIntArray(JNIEnv *env, jsize len)
2673 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2677 j = builtin_newarray_int(len);
2683 jlongArray NewLongArray(JNIEnv *env, jsize len)
2688 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2692 j = builtin_newarray_long(len);
2698 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
2703 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2707 j = builtin_newarray_float(len);
2713 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
2715 java_doublearray *j;
2718 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2722 j = builtin_newarray_double(len);
2728 jboolean * GetBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *isCopy)
2730 if (isCopy) *isCopy = JNI_FALSE;
2735 jbyte * GetByteArrayElements (JNIEnv *env, jbyteArray array, jboolean *isCopy)
2737 if (isCopy) *isCopy = JNI_FALSE;
2742 jchar * GetCharArrayElements (JNIEnv *env, jcharArray array, jboolean *isCopy)
2744 if (isCopy) *isCopy = JNI_FALSE;
2749 jshort * GetShortArrayElements (JNIEnv *env, jshortArray array, jboolean *isCopy)
2751 if (isCopy) *isCopy = JNI_FALSE;
2756 jint * GetIntArrayElements (JNIEnv *env, jintArray array, jboolean *isCopy)
2758 if (isCopy) *isCopy = JNI_FALSE;
2763 jlong * GetLongArrayElements (JNIEnv *env, jlongArray array, jboolean *isCopy)
2765 if (isCopy) *isCopy = JNI_FALSE;
2770 jfloat * GetFloatArrayElements (JNIEnv *env, jfloatArray array, jboolean *isCopy)
2772 if (isCopy) *isCopy = JNI_FALSE;
2777 jdouble * GetDoubleArrayElements (JNIEnv *env, jdoubleArray array, jboolean *isCopy)
2779 if (isCopy) *isCopy = JNI_FALSE;
2785 void ReleaseBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode)
2791 void ReleaseByteArrayElements (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode)
2797 void ReleaseCharArrayElements (JNIEnv *env, jcharArray array, jchar *elems, jint mode)
2803 void ReleaseShortArrayElements (JNIEnv *env, jshortArray array, jshort *elems, jint mode)
2809 void ReleaseIntArrayElements (JNIEnv *env, jintArray array, jint *elems, jint mode)
2815 void ReleaseLongArrayElements (JNIEnv *env, jlongArray array, jlong *elems, jint mode)
2821 void ReleaseFloatArrayElements (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode)
2827 void ReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode)
2833 void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2835 if (start < 0 || len < 0 || start + len > array->header.size)
2836 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2839 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2843 void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
2845 if (start < 0 || len < 0 || start + len > array->header.size)
2846 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2849 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2853 void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
2855 if (start < 0 || len < 0 || start + len > array->header.size)
2856 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2859 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2863 void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
2865 if (start < 0 || len < 0 || start + len > array->header.size)
2866 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2869 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2873 void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
2875 if (start < 0 || len < 0 || start + len > array->header.size)
2876 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2879 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2883 void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
2885 if (start < 0 || len < 0 || start + len > array->header.size)
2886 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2889 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2893 void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
2895 if (start < 0 || len < 0 || start + len > array->header.size)
2896 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2899 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2903 void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
2905 if (start < 0 || len < 0 || start+len>array->header.size)
2906 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2909 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2913 void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2915 if (start < 0 || len < 0 || start + len > array->header.size)
2916 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2919 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2923 void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
2925 if (start < 0 || len < 0 || start + len > array->header.size)
2926 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2929 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2933 void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
2935 if (start < 0 || len < 0 || start + len > array->header.size)
2936 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2939 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2944 void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
2946 if (start < 0 || len < 0 || start + len > array->header.size)
2947 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2950 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2954 void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
2956 if (start < 0 || len < 0 || start + len > array->header.size)
2957 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2960 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2965 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
2967 if (start < 0 || len < 0 || start + len > array->header.size)
2968 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2971 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2976 void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
2978 if (start < 0 || len < 0 || start + len > array->header.size)
2979 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2982 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2987 void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
2989 if (start < 0 || len < 0 || start + len > array->header.size)
2990 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2993 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2997 jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
2999 log_text("JNI-Call: RegisterNatives");
3004 jint UnregisterNatives (JNIEnv* env, jclass clazz)
3006 log_text("JNI-Call: UnregisterNatives");
3010 /******************************* monitor operations ********************************/
3012 jint MonitorEnter(JNIEnv* env, jobject obj)
3014 #if defined(USE_THREADS)
3015 builtin_monitorenter(obj);
3022 jint MonitorExit(JNIEnv* env, jobject obj)
3024 #if defined(USE_THREADS)
3025 builtin_monitorexit(obj);
3032 /* JavaVM interface ***********************************************************/
3034 /* GetJavaVM *******************************************************************
3036 Returns the Java VM interface (used in the Invocation API) associated with
3037 the current thread. The result is placed at the location pointed to by the
3038 second argument, vm.
3040 *******************************************************************************/
3042 jint GetJavaVM(JNIEnv* env, JavaVM **vm)
3044 *vm = &JNI_javaVMTable;
3050 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3052 log_text("JNI-Call: GetStringRegion");
3056 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3058 log_text("JNI-Call: GetStringUTFRegion");
3062 /************** obtain direct pointer to array elements ***********************/
3064 void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
3066 java_objectheader *s = (java_objectheader*) array;
3067 arraydescriptor *desc = s->vftbl->arraydesc;
3069 if (!desc) return NULL;
3071 return ((u1*)s) + desc->dataoffset;
3075 void ReleasePrimitiveArrayCritical (JNIEnv* env, jarray array, void *carray, jint mode)
3077 log_text("JNI-Call: ReleasePrimitiveArrayCritical");
3082 /**** returns a pointer to an array of Unicode characters of the string *******/
3084 const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
3086 log_text("JNI-Call: GetStringCritical");
3088 return GetStringChars(env,string,isCopy);
3091 /*********** native code no longer needs access to chars **********************/
3093 void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
3095 log_text("JNI-Call: ReleaseStringCritical");
3097 ReleaseStringChars(env,string,cstring);
3101 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3103 log_text("JNI-Call: NewWeakGlobalRef");
3109 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
3111 log_text("JNI-Call: DeleteWeakGlobalRef");
3117 /** Creates a new global reference to the object referred to by the obj argument **/
3119 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
3125 MonitorEnter(env, *global_ref_table);
3127 refcount = CallObjectMethod(env, *global_ref_table, getmid, lobj);
3128 val = (refcount == NULL) ? 0 : CallIntMethod(env, refcount, intvalue);
3129 newval = NewObject(env, intclass, newint, val + 1);
3131 if (newval != NULL) {
3132 CallObjectMethod(env, *global_ref_table, putmid, lobj, newval);
3133 MonitorExit(env, *global_ref_table);
3137 log_text("JNI-NewGlobalRef: unable to create new java.lang.Integer");
3138 MonitorExit(env, *global_ref_table);
3143 /************* Deletes the global reference pointed to by globalRef **************/
3145 void DeleteGlobalRef(JNIEnv* env, jobject gref)
3150 MonitorEnter(env, *global_ref_table);
3151 refcount = CallObjectMethod(env, *global_ref_table, getmid, gref);
3153 if (refcount == NULL) {
3154 log_text("JNI-DeleteGlobalRef: unable to find global reference");
3158 val = CallIntMethod(env, refcount, intvalue);
3162 CallObjectMethod(env, *global_ref_table, removemid,refcount);
3165 jobject newval = NewObject(env, intclass, newint, val);
3167 if (newval != NULL) {
3168 CallObjectMethod(env,*global_ref_table, putmid,newval);
3171 log_text("JNI-DeleteGlobalRef: unable to create new java.lang.Integer");
3175 MonitorExit(env,*global_ref_table);
3179 /* ExceptionCheck *****************************************************************
3181 check for pending exception
3183 **********************************************************************************/
3185 jboolean ExceptionCheck(JNIEnv *env)
3187 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
3191 /* New JNI 1.4 functions ******************************************************/
3193 /* NewDirectByteBuffer *********************************************************
3195 Allocates and returns a direct java.nio.ByteBuffer referring to the block of
3196 memory starting at the memory address address and extending capacity bytes.
3198 *******************************************************************************/
3200 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3202 log_text("NewDirectByteBuffer: IMPLEMENT ME!");
3208 /* GetDirectBufferAddress ******************************************************
3210 Fetches and returns the starting address of the memory region referenced by
3211 the given direct java.nio.Buffer.
3213 *******************************************************************************/
3215 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
3217 log_text("GetDirectBufferAddress: IMPLEMENT ME!");
3223 /* GetDirectBufferCapacity *****************************************************
3225 Fetches and returns the capacity in bytes of the memory region referenced by
3226 the given direct java.nio.Buffer.
3228 *******************************************************************************/
3230 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3232 log_text("GetDirectBufferCapacity: IMPLEMENT ME!");
3238 jint DestroyJavaVM(JavaVM *vm)
3240 log_text("DestroyJavaVM called");
3246 jint AttachCurrentThread(JavaVM *vm, void **par1, void *par2)
3248 log_text("AttachCurrentThread called");
3254 jint DetachCurrentThread(JavaVM *vm)
3256 log_text("DetachCurrentThread called");
3262 jint GetEnv(JavaVM *vm, void **environment, jint jniversion)
3264 *environment = &JNI_envTable;
3270 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
3272 log_text("AttachCurrentThreadAsDaemon called");
3277 /************* JNI Initialization ****************************************************/
3279 jobject jni_init1(JNIEnv* env, jobject lobj) {
3280 #if defined(USE_THREADS)
3281 while (initrunning) {yieldThread();} /* wait until init is done */
3283 if (global_ref_table == NULL) {
3286 #if defined(USE_THREADS)
3288 /* wait until jni_init is done */
3289 MonitorEnter(env, *global_ref_table) ;
3290 MonitorExit(env, *global_ref_table);
3293 return NewGlobalRef(env, lobj);
3295 void jni_init2(JNIEnv* env, jobject gref) {
3296 log_text("DeleteGlobalref called before NewGlobalref");
3297 #if defined(USE_THREADS)
3298 while (initrunning) {yieldThread();} /* wait until init is done */
3300 if (global_ref_table == NULL) {
3303 #if defined(USE_THREADS)
3305 /* wait until jni_init is done */
3306 MonitorEnter(env, *global_ref_table) ;
3307 MonitorExit(env, *global_ref_table);
3310 DeleteGlobalRef(env, gref);
3317 log_text("JNI-Init: initialize global_ref_table");
3318 /* initalize global reference table */
3319 ihmclass = FindClass(NULL, "java/util/IdentityHashMap");
3321 if (ihmclass == NULL) {
3322 log_text("JNI-Init: unable to find java.util.IdentityHashMap");
3325 mid = GetMethodID(NULL, ihmclass, "<init>","()V");
3327 log_text("JNI-Init: unable to find constructor in java.util.IdentityHashMap");
3330 global_ref_table = (jobject*)heap_allocate(sizeof(jobject),true,NULL);
3332 *global_ref_table = NewObject(NULL,ihmclass,mid);
3334 if (*global_ref_table == NULL) {
3335 log_text("JNI-Init: unable to create new global_ref_table");
3338 initrunning = false;
3340 getmid = GetMethodID(NULL, ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3342 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3345 getmid = GetMethodID(NULL ,ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3346 if (getmid == NULL) {
3347 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3350 putmid = GetMethodID(NULL, ihmclass, "put","(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
3351 if (putmid == NULL) {
3352 log_text("JNI-Init: unable to find method \"put\" in java.util.IdentityHashMap");
3355 intclass = FindClass(NULL, "java/lang/Integer");
3356 if (intclass == NULL) {
3357 log_text("JNI-Init: unable to find java.lang.Integer");
3360 newint = GetMethodID(NULL, intclass, "<init>","(I)V");
3361 if (newint == NULL) {
3362 log_text("JNI-Init: unable to find constructor in java.lang.Integer");
3365 intvalue = GetMethodID(NULL, intclass, "intValue","()I");
3366 if (intvalue == NULL) {
3367 log_text("JNI-Init: unable to find method \"intValue\" in java.lang.Integer");
3370 removemid = GetMethodID(NULL, ihmclass, "remove","(Ljava/lang/Object;)Ljava/lang/Object;");
3371 if (removemid == NULL) {
3372 log_text("JNI-DeleteGlobalRef: unable to find method \"remove\" in java.lang.Object");
3375 /* set NewGlobalRef, DeleteGlobalRef envTable entry to real implementation */
3377 JNI_envTable.NewGlobalRef = &NewGlobalRef;
3378 JNI_envTable.DeleteGlobalRef = &DeleteGlobalRef;
3382 /* JNI invocation table *******************************************************/
3384 struct _JavaVM JNI_javaVMTable = {
3389 &AttachCurrentThread,
3390 &DetachCurrentThread,
3392 &AttachCurrentThreadAsDaemon
3396 /* JNI function table *********************************************************/
3398 struct JNI_Table JNI_envTable = {
3407 &FromReflectedMethod,
3408 &FromReflectedField,
3423 &jni_init1, /* &NewGlobalRef, initialize Global_Ref_Table*/
3424 &jni_init2, /* &DeleteGlobalRef,*/
3428 &EnsureLocalCapacity,
3444 &CallBooleanMethodV,
3445 &CallBooleanMethodA,
3471 &CallNonvirtualObjectMethod,
3472 &CallNonvirtualObjectMethodV,
3473 &CallNonvirtualObjectMethodA,
3474 &CallNonvirtualBooleanMethod,
3475 &CallNonvirtualBooleanMethodV,
3476 &CallNonvirtualBooleanMethodA,
3477 &CallNonvirtualByteMethod,
3478 &CallNonvirtualByteMethodV,
3479 &CallNonvirtualByteMethodA,
3480 &CallNonvirtualCharMethod,
3481 &CallNonvirtualCharMethodV,
3482 &CallNonvirtualCharMethodA,
3483 &CallNonvirtualShortMethod,
3484 &CallNonvirtualShortMethodV,
3485 &CallNonvirtualShortMethodA,
3486 &CallNonvirtualIntMethod,
3487 &CallNonvirtualIntMethodV,
3488 &CallNonvirtualIntMethodA,
3489 &CallNonvirtualLongMethod,
3490 &CallNonvirtualLongMethodV,
3491 &CallNonvirtualLongMethodA,
3492 &CallNonvirtualFloatMethod,
3493 &CallNonvirtualFloatMethodV,
3494 &CallNonvirtualFloatMethodA,
3495 &CallNonvirtualDoubleMethod,
3496 &CallNonvirtualDoubleMethodV,
3497 &CallNonvirtualDoubleMethodA,
3498 &CallNonvirtualVoidMethod,
3499 &CallNonvirtualVoidMethodV,
3500 &CallNonvirtualVoidMethodA,
3525 &CallStaticObjectMethod,
3526 &CallStaticObjectMethodV,
3527 &CallStaticObjectMethodA,
3528 &CallStaticBooleanMethod,
3529 &CallStaticBooleanMethodV,
3530 &CallStaticBooleanMethodA,
3531 &CallStaticByteMethod,
3532 &CallStaticByteMethodV,
3533 &CallStaticByteMethodA,
3534 &CallStaticCharMethod,
3535 &CallStaticCharMethodV,
3536 &CallStaticCharMethodA,
3537 &CallStaticShortMethod,
3538 &CallStaticShortMethodV,
3539 &CallStaticShortMethodA,
3540 &CallStaticIntMethod,
3541 &CallStaticIntMethodV,
3542 &CallStaticIntMethodA,
3543 &CallStaticLongMethod,
3544 &CallStaticLongMethodV,
3545 &CallStaticLongMethodA,
3546 &CallStaticFloatMethod,
3547 &CallStaticFloatMethodV,
3548 &CallStaticFloatMethodA,
3549 &CallStaticDoubleMethod,
3550 &CallStaticDoubleMethodV,
3551 &CallStaticDoubleMethodA,
3552 &CallStaticVoidMethod,
3553 &CallStaticVoidMethodV,
3554 &CallStaticVoidMethodA,
3558 &GetStaticObjectField,
3559 &GetStaticBooleanField,
3560 &GetStaticByteField,
3561 &GetStaticCharField,
3562 &GetStaticShortField,
3564 &GetStaticLongField,
3565 &GetStaticFloatField,
3566 &GetStaticDoubleField,
3567 &SetStaticObjectField,
3568 &SetStaticBooleanField,
3569 &SetStaticByteField,
3570 &SetStaticCharField,
3571 &SetStaticShortField,
3573 &SetStaticLongField,
3574 &SetStaticFloatField,
3575 &SetStaticDoubleField,
3580 &ReleaseStringChars,
3583 &GetStringUTFLength,
3585 &ReleaseStringUTFChars,
3590 &GetObjectArrayElement,
3591 &SetObjectArrayElement,
3602 &GetBooleanArrayElements,
3603 &GetByteArrayElements,
3604 &GetCharArrayElements,
3605 &GetShortArrayElements,
3606 &GetIntArrayElements,
3607 &GetLongArrayElements,
3608 &GetFloatArrayElements,
3609 &GetDoubleArrayElements,
3611 &ReleaseBooleanArrayElements,
3612 &ReleaseByteArrayElements,
3613 &ReleaseCharArrayElements,
3614 &ReleaseShortArrayElements,
3615 &ReleaseIntArrayElements,
3616 &ReleaseLongArrayElements,
3617 &ReleaseFloatArrayElements,
3618 &ReleaseDoubleArrayElements,
3620 &GetBooleanArrayRegion,
3621 &GetByteArrayRegion,
3622 &GetCharArrayRegion,
3623 &GetShortArrayRegion,
3625 &GetLongArrayRegion,
3626 &GetFloatArrayRegion,
3627 &GetDoubleArrayRegion,
3628 &SetBooleanArrayRegion,
3629 &SetByteArrayRegion,
3630 &SetCharArrayRegion,
3631 &SetShortArrayRegion,
3633 &SetLongArrayRegion,
3634 &SetFloatArrayRegion,
3635 &SetDoubleArrayRegion,
3645 /* new JNI 1.2 functions */
3648 &GetStringUTFRegion,
3650 &GetPrimitiveArrayCritical,
3651 &ReleasePrimitiveArrayCritical,
3654 &ReleaseStringCritical,
3657 &DeleteWeakGlobalRef,
3661 /* new JNI 1.4 functions */
3663 &NewDirectByteBuffer,
3664 &GetDirectBufferAddress,
3665 &GetDirectBufferCapacity
3669 /* Invocation API Functions ***************************************************/
3671 /* JNI_GetDefaultJavaVMInitArgs ************************************************
3673 Returns a default configuration for the Java VM.
3675 *******************************************************************************/
3677 jint JNI_GetDefaultJavaVMInitArgs(void *p_vm_args)
3679 JDK1_1InitArgs *vm_args = (JDK1_1InitArgs *) p_vm_args;
3681 /* GNU classpath currently supports JNI 1.2 */
3683 vm_args->version = JNI_VERSION_1_2;
3689 /* JNI_GetCreatedJavaVMs *******************************************************
3691 Returns all Java VMs that have been created. Pointers to VMs are written in
3692 the buffer vmBuf in the order they are created. At most bufLen number of
3693 entries will be written. The total number of created VMs is returned in
3696 *******************************************************************************/
3698 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
3700 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
3704 /* JNI_CreateJavaVM ************************************************************
3706 Loads and initializes a Java VM. The current thread becomes the main thread.
3707 Sets the env argument to the JNI interface pointer of the main thread.
3709 *******************************************************************************/
3711 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *p_vm_args)
3713 *p_vm = &JNI_javaVMTable;
3714 *p_env = &JNI_envTable;
3720 jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID, jobject obj, java_objectarray *params)
3727 if (methodID == 0) {
3728 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
3732 argcount = get_parametercount(methodID);
3734 if (obj && (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
3735 *exceptionptr = new_exception_message(string_java_lang_IllegalArgumentException,
3736 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
3743 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3744 log_text("Too many arguments. invokeNativeHelper does not support that");
3748 if (((params==0) && (argcount != 0)) || (params && (params->header.size != argcount))) {
3749 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3754 if (((methodID->flags & ACC_STATIC)==0) && (0==obj)) {
3756 new_exception_message(string_java_lang_NullPointerException,
3757 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
3761 if ((methodID->flags & ACC_STATIC) && (obj)) obj = 0;
3764 if ( (methodID->flags & ACC_ABSTRACT) || (methodID->class->flags & ACC_INTERFACE) ) {
3765 methodID=get_virtual(obj,methodID);
3769 blk = MNEW(jni_callblock, /*4 */argcount+2);
3771 retT = fill_callblock_objA(obj, methodID->descriptor, blk, params);
3775 (void) asm_calljavafunction2(methodID,
3777 (argcount + 1) * sizeof(jni_callblock),
3779 retVal = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
3784 intVal = asm_calljavafunction2int(methodID,
3786 (argcount + 1) * sizeof(jni_callblock),
3788 retVal = builtin_new(class_new(utf_new_char("java/lang/Integer")));
3791 class_resolvemethod(retVal->vftbl->class,
3792 utf_new_char("<init>"),
3793 utf_new_char("(I)V")),
3800 intVal = asm_calljavafunction2int(methodID,
3802 (argcount + 1) * sizeof(jni_callblock),
3804 retVal = builtin_new(class_new(utf_new_char("java/lang/Byte")));
3807 class_resolvemethod(retVal->vftbl->class,
3808 utf_new_char("<init>"),
3809 utf_new_char("(B)V")),
3816 intVal = asm_calljavafunction2int(methodID,
3818 (argcount + 1) * sizeof(jni_callblock),
3820 retVal = builtin_new(class_new(utf_new_char("java/lang/Character")));
3823 class_resolvemethod(retVal->vftbl->class,
3824 utf_new_char("<init>"),
3825 utf_new_char("(C)V")),
3832 intVal = asm_calljavafunction2int(methodID,
3834 (argcount + 1) * sizeof(jni_callblock),
3836 retVal = builtin_new(class_new(utf_new_char("java/lang/Short")));
3839 class_resolvemethod(retVal->vftbl->class,
3840 utf_new_char("<init>"),
3841 utf_new_char("(S)V")),
3848 intVal = asm_calljavafunction2int(methodID,
3850 (argcount + 1) * sizeof(jni_callblock),
3852 retVal = builtin_new(class_new(utf_new_char("java/lang/Boolean")));
3855 class_resolvemethod(retVal->vftbl->class,
3856 utf_new_char("<init>"),
3857 utf_new_char("(Z)V")),
3864 longVal = asm_calljavafunction2long(methodID,
3866 (argcount + 1) * sizeof(jni_callblock),
3868 retVal = builtin_new(class_new(utf_new_char("java/lang/Long")));
3871 class_resolvemethod(retVal->vftbl->class,
3872 utf_new_char("<init>"),
3873 utf_new_char("(J)V")),
3880 floatVal = asm_calljavafunction2float(methodID,
3882 (argcount + 1) * sizeof(jni_callblock),
3884 retVal = builtin_new(class_new(utf_new_char("java/lang/Float")));
3887 class_resolvemethod(retVal->vftbl->class,
3888 utf_new_char("<init>"),
3889 utf_new_char("(F)V")),
3896 doubleVal = asm_calljavafunction2double(methodID,
3898 (argcount + 1) * sizeof(jni_callblock),
3900 retVal = builtin_new(class_new(utf_new_char("java/lang/Double")));
3903 class_resolvemethod(retVal->vftbl->class,
3904 utf_new_char("<init>"),
3905 utf_new_char("(D)V")),
3910 case 'L': /* fall through */
3912 retVal = asm_calljavafunction2(methodID,
3914 (argcount + 1) * sizeof(jni_callblock),
3919 /* if this happens the acception has already been set by fill_callblock_objA*/
3920 MFREE(blk, jni_callblock, /*4 */ argcount+2);
3921 return (jobject *) 0;
3924 MFREE(blk, jni_callblock, /* 4 */ argcount+2);
3926 if (*exceptionptr) {
3927 java_objectheader *exceptionToWrap = *exceptionptr;
3929 java_objectheader *ivte;
3931 *exceptionptr = NULL;
3932 ivtec = class_new(utf_new_char("java/lang/reflect/InvocationTargetException"));
3933 ivte = builtin_new(ivtec);
3934 asm_calljavafunction(class_resolvemethod(ivtec,
3935 utf_new_char("<init>"),
3936 utf_new_char("(Ljava/lang/Throwable;)V")),
3942 if (*exceptionptr != NULL)
3943 panic("jni.c: error while creating InvocationTargetException wrapper");
3945 *exceptionptr = ivte;
3948 return (jobject *) retVal;
3955 * These are local overrides for various environment variables in Emacs.
3956 * Please do not remove this and leave it at the end of the file, where
3957 * Emacs will automagically detect them.
3958 * ---------------------------------------------------------------------
3961 * indent-tabs-mode: t