1 /* jni.c - implementation of the Java Native Interface functions
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5 M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6 P. Tomsich, J. Wenninger, M. Platter
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 1471 2004-11-09 11:54:53Z motse $
37 #include "exceptions.h"
46 #include "statistics.h"
47 #include "threads/thread.h"
48 #include "toolbox/logging.h"
49 #include "toolbox/memory.h"
50 #include "nat/java_lang_Byte.h"
51 #include "nat/java_lang_Character.h"
52 #include "nat/java_lang_Short.h"
53 #include "nat/java_lang_Integer.h"
54 #include "nat/java_lang_Boolean.h"
55 #include "nat/java_lang_Long.h"
56 #include "nat/java_lang_Float.h"
57 #include "nat/java_lang_Double.h"
58 #include "nat/java_lang_Throwable.h"
62 #define JNI_VERSION 0x00010002
65 #define PTR_TO_ITEM(ptr) ((u8)(size_t)(ptr))
67 static utf* utf_char = 0;
68 static utf* utf_bool = 0;
69 static utf* utf_byte =0;
70 static utf* utf_short = 0;
71 static utf* utf_int = 0;
72 static utf* utf_long = 0;
73 static utf* utf_float = 0;
74 static utf* utf_double = 0;
76 /* global reference table */
77 static jobject *global_ref_table;
78 static bool initrunning=false;
80 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
81 static jmethodID getmid = NULL;
82 static jmethodID putmid = NULL;
83 static jclass intclass = NULL;
84 static jmethodID intvalue = NULL;
85 static jmethodID newint = NULL;
86 static jclass ihmclass = NULL;
87 static jmethodID removemid = NULL;
90 /********************* accessing instance-fields **********************************/
92 #define setField(obj,typ,var,val) *((typ*) ((long int) obj + (long int) var->offset))=val;
93 #define getField(obj,typ,var) *((typ*) ((long int) obj + (long int) var->offset))
94 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) setField(obj,jdatatype,getFieldID_critical(env,clazz,name,sig),val);
98 u4 get_parametercount(methodinfo *m)
100 utf *descr = m->descriptor; /* method-descriptor */
101 char *utf_ptr = descr->text; /* current position in utf-text */
102 char *desc_end = utf_end(descr); /* points behind utf string */
103 u4 parametercount = 0;
106 utf_nextu2(&utf_ptr);
108 /* determine number of parameters */
109 while (*utf_ptr != ')') {
110 get_type(&utf_ptr, desc_end, true);
114 return parametercount;
119 void fill_callblock(void *obj, utf *descr, jni_callblock blk[], va_list data, char ret)
121 char *utf__ptr = descr->text; /* current position in utf-text */
122 char **utf_ptr = &utf__ptr;
123 char *desc_end = utf_end(descr); /* points behind utf string */
129 log_text("fill_callblock");
136 /* determine number of parameters */
138 blk[0].itemtype = TYPE_ADR;
139 blk[0].item = PTR_TO_ITEM(obj);
143 while (**utf_ptr != ')') {
144 if (*utf_ptr >= desc_end)
145 panic("illegal method descriptor");
147 switch (utf_nextu2(utf_ptr)) {
148 /* primitive types */
153 blk[cnt].itemtype = TYPE_INT;
154 blk[cnt].item = (u8) va_arg(data, int);
158 blk[cnt].itemtype = TYPE_INT;
159 dummy = va_arg(data, u4);
160 /*printf("fill_callblock: pos:%d, value:%d\n",cnt,dummy);*/
161 blk[cnt].item = (u8) dummy;
165 blk[cnt].itemtype = TYPE_LNG;
166 blk[cnt].item = (u8) va_arg(data, jlong);
170 blk[cnt].itemtype = TYPE_FLT;
171 *((jfloat *) (&blk[cnt].item)) = (jfloat) va_arg(data, jdouble);
175 blk[cnt].itemtype = TYPE_DBL;
176 *((jdouble *) (&blk[cnt].item)) = (jdouble) va_arg(data, jdouble);
180 panic ("V not allowed as function parameter");
184 while (utf_nextu2(utf_ptr) != ';')
185 blk[cnt].itemtype = TYPE_ADR;
186 blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
193 /* char *start = *utf_ptr; */
195 while ((ch = utf_nextu2(utf_ptr)) == '[')
197 while (utf_nextu2(utf_ptr) != ';') {}
200 ch = utf_nextu2(utf_ptr);
201 blk[cnt].itemtype = TYPE_ADR;
202 blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
209 /*the standard doesn't say anything about return value checking, but it appears to be usefull*/
210 c = utf_nextu2(utf_ptr);
211 c = utf_nextu2(utf_ptr);
212 /*printf("%c %c\n",ret,c);*/
214 if (!((c == 'L') || (c == '[')))
215 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
217 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
221 /* XXX it could be considered if we should do typechecking here in the future */
222 char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_objectarray* params)
224 char *utf__ptr = descr->text; /* current position in utf-text */
225 char **utf_ptr = &utf__ptr;
226 char *desc_end = utf_end(descr); /* points behind utf string */
233 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
237 utf_char=utf_new_char("java/lang/Character");
238 utf_bool=utf_new_char("java/lang/Boolean");
239 utf_byte=utf_new_char("java/lang/Byte");
240 utf_short=utf_new_char("java/lang/Short");
241 utf_int=utf_new_char("java/lang/Integer");
242 utf_long=utf_new_char("java/lang/Long");
243 utf_float=utf_new_char("java/lang/Float");
244 utf_double=utf_new_char("java/lang/Double");
246 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
251 log_text("fill_callblock");
258 /* determine number of parameters */
260 blk[0].itemtype = TYPE_ADR;
261 blk[0].item = PTR_TO_ITEM(obj);
269 while (**utf_ptr != ')') {
270 if (*utf_ptr >= desc_end)
271 panic("illegal method descriptor");
273 /* primitive types */
274 switch (utf_nextu2(utf_ptr)) {
276 param = params->data[cnts];
278 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
281 if (param->vftbl->class->name == utf_byte) {
282 blk[cnt].itemtype = TYPE_INT;
283 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
286 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
292 param = params->data[cnts];
294 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
297 if (param->vftbl->class->name == utf_char) {
298 blk[cnt].itemtype = TYPE_INT;
299 blk[cnt].item = (u8) ((java_lang_Character *) param)->value;
302 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
308 param = params->data[cnts];
310 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
313 if (param->vftbl->class->name == utf_short) {
314 blk[cnt].itemtype = TYPE_INT;
315 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
318 if (param->vftbl->class->name == utf_byte) {
319 blk[cnt].itemtype = TYPE_INT;
320 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
323 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
330 param = params->data[cnts];
332 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
335 if (param->vftbl->class->name == utf_bool) {
336 blk[cnt].itemtype = TYPE_INT;
337 blk[cnt].item = (u8) ((java_lang_Boolean *) param)->value;
340 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
346 /*log_text("fill_callblock_objA: param 'I'");*/
347 param = params->data[cnts];
349 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
352 if (param->vftbl->class->name == utf_int) {
353 blk[cnt].itemtype = TYPE_INT;
354 blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
355 /*printf("INT VALUE :%d\n",((struct java_lang_Integer * )param)->value);*/
357 if (param->vftbl->class->name == utf_short) {
358 blk[cnt].itemtype = TYPE_INT;
359 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
362 if (param->vftbl->class->name == utf_byte) {
363 blk[cnt].itemtype = TYPE_INT;
364 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
367 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
375 param = params->data[cnts];
377 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
380 if (param->vftbl->class->name == utf_long) {
381 blk[cnt].itemtype = TYPE_LNG;
382 blk[cnt].item = (u8) ((java_lang_Long *) param)->value;
385 if (param->vftbl->class->name == utf_int) {
386 blk[cnt].itemtype = TYPE_LNG;
387 blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
390 if (param->vftbl->class->name == utf_short) {
391 blk[cnt].itemtype = TYPE_LNG;
392 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
395 if (param->vftbl->class->name == utf_byte) {
396 blk[cnt].itemtype = TYPE_LNG;
397 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
399 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
409 param = params->data[cnts];
411 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
415 if (param->vftbl->class->name == utf_float) {
416 blk[cnt].itemtype = TYPE_FLT;
417 *((jfloat *) (&blk[cnt].item)) = (jfloat) ((java_lang_Float *) param)->value;
420 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
426 param = params->data[cnts];
428 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
432 if (param->vftbl->class->name == utf_double) {
433 blk[cnt].itemtype = TYPE_DBL;
434 *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
437 if (param->vftbl->class->name == utf_float) {
438 blk[cnt].itemtype = TYPE_DBL;
439 *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
442 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
449 panic("V not allowed as function parameter");
454 char *start = (*utf_ptr) - 1;
457 while (utf_nextu2(utf_ptr) != ';')
458 end = (*utf_ptr) + 1;
460 if (!builtin_instanceof(params->data[cnts], class_from_descriptor(start, end, 0, CLASSLOAD_LOAD))) {
461 if (params->data[cnts] != 0) {
462 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
467 blk[cnt].itemtype = TYPE_ADR;
468 blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
474 char *start = (*utf_ptr) - 1;
478 while ((ch = utf_nextu2(utf_ptr)) == '[')
480 while (utf_nextu2(utf_ptr) != ';') {}
483 end = (*utf_ptr) - 1;
484 ch = utf_nextu2(utf_ptr);
486 if (!builtin_arrayinstanceof(params->data[cnts], class_from_descriptor(start, end, 0, CLASSLOAD_LOAD)->vftbl)) {
487 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
491 blk[cnt].itemtype = TYPE_ADR;
492 blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
500 c = utf_nextu2(utf_ptr);
501 c = utf_nextu2(utf_ptr);
502 return c; /*return type needed usage of the right lowlevel methods*/
519 jmethodID get_virtual(jobject obj,jmethodID methodID) {
520 if (obj->vftbl->class==methodID->class) return methodID;
521 return class_resolvemethod (obj->vftbl->class, methodID->name, methodID->descriptor);
524 jmethodID get_nonvirtual(jclass clazz,jmethodID methodID) {
525 if (clazz==methodID->class) return methodID;
526 /*class_resolvemethod -> classfindmethod? (JOWENN)*/
527 return class_resolvemethod (clazz, methodID->name, methodID->descriptor);
532 jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
541 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
545 argcount = get_parametercount(methodID);
547 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
548 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
549 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
553 if (obj && !builtin_instanceof(obj, methodID->class)) {
554 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
561 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
562 log_text("Too many arguments. CallObjectMethod does not support that");
567 blk = MNEW(jni_callblock, /*4 */argcount+2);
569 fill_callblock(obj, methodID->descriptor, blk, args, 'O');
570 /* printf("parameter: obj: %p",blk[0].item); */
571 ret = asm_calljavafunction2(methodID,
573 (argcount + 1) * sizeof(jni_callblock),
575 MFREE(blk, jni_callblock, argcount + 1);
576 /* printf("(CallObjectMethodV)-->%p\n",ret); */
583 core function for integer class methods (bool, byte, short, integer)
584 This is basically needed for i386
586 jint callIntegerMethod(jobject obj, jmethodID methodID, char retType, va_list args)
592 /* printf("%p, %c\n",retType,methodID,retType);*/
595 log_text("JNI-Call: CallObjectMethodV");
596 utf_display(methodID->name);
597 utf_display(methodID->descriptor);
598 printf("\nParmaeter count: %d\n",argcount);
599 utf_display(obj->vftbl->class->name);
603 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
607 argcount = get_parametercount(methodID);
609 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
610 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
611 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
615 if (obj && !builtin_instanceof(obj, methodID->class)) {
616 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
622 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
623 log_text("Too many arguments. CallIntegerMethod does not support that");
628 blk = MNEW(jni_callblock, /*4 */ argcount+2);
630 fill_callblock(obj, methodID->descriptor, blk, args, retType);
632 /* printf("parameter: obj: %p",blk[0].item); */
633 ret = (jint) asm_calljavafunction2(methodID,
635 (argcount + 1) * sizeof(jni_callblock),
638 MFREE(blk, jni_callblock, argcount + 1);
639 /* printf("(CallObjectMethodV)-->%p\n",ret); */
645 /*core function for long class functions*/
646 jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
653 log_text("JNI-Call: CallObjectMethodV");
654 utf_display(methodID->name);
655 utf_display(methodID->descriptor);
656 printf("\nParmaeter count: %d\n",argcount);
657 utf_display(obj->vftbl->class->name);
661 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
665 argcount = get_parametercount(methodID);
667 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
668 ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
669 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
673 if (obj && !builtin_instanceof(obj,methodID->class)) {
674 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
680 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
681 log_text("Too many arguments. CallObjectMethod does not support that");
686 blk = MNEW(jni_callblock,/* 4 */argcount+2);
688 fill_callblock(obj, methodID->descriptor, blk, args, 'J');
690 /* printf("parameter: obj: %p",blk[0].item); */
691 ret = asm_calljavafunction2long(methodID,
693 (argcount + 1) * sizeof(jni_callblock),
696 MFREE(blk, jni_callblock, argcount + 1);
697 /* printf("(CallObjectMethodV)-->%p\n",ret); */
703 /*core function for float class methods (float,double)*/
704 jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,char retType)
706 int argcount = get_parametercount(methodID);
711 log_text("JNI-Call: CallObjectMethodV");
712 utf_display(methodID->name);
713 utf_display(methodID->descriptor);
714 printf("\nParmaeter count: %d\n",argcount);
715 utf_display(obj->vftbl->class->name);
721 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
722 log_text("Too many arguments. CallObjectMethod does not support that");
727 blk = MNEW(jni_callblock, /*4 */ argcount+2);
729 fill_callblock(obj, methodID->descriptor, blk, args, retType);
731 /* printf("parameter: obj: %p",blk[0].item); */
732 ret = asm_calljavafunction2double(methodID,
734 (argcount + 1) * sizeof(jni_callblock),
737 MFREE(blk, jni_callblock, argcount + 1);
738 /* printf("(CallObjectMethodV)-->%p\n",ret); */
744 /*************************** function: jclass_findfield ****************************
746 searches for field with specified name and type in a 'classinfo'-structur
747 if no such field is found NULL is returned
749 ************************************************************************************/
751 fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
754 /* printf(" FieldCount: %d\n",c->fieldscount);
755 utf_display(c->name); */
756 for (i = 0; i < c->fieldscount; i++) {
757 /* utf_display(c->fields[i].name);
759 utf_display(c->fields[i].descriptor);
761 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
762 return &(c->fields[i]);
765 if (c->super) return jclass_findfield(c->super,name,desc);
770 /********************* returns version of native method interface *****************/
772 jint GetVersion (JNIEnv* env)
778 /************** loads a class from a buffer of raw class data *****************/
780 jclass DefineClass(JNIEnv* env, const char *name, jobject loader, const jbyte *buf, jsize len)
786 c = class_new(utf_new_char_classname((char *) name));
788 /* enter a monitor on the class */
790 builtin_monitorenter((java_objectheader *) c);
796 /* build a classbuffer with the given data */
797 cb = NEW(classbuffer);
800 cb->data = (u1 *) buf;
801 cb->pos = cb->data - 1;
803 r = class_load_intern(cb);
805 /* if return value is NULL, we had a problem and the class is not loaded */
809 /* now free the allocated memory, otherwise we could ran into a DOS */
814 FREE(cb, classbuffer);
820 /* leave the monitor */
822 builtin_monitorexit((java_objectheader *) c);
824 /* XXX link the class here? */
825 /* if (class_link(c)) */
829 c->classloader = loader;
835 /*********** loads locally defined class with the specified name **************/
837 jclass FindClass(JNIEnv* env, const char *name)
841 c = class_new(utf_new_char_classname((char *) name));
853 /*******************************************************************************
855 converts java.lang.reflect.Method or
856 java.lang.reflect.Constructor object to a method ID
858 *******************************************************************************/
860 jmethodID FromReflectedMethod(JNIEnv* env, jobject method)
862 /* log_text("JNI-Call: FromReflectedMethod"); */
868 /*************** return superclass of the class represented by sub ****************/
870 jclass GetSuperclass(JNIEnv* env, jclass sub)
874 c = ((classinfo*) sub)->super;
878 use_class_as_object(c);
884 /*********************** check whether sub can be cast to sup ********************/
886 jboolean IsAssignableForm(JNIEnv* env, jclass sub, jclass sup)
888 return builtin_isanysubclass(sub, sup);
892 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
894 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
896 /* log_text("JNI-Call: ToReflectedField"); */
902 /***************** throw java.lang.Throwable object ******************************/
904 jint Throw(JNIEnv* env, jthrowable obj)
906 *exceptionptr = (java_objectheader*) obj;
912 /*******************************************************************************
914 create exception object from the class clazz with the
915 specified message and cause it to be thrown
917 *******************************************************************************/
919 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
921 java_lang_Throwable *o;
923 /* instantiate exception object */
924 o = (java_lang_Throwable *) native_new_and_init((classinfo*) clazz);
928 o->detailMessage = (java_lang_String *) javastring_new_char((char *) msg);
930 *exceptionptr = (java_objectheader *) o;
936 /************************* check if exception occured *****************************/
938 jthrowable ExceptionOccurred (JNIEnv* env)
940 return (jthrowable) *exceptionptr;
943 /********** print exception and a backtrace of the stack (for debugging) **********/
945 void ExceptionDescribe (JNIEnv* env)
947 utf_display((*exceptionptr)->vftbl->class->name);
953 /******************* clear any exception currently being thrown *******************/
955 void ExceptionClear (JNIEnv* env)
957 *exceptionptr = NULL;
961 /********** raises a fatal error and does not expect the VM to recover ************/
963 void FatalError (JNIEnv* env, const char *msg)
968 /******************* creates a new local reference frame **************************/
970 jint PushLocalFrame(JNIEnv* env, jint capacity)
977 /**************** Pops off the current local reference frame **********************/
979 jobject PopLocalFrame(JNIEnv* env, jobject result)
981 log_text("JNI-Call: PopLocalFrame");
988 /*************** Deletes the local reference pointed to by localRef ***************/
990 void DeleteLocalRef (JNIEnv* env, jobject localRef)
992 /* log_text("JNI-Call: DeleteLocalRef");*/
996 /********** Tests whether two references refer to the same Java object ************/
998 jboolean IsSameObject (JNIEnv* env, jobject obj1, jobject obj2)
1000 return (obj1==obj2);
1003 /***** Creates a new local reference that refers to the same object as ref *******/
1005 jobject NewLocalRef (JNIEnv* env, jobject ref)
1010 /***********************************************************************************
1012 Ensures that at least a given number of local references can
1013 be created in the current thread
1015 **********************************************************************************/
1017 jint EnsureLocalCapacity (JNIEnv* env, jint capacity)
1019 return 0; /* return 0 on success */
1023 /********* Allocates a new Java object without invoking a constructor *************/
1025 jobject AllocObject (JNIEnv* env, jclass clazz)
1027 java_objectheader *o = builtin_new(clazz);
1032 /***********************************************************************************
1034 Constructs a new Java object
1035 arguments that are to be passed to the constructor are placed after methodID
1037 ***********************************************************************************/
1039 jobject NewObject (JNIEnv* env, jclass clazz, jmethodID methodID, ...)
1041 java_objectheader *o;
1043 int argcount=get_parametercount(methodID);
1047 /* log_text("JNI-Call: NewObject"); */
1051 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
1052 log_text("Too many arguments. NewObject does not support that");
1057 o = builtin_new (clazz); /* create object */
1059 if (!o) return NULL;
1061 va_start(vaargs,methodID);
1062 for (i=0;i<argcount;i++) {
1063 args[i]=va_arg(vaargs,void*);
1066 asm_calljavafunction(methodID,o,args[0],args[1],args[2]);
1072 /***********************************************************************************
1074 Constructs a new Java object
1075 arguments that are to be passed to the constructor are placed in va_list args
1077 ***********************************************************************************/
1079 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1081 /* log_text("JNI-Call: NewObjectV"); */
1087 /***********************************************************************************
1089 Constructs a new Java object
1090 arguments that are to be passed to the constructor are placed in
1091 args array of jvalues
1093 ***********************************************************************************/
1095 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1097 /* log_text("JNI-Call: NewObjectA"); */
1103 /************************ returns the class of an object **************************/
1105 jclass GetObjectClass(JNIEnv* env, jobject obj)
1107 classinfo *c = obj->vftbl->class;
1109 use_class_as_object(c);
1115 /************* tests whether an object is an instance of a class ******************/
1117 jboolean IsInstanceOf(JNIEnv* env, jobject obj, jclass clazz)
1119 return builtin_instanceof(obj,clazz);
1123 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1125 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1127 log_text("JNI-Call: FromReflectedField");
1133 /**********************************************************************************
1135 converts a method ID to a java.lang.reflect.Method or
1136 java.lang.reflect.Constructor object
1138 **********************************************************************************/
1140 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1142 log_text("JNI-Call: ToReflectedMethod");
1148 /**************** returns the method ID for an instance method ********************/
1150 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1154 m = class_resolvemethod (
1156 utf_new_char ((char*) name),
1157 utf_new_char ((char*) sig)
1160 if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
1161 else if (m->flags & ACC_STATIC) {
1163 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
1169 /******************** JNI-functions for calling instance methods ******************/
1171 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1176 /* log_text("JNI-Call: CallObjectMethod");*/
1178 va_start(vaargs, methodID);
1179 ret = callObjectMethod(obj, methodID, vaargs);
1186 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1188 return callObjectMethod(obj,methodID,args);
1192 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1194 log_text("JNI-Call: CallObjectMethodA");
1202 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1207 /* log_text("JNI-Call: CallBooleanMethod");*/
1209 va_start(vaargs,methodID);
1210 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',vaargs);
1216 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1218 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',args);
1222 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1224 log_text("JNI-Call: CallBooleanMethodA");
1229 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1234 /* log_text("JNI-Call: CallVyteMethod");*/
1236 va_start(vaargs,methodID);
1237 ret = callIntegerMethod(obj,get_virtual(obj,methodID),'B',vaargs);
1243 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1245 /* log_text("JNI-Call: CallByteMethodV");*/
1246 return callIntegerMethod(obj,methodID,'B',args);
1250 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1252 log_text("JNI-Call: CallByteMethodA");
1258 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1263 /* log_text("JNI-Call: CallCharMethod");*/
1265 va_start(vaargs,methodID);
1266 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'C', vaargs);
1273 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1275 /* log_text("JNI-Call: CallCharMethodV");*/
1276 return callIntegerMethod(obj,get_virtual(obj,methodID),'C',args);
1280 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1282 log_text("JNI-Call: CallCharMethodA");
1288 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1293 /* log_text("JNI-Call: CallShortMethod");*/
1295 va_start(vaargs, methodID);
1296 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'S', vaargs);
1303 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1305 return callIntegerMethod(obj, get_virtual(obj, methodID), 'S', args);
1309 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1311 log_text("JNI-Call: CallShortMethodA");
1318 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1323 va_start(vaargs,methodID);
1324 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'I', vaargs);
1331 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1333 return callIntegerMethod(obj, get_virtual(obj, methodID), 'I', args);
1337 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1339 log_text("JNI-Call: CallIntMethodA");
1346 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1351 va_start(vaargs,methodID);
1352 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1359 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1361 return callLongMethod(obj,get_virtual(obj, methodID),args);
1365 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1367 log_text("JNI-Call: CallLongMethodA");
1374 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1379 /* log_text("JNI-Call: CallFloatMethod");*/
1381 va_start(vaargs,methodID);
1382 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'F');
1389 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1391 log_text("JNI-Call: CallFloatMethodV");
1392 return callFloatMethod(obj, get_virtual(obj, methodID), args, 'F');
1396 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1398 log_text("JNI-Call: CallFloatMethodA");
1405 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1410 /* log_text("JNI-Call: CallDoubleMethod");*/
1412 va_start(vaargs,methodID);
1413 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'D');
1420 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1422 log_text("JNI-Call: CallDoubleMethodV");
1423 return callFloatMethod(obj, get_virtual(obj, methodID), args, 'D');
1427 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1429 log_text("JNI-Call: CallDoubleMethodA");
1435 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1439 /* log_text("JNI-Call: CallVoidMethod");*/
1441 va_start(vaargs,methodID);
1442 (void) callIntegerMethod(obj, get_virtual(obj, methodID), 'V', vaargs);
1447 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1449 log_text("JNI-Call: CallVoidMethodV");
1450 (void)callIntegerMethod(obj,get_virtual(obj,methodID),'V',args);
1454 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1456 log_text("JNI-Call: CallVoidMethodA");
1461 jobject CallNonvirtualObjectMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1463 log_text("JNI-Call: CallNonvirtualObjectMethod");
1469 jobject CallNonvirtualObjectMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1471 log_text("JNI-Call: CallNonvirtualObjectMethodV");
1477 jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1479 log_text("JNI-Call: CallNonvirtualObjectMethodA");
1486 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1491 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1493 va_start(vaargs,methodID);
1494 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',vaargs);
1501 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1503 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1504 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',args);
1508 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1510 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1517 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1522 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1524 va_start(vaargs,methodID);
1525 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',vaargs);
1531 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1533 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1534 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',args);
1539 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1541 log_text("JNI-Call: CallNonvirtualByteMethodA");
1548 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1553 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1555 va_start(vaargs,methodID);
1556 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',vaargs);
1562 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1564 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1565 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',args);
1569 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1571 log_text("JNI-Call: CallNonvirtualCharMethodA");
1578 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1583 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1585 va_start(vaargs,methodID);
1586 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',vaargs);
1592 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1594 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1595 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',args);
1599 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1601 log_text("JNI-Call: CallNonvirtualShortMethodA");
1608 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1614 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1616 va_start(vaargs,methodID);
1617 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',vaargs);
1623 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1625 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1626 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',args);
1630 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1632 log_text("JNI-Call: CallNonvirtualIntMethodA");
1639 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1641 log_text("JNI-Call: CallNonvirtualLongMethod");
1647 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1649 log_text("JNI-Call: CallNonvirtualLongMethodV");
1655 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1657 log_text("JNI-Call: CallNonvirtualLongMethodA");
1664 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1669 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1672 va_start(vaargs,methodID);
1673 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'F');
1680 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1682 log_text("JNI-Call: CallNonvirtualFloatMethodV");
1683 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'F');
1687 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1689 log_text("JNI-Call: CallNonvirtualFloatMethodA");
1696 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1700 log_text("JNI-Call: CallNonvirtualDoubleMethod");
1702 va_start(vaargs,methodID);
1703 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'D');
1710 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1712 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
1713 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'D');
1717 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1719 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
1726 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1730 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
1732 va_start(vaargs,methodID);
1733 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',vaargs);
1739 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1741 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
1743 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',args);
1748 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1750 log_text("JNI-Call: CallNonvirtualVoidMethodA");
1753 /************************* JNI-functions for accessing fields ************************/
1755 jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
1759 /* log_text("========================= searching for:");
1762 f = jclass_findfield(clazz,
1763 utf_new_char ((char*) name),
1764 utf_new_char ((char*) sig)
1768 utf_display(clazz->name);
1771 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
1776 /*************************** retrieve fieldid, abort on error ************************/
1778 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
1780 jfieldID id = GetFieldID(env, clazz, name, sig);
1784 utf_display(clazz->name);
1785 log_text("\nfield:");
1790 panic("setfield_critical failed");
1795 jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
1797 jobject dbg,dretval,*dpretval;
1798 long int dli1, dli2, dli3;
1800 /* printf("GetObjectField(1): thread: %s obj: %p name: %s desc: %s \n",GetStringUTFChars(env,
1801 ((threadobject *) THREADOBJECT)->o
1803 ,obj,((fieldinfo*)fieldID)->name->text,(fieldID->descriptor)->text);*/
1805 dbg = getField(obj,jobject,fieldID);
1806 dli1 = (long int) obj;
1807 dli2 = (long int) fieldID->offset;
1809 dpretval = (jobject*) dli3;
1810 dretval = *dpretval;
1815 tmp = FindClass(env, "java/lang/Object");
1816 mid = GetMethodID(env,tmp,"toString","()Ljava/lang/String;");
1817 jstr = CallObjectMethod(env,dbg,mid);*/
1819 /* printf("GetObjectField(2): retval %p (obj: %#lx + offset: %#lx = %#lx (jobject*) %p (jobject) %p\n"
1820 ,dbg, dli1, dli2, dli3,dpretval, dretval);*/
1826 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
1828 return getField(obj,jboolean,fieldID);
1832 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
1834 return getField(obj,jbyte,fieldID);
1838 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
1840 return getField(obj,jchar,fieldID);
1844 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
1846 return getField(obj,jshort,fieldID);
1850 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
1852 return getField(obj,jint,fieldID);
1856 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
1858 return getField(obj,jlong,fieldID);
1862 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
1864 return getField(obj,jfloat,fieldID);
1868 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
1870 return getField(obj,jdouble,fieldID);
1873 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
1875 setField(obj,jobject,fieldID,val);
1879 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
1881 setField(obj,jboolean,fieldID,val);
1885 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
1887 setField(obj,jbyte,fieldID,val);
1891 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
1893 setField(obj,jchar,fieldID,val);
1897 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
1899 setField(obj,jshort,fieldID,val);
1903 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
1905 setField(obj,jint,fieldID,val);
1909 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
1911 setField(obj,jlong,fieldID,val);
1915 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
1917 setField(obj,jfloat,fieldID,val);
1921 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
1923 setField(obj,jdouble,fieldID,val);
1927 /**************** JNI-functions for calling static methods **********************/
1929 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
1933 m = class_resolvemethod(clazz,
1934 utf_new_char((char *) name),
1935 utf_new_char((char *) sig));
1937 if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
1938 else if (!(m->flags & ACC_STATIC)) {
1940 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
1947 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1952 /* log_text("JNI-Call: CallStaticObjectMethod");*/
1954 va_start(vaargs, methodID);
1955 ret = callObjectMethod(0, methodID, vaargs);
1962 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
1964 /* log_text("JNI-Call: CallStaticObjectMethodV"); */
1966 return callObjectMethod(0,methodID,args);
1970 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
1972 log_text("JNI-Call: CallStaticObjectMethodA");
1978 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1983 va_start(vaargs, methodID);
1984 ret = (jboolean) callIntegerMethod(0, methodID, 'Z', vaargs);
1991 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
1993 return (jboolean) callIntegerMethod(0, methodID, 'Z', args);
1997 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
1999 log_text("JNI-Call: CallStaticBooleanMethodA");
2005 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2010 /* log_text("JNI-Call: CallStaticByteMethod");*/
2012 va_start(vaargs, methodID);
2013 ret = (jbyte) callIntegerMethod(0, methodID, 'B', vaargs);
2020 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2022 return (jbyte) callIntegerMethod(0, methodID, 'B', args);
2026 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2028 log_text("JNI-Call: CallStaticByteMethodA");
2034 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2039 /* log_text("JNI-Call: CallStaticByteMethod");*/
2041 va_start(vaargs, methodID);
2042 ret = (jchar) callIntegerMethod(0, methodID, 'C', vaargs);
2049 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2051 return (jchar) callIntegerMethod(0, methodID, 'C', args);
2055 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2057 log_text("JNI-Call: CallStaticCharMethodA");
2064 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2069 /* log_text("JNI-Call: CallStaticByteMethod");*/
2071 va_start(vaargs, methodID);
2072 ret = (jshort) callIntegerMethod(0, methodID, 'S', vaargs);
2079 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2081 /*log_text("JNI-Call: CallStaticShortMethodV");*/
2082 return (jshort) callIntegerMethod(0, methodID, 'S', args);
2086 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2088 log_text("JNI-Call: CallStaticShortMethodA");
2095 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2100 /* log_text("JNI-Call: CallStaticIntMethod");*/
2102 va_start(vaargs, methodID);
2103 ret = callIntegerMethod(0, methodID, 'I', vaargs);
2110 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2112 log_text("JNI-Call: CallStaticIntMethodV");
2114 return callIntegerMethod(0, methodID, 'I', args);
2118 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2120 log_text("JNI-Call: CallStaticIntMethodA");
2127 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2132 /* log_text("JNI-Call: CallStaticLongMethod");*/
2134 va_start(vaargs, methodID);
2135 ret = callLongMethod(0, methodID, vaargs);
2142 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2144 log_text("JNI-Call: CallStaticLongMethodV");
2146 return callLongMethod(0,methodID,args);
2150 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2152 log_text("JNI-Call: CallStaticLongMethodA");
2159 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2164 /* log_text("JNI-Call: CallStaticLongMethod");*/
2166 va_start(vaargs, methodID);
2167 ret = callFloatMethod(0, methodID, vaargs, 'F');
2174 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2177 return callFloatMethod(0, methodID, args, 'F');
2182 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2184 log_text("JNI-Call: CallStaticFloatMethodA");
2191 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2196 /* log_text("JNI-Call: CallStaticDoubleMethod");*/
2198 va_start(vaargs,methodID);
2199 ret = callFloatMethod(0, methodID, vaargs, 'D');
2206 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2208 log_text("JNI-Call: CallStaticDoubleMethodV");
2210 return callFloatMethod(0, methodID, args, 'D');
2214 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2216 log_text("JNI-Call: CallStaticDoubleMethodA");
2222 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2226 /* log_text("JNI-Call: CallStaticVoidMethod");*/
2228 va_start(vaargs, methodID);
2229 (void) callIntegerMethod(0, methodID, 'V', vaargs);
2234 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2236 log_text("JNI-Call: CallStaticVoidMethodV");
2237 (void)callIntegerMethod(0, methodID, 'V', args);
2241 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2243 log_text("JNI-Call: CallStaticVoidMethodA");
2247 /****************** JNI-functions for accessing static fields ********************/
2249 jfieldID GetStaticFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
2253 f = jclass_findfield(clazz,
2254 utf_new_char ((char*) name),
2255 utf_new_char ((char*) sig)
2258 if (!f) *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2264 jobject GetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2267 return fieldID->value.a;
2271 jboolean GetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2274 return fieldID->value.i;
2278 jbyte GetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2281 return fieldID->value.i;
2285 jchar GetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2288 return fieldID->value.i;
2292 jshort GetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2295 return fieldID->value.i;
2299 jint GetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2302 return fieldID->value.i;
2306 jlong GetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2309 return fieldID->value.l;
2313 jfloat GetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2316 return fieldID->value.f;
2320 jdouble GetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2323 return fieldID->value.d;
2328 void SetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2331 fieldID->value.a = value;
2335 void SetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2338 fieldID->value.i = value;
2342 void SetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2345 fieldID->value.i = value;
2349 void SetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2352 fieldID->value.i = value;
2356 void SetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2359 fieldID->value.i = value;
2363 void SetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2366 fieldID->value.i = value;
2370 void SetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2373 fieldID->value.l = value;
2377 void SetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2380 fieldID->value.f = value;
2384 void SetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2387 fieldID->value.d = value;
2391 /***** create new java.lang.String object from an array of Unicode characters ****/
2393 jstring NewString (JNIEnv *env, const jchar *buf, jsize len)
2396 java_lang_String *s;
2399 s = (java_lang_String*) builtin_new (class_java_lang_String);
2400 a = builtin_newarray_char (len);
2402 /* javastring or characterarray could not be created */
2403 if ( (!a) || (!s) ) return NULL;
2406 for (i=0; i<len; i++) a->data[i] = buf[i];
2415 static char emptyString[]="";
2416 static jchar emptyStringJ[]={0,0};
2418 /******************* returns the length of a Java string ***************************/
2420 jsize GetStringLength (JNIEnv *env, jstring str)
2422 return ((java_lang_String*) str)->count;
2426 /******************** convertes javastring to u2-array ****************************/
2428 u2 *javastring_tou2 (jstring so)
2430 java_lang_String *s = (java_lang_String*) so;
2435 if (!s) return NULL;
2438 if (!a) return NULL;
2440 /* allocate memory */
2441 stringbuffer = MNEW( u2 , s->count + 1 );
2444 for (i=0; i<s->count; i++) stringbuffer[i] = a->data[s->offset+i];
2446 /* terminate string */
2447 stringbuffer[i] = '\0';
2449 return stringbuffer;
2452 /********* returns a pointer to an array of Unicode characters of the string *******/
2454 const jchar *GetStringChars (JNIEnv *env, jstring str, jboolean *isCopy)
2456 jchar *jc=javastring_tou2(str);
2459 if (isCopy) *isCopy=JNI_TRUE;
2462 if (isCopy) *isCopy=JNI_TRUE;
2463 return emptyStringJ;
2466 /**************** native code no longer needs access to chars **********************/
2468 void ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars)
2470 if (chars==emptyStringJ) return;
2471 MFREE(((jchar*) chars),jchar,((java_lang_String*) str)->count+1);
2474 /************ create new java.lang.String object from utf8-characterarray **********/
2476 jstring NewStringUTF (JNIEnv *env, const char *utf)
2478 /* log_text("NewStringUTF called");*/
2479 return (jstring) javastring_new(utf_new_char((char *) utf));
2482 /****************** returns the utf8 length in bytes of a string *******************/
2484 jsize GetStringUTFLength (JNIEnv *env, jstring string)
2486 java_lang_String *s = (java_lang_String*) string;
2488 return (jsize) u2_utflength(s->value->data, s->count);
2492 /************ converts a Javastring to an array of UTF-8 characters ****************/
2494 const char* GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
2498 u = javastring_toutf((java_lang_String *) string, false);
2501 *isCopy = JNI_FALSE;
2511 /***************** native code no longer needs access to utf ***********************/
2513 void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
2515 /*we don't release utf chars right now, perhaps that should be done later. Since there is always one reference
2516 the garbage collector will never get them*/
2518 log_text("JNI-Call: ReleaseStringUTFChars");
2519 utf_display(utf_new_char(chars));
2523 /************************** array operations ***************************************/
2525 jsize GetArrayLength(JNIEnv *env, jarray array)
2531 jobjectArray NewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init)
2533 java_objectarray *j;
2536 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2540 j = builtin_anewarray(len, clazz);
2546 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
2550 if (index < array->header.size)
2551 j = array->data[index];
2553 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2559 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
2561 if (index >= array->header.size)
2562 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2565 /* check if the class of value is a subclass of the element class of the array */
2566 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
2567 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
2570 array->data[index] = val;
2576 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
2578 java_booleanarray *j;
2581 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2585 j = builtin_newarray_boolean(len);
2591 jbyteArray NewByteArray(JNIEnv *env, jsize len)
2596 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2600 j = builtin_newarray_byte(len);
2606 jcharArray NewCharArray(JNIEnv *env, jsize len)
2611 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2615 j = builtin_newarray_char(len);
2621 jshortArray NewShortArray(JNIEnv *env, jsize len)
2626 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2630 j = builtin_newarray_short(len);
2636 jintArray NewIntArray(JNIEnv *env, jsize len)
2641 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2645 j = builtin_newarray_int(len);
2651 jlongArray NewLongArray(JNIEnv *env, jsize len)
2656 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2660 j = builtin_newarray_long(len);
2666 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
2671 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2675 j = builtin_newarray_float(len);
2681 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
2683 java_doublearray *j;
2686 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2690 j = builtin_newarray_double(len);
2696 jboolean * GetBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *isCopy)
2698 if (isCopy) *isCopy = JNI_FALSE;
2703 jbyte * GetByteArrayElements (JNIEnv *env, jbyteArray array, jboolean *isCopy)
2705 if (isCopy) *isCopy = JNI_FALSE;
2710 jchar * GetCharArrayElements (JNIEnv *env, jcharArray array, jboolean *isCopy)
2712 if (isCopy) *isCopy = JNI_FALSE;
2717 jshort * GetShortArrayElements (JNIEnv *env, jshortArray array, jboolean *isCopy)
2719 if (isCopy) *isCopy = JNI_FALSE;
2724 jint * GetIntArrayElements (JNIEnv *env, jintArray array, jboolean *isCopy)
2726 if (isCopy) *isCopy = JNI_FALSE;
2731 jlong * GetLongArrayElements (JNIEnv *env, jlongArray array, jboolean *isCopy)
2733 if (isCopy) *isCopy = JNI_FALSE;
2738 jfloat * GetFloatArrayElements (JNIEnv *env, jfloatArray array, jboolean *isCopy)
2740 if (isCopy) *isCopy = JNI_FALSE;
2745 jdouble * GetDoubleArrayElements (JNIEnv *env, jdoubleArray array, jboolean *isCopy)
2747 if (isCopy) *isCopy = JNI_FALSE;
2753 void ReleaseBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode)
2759 void ReleaseByteArrayElements (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode)
2765 void ReleaseCharArrayElements (JNIEnv *env, jcharArray array, jchar *elems, jint mode)
2771 void ReleaseShortArrayElements (JNIEnv *env, jshortArray array, jshort *elems, jint mode)
2777 void ReleaseIntArrayElements (JNIEnv *env, jintArray array, jint *elems, jint mode)
2783 void ReleaseLongArrayElements (JNIEnv *env, jlongArray array, jlong *elems, jint mode)
2789 void ReleaseFloatArrayElements (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode)
2795 void ReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode)
2801 void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2803 if (start < 0 || len < 0 || start + len > array->header.size)
2804 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2807 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2811 void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
2813 if (start < 0 || len < 0 || start + len > array->header.size)
2814 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2817 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2821 void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
2823 if (start < 0 || len < 0 || start + len > array->header.size)
2824 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2827 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2831 void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
2833 if (start < 0 || len < 0 || start + len > array->header.size)
2834 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2837 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2841 void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
2843 if (start < 0 || len < 0 || start + len > array->header.size)
2844 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2847 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2851 void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
2853 if (start < 0 || len < 0 || start + len > array->header.size)
2854 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2857 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2861 void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
2863 if (start < 0 || len < 0 || start + len > array->header.size)
2864 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2867 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2871 void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
2873 if (start < 0 || len < 0 || start+len>array->header.size)
2874 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2877 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2881 void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2883 if (start < 0 || len < 0 || start + len > array->header.size)
2884 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2887 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2891 void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
2893 if (start < 0 || len < 0 || start + len > array->header.size)
2894 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2897 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2901 void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
2903 if (start < 0 || len < 0 || start + len > array->header.size)
2904 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2907 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2912 void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
2914 if (start < 0 || len < 0 || start + len > array->header.size)
2915 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2918 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2922 void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
2924 if (start < 0 || len < 0 || start + len > array->header.size)
2925 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2928 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2933 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *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 SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *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]));
2955 void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
2957 if (start < 0 || len < 0 || start + len > array->header.size)
2958 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2961 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2965 jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
2967 log_text("JNI-Call: RegisterNatives");
2972 jint UnregisterNatives (JNIEnv* env, jclass clazz)
2974 log_text("JNI-Call: UnregisterNatives");
2978 /******************************* monitor operations ********************************/
2980 jint MonitorEnter (JNIEnv* env, jobject obj)
2982 builtin_monitorenter(obj);
2987 jint MonitorExit (JNIEnv* env, jobject obj)
2989 builtin_monitorexit(obj);
2994 /************************************* JavaVM interface ****************************/
2996 #error CPP mode not supported yet
2998 jint GetJavaVM (JNIEnv* env, JavaVM **vm)
3000 log_text("JNI-Call: GetJavaVM");
3004 #endif /*__cplusplus*/
3006 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3008 log_text("JNI-Call: GetStringRegion");
3012 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3014 log_text("JNI-Call: GetStringUTFRegion");
3018 /************** obtain direct pointer to array elements ***********************/
3020 void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
3022 java_objectheader *s = (java_objectheader*) array;
3023 arraydescriptor *desc = s->vftbl->arraydesc;
3025 if (!desc) return NULL;
3027 return ((u1*)s) + desc->dataoffset;
3031 void ReleasePrimitiveArrayCritical (JNIEnv* env, jarray array, void *carray, jint mode)
3033 log_text("JNI-Call: ReleasePrimitiveArrayCritical");
3038 /**** returns a pointer to an array of Unicode characters of the string *******/
3040 const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
3042 log_text("JNI-Call: GetStringCritical");
3044 return GetStringChars(env,string,isCopy);
3047 /*********** native code no longer needs access to chars **********************/
3049 void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
3051 log_text("JNI-Call: ReleaseStringCritical");
3053 ReleaseStringChars(env,string,cstring);
3057 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3059 log_text("JNI-Call: NewWeakGlobalRef");
3065 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
3067 log_text("JNI-Call: DeleteWeakGlobalRef");
3073 /** Creates a new global reference to the object referred to by the obj argument **/
3075 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
3081 MonitorEnter(env, *global_ref_table);
3083 refcount = CallObjectMethod(env, *global_ref_table, getmid, lobj);
3084 val = (refcount == NULL) ? 0 : CallIntMethod(env, refcount, intvalue);
3085 newval = NewObject(env, intclass, newint, val + 1);
3087 if (newval != NULL) {
3088 CallObjectMethod(env, *global_ref_table, putmid, lobj, newval);
3089 MonitorExit(env, *global_ref_table);
3093 log_text("JNI-NewGlobalRef: unable to create new java.lang.Integer");
3094 MonitorExit(env, *global_ref_table);
3099 /************* Deletes the global reference pointed to by globalRef **************/
3101 void DeleteGlobalRef(JNIEnv* env, jobject gref)
3106 MonitorEnter(env, *global_ref_table);
3107 refcount = CallObjectMethod(env, *global_ref_table, getmid, gref);
3109 if (refcount == NULL) {
3110 log_text("JNI-DeleteGlobalRef: unable to find global reference");
3114 val = CallIntMethod(env, refcount, intvalue);
3118 CallObjectMethod(env, *global_ref_table, removemid,refcount);
3121 jobject newval = NewObject(env, intclass, newint, val);
3123 if (newval != NULL) {
3124 CallObjectMethod(env,*global_ref_table, putmid,newval);
3127 log_text("JNI-DeleteGlobalRef: unable to create new java.lang.Integer");
3131 MonitorExit(env,*global_ref_table);
3134 /******************************* check for pending exception ***********************/
3137 jboolean ExceptionCheck(JNIEnv* env)
3139 log_text("JNI-Call: ExceptionCheck");
3141 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
3149 jint DestroyJavaVM(JavaVM *vm)
3151 log_text("DestroyJavaVM called");
3157 jint AttachCurrentThread(JavaVM *vm, void **par1, void *par2)
3159 log_text("AttachCurrentThread called");
3165 jint DetachCurrentThread(JavaVM *vm)
3167 log_text("DetachCurrentThread called");
3173 jint GetEnv(JavaVM *vm, void **environment, jint jniversion)
3175 *environment = &env;
3181 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
3183 log_text("AttachCurrentThreadAsDaemon called");
3188 /************* JNI Initialization ****************************************************/
3190 jobject jni_init1(JNIEnv* env, jobject lobj) {
3191 #if defined(USE_THREADS)
3192 while (initrunning) {yieldThread();} /* wait until init is done */
3194 if (global_ref_table == NULL) {
3197 #if defined(USE_THREADS)
3199 /* wait until jni_init is done */
3200 MonitorEnter(env, *global_ref_table) ;
3201 MonitorExit(env, *global_ref_table);
3204 return NewGlobalRef(env, lobj);
3206 void jni_init2(JNIEnv* env, jobject gref) {
3207 log_text("DeleteGlobalref called before NewGlobalref");
3208 #if defined(USE_THREADS)
3209 while (initrunning) {yieldThread();} /* wait until init is done */
3211 if (global_ref_table == NULL) {
3214 #if defined(USE_THREADS)
3216 /* wait until jni_init is done */
3217 MonitorEnter(env, *global_ref_table) ;
3218 MonitorExit(env, *global_ref_table);
3221 DeleteGlobalRef(env, gref);
3228 log_text("JNI-Init: initialize global_ref_table");
3229 // initalize global reference table
3230 ihmclass = FindClass(NULL, "java/util/IdentityHashMap");
3232 if (ihmclass == NULL) {
3233 log_text("JNI-Init: unable to find java.util.IdentityHashMap");
3236 mid = GetMethodID(NULL, ihmclass, "<init>","()V");
3238 log_text("JNI-Init: unable to find constructor in java.util.IdentityHashMap");
3241 global_ref_table = (jobject*)heap_allocate(sizeof(jobject),true,NULL);
3243 *global_ref_table = NewObject(NULL,ihmclass,mid);
3245 if (*global_ref_table == NULL) {
3246 log_text("JNI-Init: unable to create new global_ref_table");
3249 initrunning = false;
3251 getmid = GetMethodID(NULL, ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3253 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3256 getmid = GetMethodID(NULL ,ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3257 if (getmid == NULL) {
3258 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3261 putmid = GetMethodID(NULL, ihmclass, "put","(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
3262 if (putmid == NULL) {
3263 log_text("JNI-Init: unable to find method \"put\" in java.util.IdentityHashMap");
3266 intclass = FindClass(NULL, "java/lang/Integer");
3267 if (intclass == NULL) {
3268 log_text("JNI-Init: unable to find java.lang.Integer");
3271 newint = GetMethodID(NULL, intclass, "<init>","(I)V");
3272 if (newint == NULL) {
3273 log_text("JNI-Init: unable to find constructor in java.lang.Integer");
3276 intvalue = GetMethodID(NULL, intclass, "intValue","()I");
3277 if (intvalue == NULL) {
3278 log_text("JNI-Init: unable to find method \"intValue\" in java.lang.Integer");
3281 removemid = GetMethodID(NULL, ihmclass, "remove","(Ljava/lang/Object;)Ljava/lang/Object;");
3282 if (removemid == NULL) {
3283 log_text("JNI-DeleteGlobalRef: unable to find method \"remove\" in java.lang.Object");
3286 /* set NewGlobalRef, DeleteGlobalRef envTable entry to real implementation */
3287 envTable.NewGlobalRef = &NewGlobalRef;
3288 envTable.DeleteGlobalRef = &DeleteGlobalRef;
3292 /********************************* JNI invocation table ******************************/
3294 struct _JavaVM javaVMTable={
3299 &AttachCurrentThread,
3300 &DetachCurrentThread,
3302 &AttachCurrentThreadAsDaemon
3305 JavaVM javaVM = &javaVMTable;
3308 /********************************* JNI function table ******************************/
3310 struct JNI_Table envTable = {
3318 &FromReflectedMethod,
3319 &FromReflectedField,
3332 &jni_init1, /* &NewGlobalRef, initialize Global_Ref_Table*/
3333 &jni_init2, /* &DeleteGlobalRef,*/
3337 &EnsureLocalCapacity,
3349 &CallBooleanMethodV,
3350 &CallBooleanMethodA,
3375 &CallNonvirtualObjectMethod,
3376 &CallNonvirtualObjectMethodV,
3377 &CallNonvirtualObjectMethodA,
3378 &CallNonvirtualBooleanMethod,
3379 &CallNonvirtualBooleanMethodV,
3380 &CallNonvirtualBooleanMethodA,
3381 &CallNonvirtualByteMethod,
3382 &CallNonvirtualByteMethodV,
3383 &CallNonvirtualByteMethodA,
3384 &CallNonvirtualCharMethod,
3385 &CallNonvirtualCharMethodV,
3386 &CallNonvirtualCharMethodA,
3387 &CallNonvirtualShortMethod,
3388 &CallNonvirtualShortMethodV,
3389 &CallNonvirtualShortMethodA,
3390 &CallNonvirtualIntMethod,
3391 &CallNonvirtualIntMethodV,
3392 &CallNonvirtualIntMethodA,
3393 &CallNonvirtualLongMethod,
3394 &CallNonvirtualLongMethodV,
3395 &CallNonvirtualLongMethodA,
3396 &CallNonvirtualFloatMethod,
3397 &CallNonvirtualFloatMethodV,
3398 &CallNonvirtualFloatMethodA,
3399 &CallNonvirtualDoubleMethod,
3400 &CallNonvirtualDoubleMethodV,
3401 &CallNonvirtualDoubleMethodA,
3402 &CallNonvirtualVoidMethod,
3403 &CallNonvirtualVoidMethodV,
3404 &CallNonvirtualVoidMethodA,
3425 &CallStaticObjectMethod,
3426 &CallStaticObjectMethodV,
3427 &CallStaticObjectMethodA,
3428 &CallStaticBooleanMethod,
3429 &CallStaticBooleanMethodV,
3430 &CallStaticBooleanMethodA,
3431 &CallStaticByteMethod,
3432 &CallStaticByteMethodV,
3433 &CallStaticByteMethodA,
3434 &CallStaticCharMethod,
3435 &CallStaticCharMethodV,
3436 &CallStaticCharMethodA,
3437 &CallStaticShortMethod,
3438 &CallStaticShortMethodV,
3439 &CallStaticShortMethodA,
3440 &CallStaticIntMethod,
3441 &CallStaticIntMethodV,
3442 &CallStaticIntMethodA,
3443 &CallStaticLongMethod,
3444 &CallStaticLongMethodV,
3445 &CallStaticLongMethodA,
3446 &CallStaticFloatMethod,
3447 &CallStaticFloatMethodV,
3448 &CallStaticFloatMethodA,
3449 &CallStaticDoubleMethod,
3450 &CallStaticDoubleMethodV,
3451 &CallStaticDoubleMethodA,
3452 &CallStaticVoidMethod,
3453 &CallStaticVoidMethodV,
3454 &CallStaticVoidMethodA,
3456 &GetStaticObjectField,
3457 &GetStaticBooleanField,
3458 &GetStaticByteField,
3459 &GetStaticCharField,
3460 &GetStaticShortField,
3462 &GetStaticLongField,
3463 &GetStaticFloatField,
3464 &GetStaticDoubleField,
3465 &SetStaticObjectField,
3466 &SetStaticBooleanField,
3467 &SetStaticByteField,
3468 &SetStaticCharField,
3469 &SetStaticShortField,
3471 &SetStaticLongField,
3472 &SetStaticFloatField,
3473 &SetStaticDoubleField,
3477 &ReleaseStringChars,
3479 &GetStringUTFLength,
3481 &ReleaseStringUTFChars,
3484 &GetObjectArrayElement,
3485 &SetObjectArrayElement,
3494 &GetBooleanArrayElements,
3495 &GetByteArrayElements,
3496 &GetCharArrayElements,
3497 &GetShortArrayElements,
3498 &GetIntArrayElements,
3499 &GetLongArrayElements,
3500 &GetFloatArrayElements,
3501 &GetDoubleArrayElements,
3502 &ReleaseBooleanArrayElements,
3503 &ReleaseByteArrayElements,
3504 &ReleaseCharArrayElements,
3505 &ReleaseShortArrayElements,
3506 &ReleaseIntArrayElements,
3507 &ReleaseLongArrayElements,
3508 &ReleaseFloatArrayElements,
3509 &ReleaseDoubleArrayElements,
3510 &GetBooleanArrayRegion,
3511 &GetByteArrayRegion,
3512 &GetCharArrayRegion,
3513 &GetShortArrayRegion,
3515 &GetLongArrayRegion,
3516 &GetFloatArrayRegion,
3517 &GetDoubleArrayRegion,
3518 &SetBooleanArrayRegion,
3519 &SetByteArrayRegion,
3520 &SetCharArrayRegion,
3521 &SetShortArrayRegion,
3523 &SetLongArrayRegion,
3524 &SetFloatArrayRegion,
3525 &SetDoubleArrayRegion,
3532 &GetStringUTFRegion,
3533 &GetPrimitiveArrayCritical,
3534 &ReleasePrimitiveArrayCritical,
3536 &ReleaseStringCritical,
3538 &DeleteWeakGlobalRef,
3542 JNIEnv env = &envTable;
3545 jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID, jobject obj, java_objectarray *params)
3552 if (methodID == 0) {
3553 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
3557 argcount = get_parametercount(methodID);
3559 if (obj && (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
3560 *exceptionptr = new_exception_message(string_java_lang_IllegalArgumentException,
3561 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
3568 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3569 log_text("Too many arguments. invokeNativeHelper does not support that");
3574 if (((!params) && (argcount != 0)) || (params && (params->header.size != argcount))) {
3575 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3580 if (!(methodID->flags & ACC_STATIC) && (!obj)) {
3581 *exceptionptr = new_exception_message(string_java_lang_NullPointerException,
3582 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
3586 if ((methodID->flags & ACC_STATIC) && (obj)) obj = 0;
3588 blk = MNEW(jni_callblock, /*4 */argcount+2);
3590 retT = fill_callblock_objA(obj, methodID->descriptor, blk, params);
3594 (void) asm_calljavafunction2(methodID,
3596 (argcount + 1) * sizeof(jni_callblock),
3598 retVal = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
3603 intVal = (s4) asm_calljavafunction2(methodID,
3605 (argcount + 1) * sizeof(jni_callblock),
3607 retVal = builtin_new(class_new(utf_new_char("java/lang/Integer")));
3610 class_resolvemethod(retVal->vftbl->class,
3611 utf_new_char("<init>"),
3612 utf_new_char("(I)V")),
3619 intVal = (s4) asm_calljavafunction2(methodID,
3621 (argcount + 1) * sizeof(jni_callblock),
3623 retVal = builtin_new(class_new(utf_new_char("java/lang/Byte")));
3626 class_resolvemethod(retVal->vftbl->class,
3627 utf_new_char("<init>"),
3628 utf_new_char("(B)V")),
3635 intVal = (s4) asm_calljavafunction2(methodID,
3637 (argcount + 1) * sizeof(jni_callblock),
3639 retVal = builtin_new(class_new(utf_new_char("java/lang/Character")));
3642 class_resolvemethod(retVal->vftbl->class,
3643 utf_new_char("<init>"),
3644 utf_new_char("(C)V")),
3651 intVal = (s4) asm_calljavafunction2(methodID,
3653 (argcount + 1) * sizeof(jni_callblock),
3655 retVal = builtin_new(class_new(utf_new_char("java/lang/Short")));
3658 class_resolvemethod(retVal->vftbl->class,
3659 utf_new_char("<init>"),
3660 utf_new_char("(S)V")),
3667 intVal = (s4) asm_calljavafunction2(methodID,
3669 (argcount + 1) * sizeof(jni_callblock),
3671 retVal = builtin_new(class_new(utf_new_char("java/lang/Boolean")));
3674 class_resolvemethod(retVal->vftbl->class,
3675 utf_new_char("<init>"),
3676 utf_new_char("(Z)V")),
3683 intVal = asm_calljavafunction2long(methodID,
3685 (argcount + 1) * sizeof(jni_callblock),
3687 retVal = builtin_new(class_new(utf_new_char("java/lang/Long")));
3690 class_resolvemethod(retVal->vftbl->class,
3691 utf_new_char("<init>"),
3692 utf_new_char("(J)V")),
3699 floatVal = asm_calljavafunction2double(methodID,
3701 (argcount + 1) * sizeof(jni_callblock),
3703 retVal = builtin_new(class_new(utf_new_char("java/lang/Float")));
3706 class_resolvemethod(retVal->vftbl->class,
3707 utf_new_char("<init>"),
3708 utf_new_char("(F)V")),
3715 floatVal = asm_calljavafunction2double(methodID,
3717 (argcount + 1) * sizeof(jni_callblock),
3719 retVal = builtin_new(class_new(utf_new_char("java/lang/Double")));
3722 class_resolvemethod(retVal->vftbl->class,
3723 utf_new_char("<init>"),
3724 utf_new_char("(D)V")),
3729 case 'L': /* fall through */
3731 retVal = asm_calljavafunction2(methodID,
3733 (argcount + 1) * sizeof(jni_callblock),
3738 /* if this happens the acception has already been set by fill_callblock_objA*/
3739 MFREE(blk, jni_callblock, /*4 */ argcount+2);
3740 return (jobject *) 0;
3743 MFREE(blk, jni_callblock, /* 4 */ argcount+2);
3745 if (*exceptionptr) {
3746 java_objectheader *exceptionToWrap = *exceptionptr;
3748 java_objectheader *ivte;
3750 *exceptionptr = NULL;
3751 ivtec = class_new(utf_new_char("java/lang/reflect/InvocationTargetException"));
3752 ivte = builtin_new(ivtec);
3753 asm_calljavafunction(class_resolvemethod(ivtec,
3754 utf_new_char("<init>"),
3755 utf_new_char("(Ljava/lang/Throwable;)V")),
3761 if (*exceptionptr != NULL)
3762 panic("jni.c: error while creating InvocationTargetException wrapper");
3764 *exceptionptr = ivte;
3767 return (jobject *) retVal;
3774 * These are local overrides for various environment variables in Emacs.
3775 * Please do not remove this and leave it at the end of the file, where
3776 * Emacs will automagically detect them.
3777 * ---------------------------------------------------------------------
3780 * indent-tabs-mode: t