1 /* native/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 1621 2004-11-30 13:06:55Z 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 #define JNI_VERSION 0x00010002
75 #define PTR_TO_ITEM(ptr) ((u8)(size_t)(ptr))
77 static utf* utf_char = 0;
78 static utf* utf_bool = 0;
79 static utf* utf_byte =0;
80 static utf* utf_short = 0;
81 static utf* utf_int = 0;
82 static utf* utf_long = 0;
83 static utf* utf_float = 0;
84 static utf* utf_double = 0;
86 /* global reference table */
87 static jobject *global_ref_table;
88 static bool initrunning=false;
90 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
91 static jmethodID getmid = NULL;
92 static jmethodID putmid = NULL;
93 static jclass intclass = NULL;
94 static jmethodID intvalue = NULL;
95 static jmethodID newint = NULL;
96 static jclass ihmclass = NULL;
97 static jmethodID removemid = NULL;
100 /********************* accessing instance-fields **********************************/
102 #define setField(obj,typ,var,val) *((typ*) ((long int) obj + (long int) var->offset))=val;
103 #define getField(obj,typ,var) *((typ*) ((long int) obj + (long int) var->offset))
104 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) setField(obj,jdatatype,getFieldID_critical(env,clazz,name,sig),val);
108 u4 get_parametercount(methodinfo *m)
110 utf *descr = m->descriptor; /* method-descriptor */
111 char *utf_ptr = descr->text; /* current position in utf-text */
112 char *desc_end = utf_end(descr); /* points behind utf string */
113 u4 parametercount = 0;
116 utf_nextu2(&utf_ptr);
118 /* determine number of parameters */
119 while (*utf_ptr != ')') {
120 get_type(&utf_ptr, desc_end, true);
124 return parametercount;
129 void fill_callblock(void *obj, utf *descr, jni_callblock blk[], va_list data, char ret)
131 char *utf__ptr = descr->text; /* current position in utf-text */
132 char **utf_ptr = &utf__ptr;
133 char *desc_end = utf_end(descr); /* points behind utf string */
139 log_text("fill_callblock");
146 /* determine number of parameters */
148 blk[0].itemtype = TYPE_ADR;
149 blk[0].item = PTR_TO_ITEM(obj);
153 while (**utf_ptr != ')') {
154 if (*utf_ptr >= desc_end)
155 panic("illegal method descriptor");
157 switch (utf_nextu2(utf_ptr)) {
158 /* primitive types */
163 blk[cnt].itemtype = TYPE_INT;
164 blk[cnt].item = (u8) va_arg(data, int);
168 blk[cnt].itemtype = TYPE_INT;
169 dummy = va_arg(data, u4);
170 /*printf("fill_callblock: pos:%d, value:%d\n",cnt,dummy);*/
171 blk[cnt].item = (u8) dummy;
175 blk[cnt].itemtype = TYPE_LNG;
176 blk[cnt].item = (u8) va_arg(data, jlong);
180 blk[cnt].itemtype = TYPE_FLT;
181 *((jfloat *) (&blk[cnt].item)) = (jfloat) va_arg(data, jdouble);
185 blk[cnt].itemtype = TYPE_DBL;
186 *((jdouble *) (&blk[cnt].item)) = (jdouble) va_arg(data, jdouble);
190 panic ("V not allowed as function parameter");
194 while (utf_nextu2(utf_ptr) != ';')
195 blk[cnt].itemtype = TYPE_ADR;
196 blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
203 /* char *start = *utf_ptr; */
205 while ((ch = utf_nextu2(utf_ptr)) == '[')
207 while (utf_nextu2(utf_ptr) != ';') {}
210 ch = utf_nextu2(utf_ptr);
211 blk[cnt].itemtype = TYPE_ADR;
212 blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
219 /*the standard doesn't say anything about return value checking, but it appears to be usefull*/
220 c = utf_nextu2(utf_ptr);
221 c = utf_nextu2(utf_ptr);
222 /*printf("%c %c\n",ret,c);*/
224 if (!((c == 'L') || (c == '[')))
225 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
227 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
231 /* XXX it could be considered if we should do typechecking here in the future */
232 char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_objectarray* params)
234 char *utf__ptr = descr->text; /* current position in utf-text */
235 char **utf_ptr = &utf__ptr;
236 char *desc_end = utf_end(descr); /* points behind utf string */
243 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
247 utf_char=utf_new_char("java/lang/Character");
248 utf_bool=utf_new_char("java/lang/Boolean");
249 utf_byte=utf_new_char("java/lang/Byte");
250 utf_short=utf_new_char("java/lang/Short");
251 utf_int=utf_new_char("java/lang/Integer");
252 utf_long=utf_new_char("java/lang/Long");
253 utf_float=utf_new_char("java/lang/Float");
254 utf_double=utf_new_char("java/lang/Double");
256 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
261 log_text("fill_callblock");
268 /* determine number of parameters */
270 blk[0].itemtype = TYPE_ADR;
271 blk[0].item = PTR_TO_ITEM(obj);
279 while (**utf_ptr != ')') {
280 if (*utf_ptr >= desc_end)
281 panic("illegal method descriptor");
283 /* primitive types */
284 switch (utf_nextu2(utf_ptr)) {
286 param = params->data[cnts];
288 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
291 if (param->vftbl->class->name == utf_byte) {
292 blk[cnt].itemtype = TYPE_INT;
293 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
296 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
302 param = params->data[cnts];
304 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
307 if (param->vftbl->class->name == utf_char) {
308 blk[cnt].itemtype = TYPE_INT;
309 blk[cnt].item = (u8) ((java_lang_Character *) param)->value;
312 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
318 param = params->data[cnts];
320 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
323 if (param->vftbl->class->name == utf_short) {
324 blk[cnt].itemtype = TYPE_INT;
325 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
328 if (param->vftbl->class->name == utf_byte) {
329 blk[cnt].itemtype = TYPE_INT;
330 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
333 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
340 param = params->data[cnts];
342 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
345 if (param->vftbl->class->name == utf_bool) {
346 blk[cnt].itemtype = TYPE_INT;
347 blk[cnt].item = (u8) ((java_lang_Boolean *) param)->value;
350 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
356 /*log_text("fill_callblock_objA: param 'I'");*/
357 param = params->data[cnts];
359 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
362 if (param->vftbl->class->name == utf_int) {
363 blk[cnt].itemtype = TYPE_INT;
364 blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
365 /*printf("INT VALUE :%d\n",((struct java_lang_Integer * )param)->value);*/
367 if (param->vftbl->class->name == utf_short) {
368 blk[cnt].itemtype = TYPE_INT;
369 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
372 if (param->vftbl->class->name == utf_byte) {
373 blk[cnt].itemtype = TYPE_INT;
374 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
377 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
385 param = params->data[cnts];
387 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
390 if (param->vftbl->class->name == utf_long) {
391 blk[cnt].itemtype = TYPE_LNG;
392 blk[cnt].item = (u8) ((java_lang_Long *) param)->value;
395 if (param->vftbl->class->name == utf_int) {
396 blk[cnt].itemtype = TYPE_LNG;
397 blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
400 if (param->vftbl->class->name == utf_short) {
401 blk[cnt].itemtype = TYPE_LNG;
402 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
405 if (param->vftbl->class->name == utf_byte) {
406 blk[cnt].itemtype = TYPE_LNG;
407 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
409 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
419 param = params->data[cnts];
421 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
425 if (param->vftbl->class->name == utf_float) {
426 blk[cnt].itemtype = TYPE_FLT;
427 *((jfloat *) (&blk[cnt].item)) = (jfloat) ((java_lang_Float *) param)->value;
430 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
436 param = params->data[cnts];
438 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
442 if (param->vftbl->class->name == utf_double) {
443 blk[cnt].itemtype = TYPE_DBL;
444 *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
447 if (param->vftbl->class->name == utf_float) {
448 blk[cnt].itemtype = TYPE_DBL;
449 *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
452 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
459 panic("V not allowed as function parameter");
464 char *start = (*utf_ptr) - 1;
467 while (utf_nextu2(utf_ptr) != ';')
468 end = (*utf_ptr) + 1;
470 if (!builtin_instanceof(params->data[cnts], class_from_descriptor(start, end, 0, CLASSLOAD_LOAD))) {
471 if (params->data[cnts] != 0) {
472 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
477 blk[cnt].itemtype = TYPE_ADR;
478 blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
484 char *start = (*utf_ptr) - 1;
488 while ((ch = utf_nextu2(utf_ptr)) == '[')
490 while (utf_nextu2(utf_ptr) != ';') {}
493 end = (*utf_ptr) - 1;
494 ch = utf_nextu2(utf_ptr);
496 if (!builtin_arrayinstanceof(params->data[cnts], class_from_descriptor(start, end, 0, CLASSLOAD_LOAD)->vftbl)) {
497 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
501 blk[cnt].itemtype = TYPE_ADR;
502 blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
510 c = utf_nextu2(utf_ptr);
511 c = utf_nextu2(utf_ptr);
512 return c; /*return type needed usage of the right lowlevel methods*/
529 jmethodID get_virtual(jobject obj,jmethodID methodID) {
530 if (obj->vftbl->class==methodID->class) return methodID;
531 return class_resolvemethod (obj->vftbl->class, methodID->name, methodID->descriptor);
534 jmethodID get_nonvirtual(jclass clazz,jmethodID methodID) {
535 if (clazz==methodID->class) return methodID;
536 /*class_resolvemethod -> classfindmethod? (JOWENN)*/
537 return class_resolvemethod (clazz, methodID->name, methodID->descriptor);
542 jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
551 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
555 argcount = get_parametercount(methodID);
557 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
558 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
559 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
563 if (obj && !builtin_instanceof(obj, methodID->class)) {
564 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
571 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
572 log_text("Too many arguments. CallObjectMethod does not support that");
577 blk = MNEW(jni_callblock, /*4 */argcount+2);
579 fill_callblock(obj, methodID->descriptor, blk, args, 'O');
580 /* printf("parameter: obj: %p",blk[0].item); */
581 ret = asm_calljavafunction2(methodID,
583 (argcount + 1) * sizeof(jni_callblock),
585 MFREE(blk, jni_callblock, argcount + 1);
586 /* printf("(CallObjectMethodV)-->%p\n",ret); */
593 core function for integer class methods (bool, byte, short, integer)
594 This is basically needed for i386
596 jint callIntegerMethod(jobject obj, jmethodID methodID, char retType, va_list args)
602 /* printf("%p, %c\n",retType,methodID,retType);*/
605 log_text("JNI-Call: CallObjectMethodV");
606 utf_display(methodID->name);
607 utf_display(methodID->descriptor);
608 printf("\nParmaeter count: %d\n",argcount);
609 utf_display(obj->vftbl->class->name);
613 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
617 argcount = get_parametercount(methodID);
619 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
620 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
621 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
625 if (obj && !builtin_instanceof(obj, methodID->class)) {
626 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
632 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
633 log_text("Too many arguments. CallIntegerMethod does not support that");
638 blk = MNEW(jni_callblock, /*4 */ argcount+2);
640 fill_callblock(obj, methodID->descriptor, blk, args, retType);
642 /* printf("parameter: obj: %p",blk[0].item); */
643 ret = (jint) asm_calljavafunction2(methodID,
645 (argcount + 1) * sizeof(jni_callblock),
648 MFREE(blk, jni_callblock, argcount + 1);
649 /* printf("(CallObjectMethodV)-->%p\n",ret); */
655 /*core function for long class functions*/
656 jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
663 log_text("JNI-Call: CallObjectMethodV");
664 utf_display(methodID->name);
665 utf_display(methodID->descriptor);
666 printf("\nParmaeter count: %d\n",argcount);
667 utf_display(obj->vftbl->class->name);
671 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
675 argcount = get_parametercount(methodID);
677 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
678 ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
679 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
683 if (obj && !builtin_instanceof(obj,methodID->class)) {
684 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
690 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
691 log_text("Too many arguments. CallObjectMethod does not support that");
696 blk = MNEW(jni_callblock,/* 4 */argcount+2);
698 fill_callblock(obj, methodID->descriptor, blk, args, 'J');
700 /* printf("parameter: obj: %p",blk[0].item); */
701 ret = asm_calljavafunction2long(methodID,
703 (argcount + 1) * sizeof(jni_callblock),
706 MFREE(blk, jni_callblock, argcount + 1);
707 /* printf("(CallObjectMethodV)-->%p\n",ret); */
713 /*core function for float class methods (float,double)*/
714 jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,char retType)
716 int argcount = get_parametercount(methodID);
721 log_text("JNI-Call: CallObjectMethodV");
722 utf_display(methodID->name);
723 utf_display(methodID->descriptor);
724 printf("\nParmaeter count: %d\n",argcount);
725 utf_display(obj->vftbl->class->name);
731 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
732 log_text("Too many arguments. CallObjectMethod does not support that");
737 blk = MNEW(jni_callblock, /*4 */ argcount+2);
739 fill_callblock(obj, methodID->descriptor, blk, args, retType);
741 /* printf("parameter: obj: %p",blk[0].item); */
742 ret = asm_calljavafunction2double(methodID,
744 (argcount + 1) * sizeof(jni_callblock),
747 MFREE(blk, jni_callblock, argcount + 1);
748 /* printf("(CallObjectMethodV)-->%p\n",ret); */
754 /*************************** function: jclass_findfield ****************************
756 searches for field with specified name and type in a 'classinfo'-structur
757 if no such field is found NULL is returned
759 ************************************************************************************/
761 fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
764 /* printf(" FieldCount: %d\n",c->fieldscount);
765 utf_display(c->name); */
766 for (i = 0; i < c->fieldscount; i++) {
767 /* utf_display(c->fields[i].name);
769 utf_display(c->fields[i].descriptor);
771 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
772 return &(c->fields[i]);
775 if (c->super) return jclass_findfield(c->super,name,desc);
780 /********************* returns version of native method interface *****************/
782 jint GetVersion (JNIEnv* env)
788 /************** loads a class from a buffer of raw class data *****************/
790 jclass DefineClass(JNIEnv* env, const char *name, jobject loader, const jbyte *buf, jsize len)
796 c = class_new(utf_new_char_classname((char *) name));
798 /* enter a monitor on the class */
800 builtin_monitorenter((java_objectheader *) c);
806 /* build a classbuffer with the given data */
807 cb = NEW(classbuffer);
810 cb->data = (u1 *) buf;
811 cb->pos = cb->data - 1;
813 r = class_load_intern(cb);
815 /* if return value is NULL, we had a problem and the class is not loaded */
819 /* now free the allocated memory, otherwise we could ran into a DOS */
824 FREE(cb, classbuffer);
830 /* leave the monitor */
832 builtin_monitorexit((java_objectheader *) c);
834 /* XXX link the class here? */
835 /* if (class_link(c)) */
839 c->classloader = loader;
845 /*********** loads locally defined class with the specified name **************/
847 jclass FindClass(JNIEnv* env, const char *name)
851 c = class_new(utf_new_char_classname((char *) name));
863 /*******************************************************************************
865 converts java.lang.reflect.Method or
866 java.lang.reflect.Constructor object to a method ID
868 *******************************************************************************/
870 jmethodID FromReflectedMethod(JNIEnv* env, jobject method)
872 /* log_text("JNI-Call: FromReflectedMethod"); */
878 /*************** return superclass of the class represented by sub ****************/
880 jclass GetSuperclass(JNIEnv* env, jclass sub)
884 c = ((classinfo*) sub)->super;
888 use_class_as_object(c);
894 /*********************** check whether sub can be cast to sup ********************/
896 jboolean IsAssignableForm(JNIEnv* env, jclass sub, jclass sup)
898 return builtin_isanysubclass(sub, sup);
902 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
904 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
906 /* log_text("JNI-Call: ToReflectedField"); */
912 /***************** throw java.lang.Throwable object ******************************/
914 jint Throw(JNIEnv* env, jthrowable obj)
916 *exceptionptr = (java_objectheader*) obj;
922 /*******************************************************************************
924 create exception object from the class clazz with the
925 specified message and cause it to be thrown
927 *******************************************************************************/
929 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
931 java_lang_Throwable *o;
933 /* instantiate exception object */
934 o = (java_lang_Throwable *) native_new_and_init((classinfo*) clazz);
938 o->detailMessage = (java_lang_String *) javastring_new_char((char *) msg);
940 *exceptionptr = (java_objectheader *) o;
946 /************************* check if exception occured *****************************/
948 jthrowable ExceptionOccurred (JNIEnv* env)
950 return (jthrowable) *exceptionptr;
953 /********** print exception and a backtrace of the stack (for debugging) **********/
955 void ExceptionDescribe (JNIEnv* env)
957 utf_display((*exceptionptr)->vftbl->class->name);
963 /******************* clear any exception currently being thrown *******************/
965 void ExceptionClear (JNIEnv* env)
967 *exceptionptr = NULL;
971 /********** raises a fatal error and does not expect the VM to recover ************/
973 void FatalError (JNIEnv* env, const char *msg)
978 /******************* creates a new local reference frame **************************/
980 jint PushLocalFrame(JNIEnv* env, jint capacity)
987 /**************** Pops off the current local reference frame **********************/
989 jobject PopLocalFrame(JNIEnv* env, jobject result)
991 log_text("JNI-Call: PopLocalFrame");
998 /*************** Deletes the local reference pointed to by localRef ***************/
1000 void DeleteLocalRef (JNIEnv* env, jobject localRef)
1002 /* log_text("JNI-Call: DeleteLocalRef");*/
1006 /********** Tests whether two references refer to the same Java object ************/
1008 jboolean IsSameObject (JNIEnv* env, jobject obj1, jobject obj2)
1010 return (obj1==obj2);
1013 /***** Creates a new local reference that refers to the same object as ref *******/
1015 jobject NewLocalRef (JNIEnv* env, jobject ref)
1020 /***********************************************************************************
1022 Ensures that at least a given number of local references can
1023 be created in the current thread
1025 **********************************************************************************/
1027 jint EnsureLocalCapacity (JNIEnv* env, jint capacity)
1029 return 0; /* return 0 on success */
1033 /********* Allocates a new Java object without invoking a constructor *************/
1035 jobject AllocObject (JNIEnv* env, jclass clazz)
1037 java_objectheader *o = builtin_new(clazz);
1042 /***********************************************************************************
1044 Constructs a new Java object
1045 arguments that are to be passed to the constructor are placed after methodID
1047 ***********************************************************************************/
1049 jobject NewObject (JNIEnv* env, jclass clazz, jmethodID methodID, ...)
1051 java_objectheader *o;
1053 int argcount=get_parametercount(methodID);
1057 /* log_text("JNI-Call: NewObject"); */
1061 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
1062 log_text("Too many arguments. NewObject does not support that");
1067 o = builtin_new (clazz); /* create object */
1069 if (!o) return NULL;
1071 va_start(vaargs,methodID);
1072 for (i=0;i<argcount;i++) {
1073 args[i]=va_arg(vaargs,void*);
1076 asm_calljavafunction(methodID,o,args[0],args[1],args[2]);
1082 /***********************************************************************************
1084 Constructs a new Java object
1085 arguments that are to be passed to the constructor are placed in va_list args
1087 ***********************************************************************************/
1089 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1091 /* log_text("JNI-Call: NewObjectV"); */
1097 /***********************************************************************************
1099 Constructs a new Java object
1100 arguments that are to be passed to the constructor are placed in
1101 args array of jvalues
1103 ***********************************************************************************/
1105 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1107 /* log_text("JNI-Call: NewObjectA"); */
1113 /************************ returns the class of an object **************************/
1115 jclass GetObjectClass(JNIEnv* env, jobject obj)
1117 classinfo *c = obj->vftbl->class;
1119 use_class_as_object(c);
1125 /************* tests whether an object is an instance of a class ******************/
1127 jboolean IsInstanceOf(JNIEnv* env, jobject obj, jclass clazz)
1129 return builtin_instanceof(obj,clazz);
1133 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1135 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1137 log_text("JNI-Call: FromReflectedField");
1143 /**********************************************************************************
1145 converts a method ID to a java.lang.reflect.Method or
1146 java.lang.reflect.Constructor object
1148 **********************************************************************************/
1150 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1152 log_text("JNI-Call: ToReflectedMethod");
1158 /**************** returns the method ID for an instance method ********************/
1160 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1164 m = class_resolvemethod (
1166 utf_new_char ((char*) name),
1167 utf_new_char ((char*) sig)
1170 if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
1171 else if (m->flags & ACC_STATIC) {
1173 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
1179 /******************** JNI-functions for calling instance methods ******************/
1181 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1186 /* log_text("JNI-Call: CallObjectMethod");*/
1188 va_start(vaargs, methodID);
1189 ret = callObjectMethod(obj, methodID, vaargs);
1196 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1198 return callObjectMethod(obj,methodID,args);
1202 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1204 log_text("JNI-Call: CallObjectMethodA");
1212 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1217 /* log_text("JNI-Call: CallBooleanMethod");*/
1219 va_start(vaargs,methodID);
1220 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',vaargs);
1226 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1228 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',args);
1232 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1234 log_text("JNI-Call: CallBooleanMethodA");
1239 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1244 /* log_text("JNI-Call: CallVyteMethod");*/
1246 va_start(vaargs,methodID);
1247 ret = callIntegerMethod(obj,get_virtual(obj,methodID),'B',vaargs);
1253 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1255 /* log_text("JNI-Call: CallByteMethodV");*/
1256 return callIntegerMethod(obj,methodID,'B',args);
1260 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1262 log_text("JNI-Call: CallByteMethodA");
1268 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1273 /* log_text("JNI-Call: CallCharMethod");*/
1275 va_start(vaargs,methodID);
1276 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'C', vaargs);
1283 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1285 /* log_text("JNI-Call: CallCharMethodV");*/
1286 return callIntegerMethod(obj,get_virtual(obj,methodID),'C',args);
1290 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1292 log_text("JNI-Call: CallCharMethodA");
1298 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1303 /* log_text("JNI-Call: CallShortMethod");*/
1305 va_start(vaargs, methodID);
1306 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'S', vaargs);
1313 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1315 return callIntegerMethod(obj, get_virtual(obj, methodID), 'S', args);
1319 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1321 log_text("JNI-Call: CallShortMethodA");
1328 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1333 va_start(vaargs,methodID);
1334 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'I', vaargs);
1341 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1343 return callIntegerMethod(obj, get_virtual(obj, methodID), 'I', args);
1347 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1349 log_text("JNI-Call: CallIntMethodA");
1356 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1361 va_start(vaargs,methodID);
1362 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1369 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1371 return callLongMethod(obj,get_virtual(obj, methodID),args);
1375 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1377 log_text("JNI-Call: CallLongMethodA");
1384 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1389 /* log_text("JNI-Call: CallFloatMethod");*/
1391 va_start(vaargs,methodID);
1392 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'F');
1399 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1401 log_text("JNI-Call: CallFloatMethodV");
1402 return callFloatMethod(obj, get_virtual(obj, methodID), args, 'F');
1406 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1408 log_text("JNI-Call: CallFloatMethodA");
1415 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1420 /* log_text("JNI-Call: CallDoubleMethod");*/
1422 va_start(vaargs,methodID);
1423 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'D');
1430 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1432 log_text("JNI-Call: CallDoubleMethodV");
1433 return callFloatMethod(obj, get_virtual(obj, methodID), args, 'D');
1437 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1439 log_text("JNI-Call: CallDoubleMethodA");
1445 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1449 /* log_text("JNI-Call: CallVoidMethod");*/
1451 va_start(vaargs,methodID);
1452 (void) callIntegerMethod(obj, get_virtual(obj, methodID), 'V', vaargs);
1457 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1459 log_text("JNI-Call: CallVoidMethodV");
1460 (void)callIntegerMethod(obj,get_virtual(obj,methodID),'V',args);
1464 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1466 log_text("JNI-Call: CallVoidMethodA");
1471 jobject CallNonvirtualObjectMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1473 log_text("JNI-Call: CallNonvirtualObjectMethod");
1479 jobject CallNonvirtualObjectMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1481 log_text("JNI-Call: CallNonvirtualObjectMethodV");
1487 jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1489 log_text("JNI-Call: CallNonvirtualObjectMethodA");
1496 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1501 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1503 va_start(vaargs,methodID);
1504 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',vaargs);
1511 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1513 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1514 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',args);
1518 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1520 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1527 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1532 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1534 va_start(vaargs,methodID);
1535 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',vaargs);
1541 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1543 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1544 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',args);
1549 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1551 log_text("JNI-Call: CallNonvirtualByteMethodA");
1558 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1563 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1565 va_start(vaargs,methodID);
1566 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',vaargs);
1572 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1574 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1575 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',args);
1579 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1581 log_text("JNI-Call: CallNonvirtualCharMethodA");
1588 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1593 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1595 va_start(vaargs,methodID);
1596 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',vaargs);
1602 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1604 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1605 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',args);
1609 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1611 log_text("JNI-Call: CallNonvirtualShortMethodA");
1618 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1624 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1626 va_start(vaargs,methodID);
1627 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',vaargs);
1633 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1635 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1636 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',args);
1640 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1642 log_text("JNI-Call: CallNonvirtualIntMethodA");
1649 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1651 log_text("JNI-Call: CallNonvirtualLongMethod");
1657 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1659 log_text("JNI-Call: CallNonvirtualLongMethodV");
1665 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1667 log_text("JNI-Call: CallNonvirtualLongMethodA");
1674 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1679 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1682 va_start(vaargs,methodID);
1683 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'F');
1690 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1692 log_text("JNI-Call: CallNonvirtualFloatMethodV");
1693 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'F');
1697 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1699 log_text("JNI-Call: CallNonvirtualFloatMethodA");
1706 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1710 log_text("JNI-Call: CallNonvirtualDoubleMethod");
1712 va_start(vaargs,methodID);
1713 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'D');
1720 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1722 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
1723 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'D');
1727 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1729 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
1736 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1740 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
1742 va_start(vaargs,methodID);
1743 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',vaargs);
1749 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1751 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
1753 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',args);
1758 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1760 log_text("JNI-Call: CallNonvirtualVoidMethodA");
1763 /************************* JNI-functions for accessing fields ************************/
1765 jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
1769 /* log_text("========================= searching for:");
1772 f = jclass_findfield(clazz,
1773 utf_new_char ((char*) name),
1774 utf_new_char ((char*) sig)
1778 utf_display(clazz->name);
1781 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
1786 /*************************** retrieve fieldid, abort on error ************************/
1788 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
1790 jfieldID id = GetFieldID(env, clazz, name, sig);
1794 utf_display(clazz->name);
1795 log_text("\nfield:");
1800 panic("setfield_critical failed");
1805 jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
1807 jobject dbg,dretval,*dpretval;
1808 long int dli1, dli2, dli3;
1810 /* printf("GetObjectField(1): thread: %s obj: %p name: %s desc: %s \n",GetStringUTFChars(env,
1811 ((threadobject *) THREADOBJECT)->o
1813 ,obj,((fieldinfo*)fieldID)->name->text,(fieldID->descriptor)->text);*/
1815 dbg = getField(obj,jobject,fieldID);
1816 dli1 = (long int) obj;
1817 dli2 = (long int) fieldID->offset;
1819 dpretval = (jobject*) dli3;
1820 dretval = *dpretval;
1825 tmp = FindClass(env, "java/lang/Object");
1826 mid = GetMethodID(env,tmp,"toString","()Ljava/lang/String;");
1827 jstr = CallObjectMethod(env,dbg,mid);*/
1829 /* printf("GetObjectField(2): retval %p (obj: %#lx + offset: %#lx = %#lx (jobject*) %p (jobject) %p\n"
1830 ,dbg, dli1, dli2, dli3,dpretval, dretval);*/
1836 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
1838 return getField(obj,jboolean,fieldID);
1842 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
1844 return getField(obj,jbyte,fieldID);
1848 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
1850 return getField(obj,jchar,fieldID);
1854 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
1856 return getField(obj,jshort,fieldID);
1860 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
1862 return getField(obj,jint,fieldID);
1866 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
1868 return getField(obj,jlong,fieldID);
1872 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
1874 return getField(obj,jfloat,fieldID);
1878 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
1880 return getField(obj,jdouble,fieldID);
1883 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
1885 setField(obj,jobject,fieldID,val);
1889 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
1891 setField(obj,jboolean,fieldID,val);
1895 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
1897 setField(obj,jbyte,fieldID,val);
1901 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
1903 setField(obj,jchar,fieldID,val);
1907 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
1909 setField(obj,jshort,fieldID,val);
1913 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
1915 setField(obj,jint,fieldID,val);
1919 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
1921 setField(obj,jlong,fieldID,val);
1925 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
1927 setField(obj,jfloat,fieldID,val);
1931 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
1933 setField(obj,jdouble,fieldID,val);
1937 /**************** JNI-functions for calling static methods **********************/
1939 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
1943 m = class_resolvemethod(clazz,
1944 utf_new_char((char *) name),
1945 utf_new_char((char *) sig));
1947 if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
1948 else if (!(m->flags & ACC_STATIC)) {
1950 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
1957 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1962 /* log_text("JNI-Call: CallStaticObjectMethod");*/
1964 va_start(vaargs, methodID);
1965 ret = callObjectMethod(0, methodID, vaargs);
1972 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
1974 /* log_text("JNI-Call: CallStaticObjectMethodV"); */
1976 return callObjectMethod(0,methodID,args);
1980 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
1982 log_text("JNI-Call: CallStaticObjectMethodA");
1988 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1993 va_start(vaargs, methodID);
1994 ret = (jboolean) callIntegerMethod(0, methodID, 'Z', vaargs);
2001 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2003 return (jboolean) callIntegerMethod(0, methodID, 'Z', args);
2007 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2009 log_text("JNI-Call: CallStaticBooleanMethodA");
2015 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2020 /* log_text("JNI-Call: CallStaticByteMethod");*/
2022 va_start(vaargs, methodID);
2023 ret = (jbyte) callIntegerMethod(0, methodID, 'B', vaargs);
2030 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2032 return (jbyte) callIntegerMethod(0, methodID, 'B', args);
2036 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2038 log_text("JNI-Call: CallStaticByteMethodA");
2044 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2049 /* log_text("JNI-Call: CallStaticByteMethod");*/
2051 va_start(vaargs, methodID);
2052 ret = (jchar) callIntegerMethod(0, methodID, 'C', vaargs);
2059 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2061 return (jchar) callIntegerMethod(0, methodID, 'C', args);
2065 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2067 log_text("JNI-Call: CallStaticCharMethodA");
2074 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2079 /* log_text("JNI-Call: CallStaticByteMethod");*/
2081 va_start(vaargs, methodID);
2082 ret = (jshort) callIntegerMethod(0, methodID, 'S', vaargs);
2089 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2091 /*log_text("JNI-Call: CallStaticShortMethodV");*/
2092 return (jshort) callIntegerMethod(0, methodID, 'S', args);
2096 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2098 log_text("JNI-Call: CallStaticShortMethodA");
2105 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2110 /* log_text("JNI-Call: CallStaticIntMethod");*/
2112 va_start(vaargs, methodID);
2113 ret = callIntegerMethod(0, methodID, 'I', vaargs);
2120 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2122 log_text("JNI-Call: CallStaticIntMethodV");
2124 return callIntegerMethod(0, methodID, 'I', args);
2128 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2130 log_text("JNI-Call: CallStaticIntMethodA");
2137 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2142 /* log_text("JNI-Call: CallStaticLongMethod");*/
2144 va_start(vaargs, methodID);
2145 ret = callLongMethod(0, methodID, vaargs);
2152 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2154 log_text("JNI-Call: CallStaticLongMethodV");
2156 return callLongMethod(0,methodID,args);
2160 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2162 log_text("JNI-Call: CallStaticLongMethodA");
2169 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2174 /* log_text("JNI-Call: CallStaticLongMethod");*/
2176 va_start(vaargs, methodID);
2177 ret = callFloatMethod(0, methodID, vaargs, 'F');
2184 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2187 return callFloatMethod(0, methodID, args, 'F');
2192 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2194 log_text("JNI-Call: CallStaticFloatMethodA");
2201 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2206 /* log_text("JNI-Call: CallStaticDoubleMethod");*/
2208 va_start(vaargs,methodID);
2209 ret = callFloatMethod(0, methodID, vaargs, 'D');
2216 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2218 log_text("JNI-Call: CallStaticDoubleMethodV");
2220 return callFloatMethod(0, methodID, args, 'D');
2224 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2226 log_text("JNI-Call: CallStaticDoubleMethodA");
2232 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2236 /* log_text("JNI-Call: CallStaticVoidMethod");*/
2238 va_start(vaargs, methodID);
2239 (void) callIntegerMethod(0, methodID, 'V', vaargs);
2244 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2246 log_text("JNI-Call: CallStaticVoidMethodV");
2247 (void)callIntegerMethod(0, methodID, 'V', args);
2251 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2253 log_text("JNI-Call: CallStaticVoidMethodA");
2257 /****************** JNI-functions for accessing static fields ********************/
2259 jfieldID GetStaticFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
2263 f = jclass_findfield(clazz,
2264 utf_new_char ((char*) name),
2265 utf_new_char ((char*) sig)
2268 if (!f) *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2274 jobject GetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2277 return fieldID->value.a;
2281 jboolean GetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2284 return fieldID->value.i;
2288 jbyte GetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2291 return fieldID->value.i;
2295 jchar GetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2298 return fieldID->value.i;
2302 jshort GetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2305 return fieldID->value.i;
2309 jint GetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2312 return fieldID->value.i;
2316 jlong GetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2319 return fieldID->value.l;
2323 jfloat GetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2326 return fieldID->value.f;
2330 jdouble GetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2333 return fieldID->value.d;
2338 void SetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2341 fieldID->value.a = value;
2345 void SetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2348 fieldID->value.i = value;
2352 void SetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2355 fieldID->value.i = value;
2359 void SetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2362 fieldID->value.i = value;
2366 void SetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2369 fieldID->value.i = value;
2373 void SetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2376 fieldID->value.i = value;
2380 void SetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2383 fieldID->value.l = value;
2387 void SetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2390 fieldID->value.f = value;
2394 void SetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2397 fieldID->value.d = value;
2401 /***** create new java.lang.String object from an array of Unicode characters ****/
2403 jstring NewString (JNIEnv *env, const jchar *buf, jsize len)
2406 java_lang_String *s;
2409 s = (java_lang_String*) builtin_new (class_java_lang_String);
2410 a = builtin_newarray_char (len);
2412 /* javastring or characterarray could not be created */
2413 if ( (!a) || (!s) ) return NULL;
2416 for (i=0; i<len; i++) a->data[i] = buf[i];
2425 static char emptyString[]="";
2426 static jchar emptyStringJ[]={0,0};
2428 /******************* returns the length of a Java string ***************************/
2430 jsize GetStringLength (JNIEnv *env, jstring str)
2432 return ((java_lang_String*) str)->count;
2436 /******************** convertes javastring to u2-array ****************************/
2438 u2 *javastring_tou2 (jstring so)
2440 java_lang_String *s = (java_lang_String*) so;
2445 if (!s) return NULL;
2448 if (!a) return NULL;
2450 /* allocate memory */
2451 stringbuffer = MNEW( u2 , s->count + 1 );
2454 for (i=0; i<s->count; i++) stringbuffer[i] = a->data[s->offset+i];
2456 /* terminate string */
2457 stringbuffer[i] = '\0';
2459 return stringbuffer;
2462 /********* returns a pointer to an array of Unicode characters of the string *******/
2464 const jchar *GetStringChars (JNIEnv *env, jstring str, jboolean *isCopy)
2466 jchar *jc=javastring_tou2(str);
2469 if (isCopy) *isCopy=JNI_TRUE;
2472 if (isCopy) *isCopy=JNI_TRUE;
2473 return emptyStringJ;
2476 /**************** native code no longer needs access to chars **********************/
2478 void ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars)
2480 if (chars==emptyStringJ) return;
2481 MFREE(((jchar*) chars),jchar,((java_lang_String*) str)->count+1);
2484 /************ create new java.lang.String object from utf8-characterarray **********/
2486 jstring NewStringUTF (JNIEnv *env, const char *utf)
2488 /* log_text("NewStringUTF called");*/
2489 return (jstring) javastring_new(utf_new_char((char *) utf));
2492 /****************** returns the utf8 length in bytes of a string *******************/
2494 jsize GetStringUTFLength (JNIEnv *env, jstring string)
2496 java_lang_String *s = (java_lang_String*) string;
2498 return (jsize) u2_utflength(s->value->data, s->count);
2502 /************ converts a Javastring to an array of UTF-8 characters ****************/
2504 const char* GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
2508 u = javastring_toutf((java_lang_String *) string, false);
2511 *isCopy = JNI_FALSE;
2521 /***************** native code no longer needs access to utf ***********************/
2523 void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
2525 /*we don't release utf chars right now, perhaps that should be done later. Since there is always one reference
2526 the garbage collector will never get them*/
2528 log_text("JNI-Call: ReleaseStringUTFChars");
2529 utf_display(utf_new_char(chars));
2533 /************************** array operations ***************************************/
2535 jsize GetArrayLength(JNIEnv *env, jarray array)
2541 jobjectArray NewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init)
2543 java_objectarray *j;
2546 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2550 j = builtin_anewarray(len, clazz);
2556 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
2560 if (index < array->header.size)
2561 j = array->data[index];
2563 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2569 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
2571 if (index >= array->header.size)
2572 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2575 /* check if the class of value is a subclass of the element class of the array */
2576 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
2577 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
2580 array->data[index] = val;
2586 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
2588 java_booleanarray *j;
2591 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2595 j = builtin_newarray_boolean(len);
2601 jbyteArray NewByteArray(JNIEnv *env, jsize len)
2606 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2610 j = builtin_newarray_byte(len);
2616 jcharArray NewCharArray(JNIEnv *env, jsize len)
2621 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2625 j = builtin_newarray_char(len);
2631 jshortArray NewShortArray(JNIEnv *env, jsize len)
2636 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2640 j = builtin_newarray_short(len);
2646 jintArray NewIntArray(JNIEnv *env, jsize len)
2651 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2655 j = builtin_newarray_int(len);
2661 jlongArray NewLongArray(JNIEnv *env, jsize len)
2666 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2670 j = builtin_newarray_long(len);
2676 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
2681 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2685 j = builtin_newarray_float(len);
2691 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
2693 java_doublearray *j;
2696 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2700 j = builtin_newarray_double(len);
2706 jboolean * GetBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *isCopy)
2708 if (isCopy) *isCopy = JNI_FALSE;
2713 jbyte * GetByteArrayElements (JNIEnv *env, jbyteArray array, jboolean *isCopy)
2715 if (isCopy) *isCopy = JNI_FALSE;
2720 jchar * GetCharArrayElements (JNIEnv *env, jcharArray array, jboolean *isCopy)
2722 if (isCopy) *isCopy = JNI_FALSE;
2727 jshort * GetShortArrayElements (JNIEnv *env, jshortArray array, jboolean *isCopy)
2729 if (isCopy) *isCopy = JNI_FALSE;
2734 jint * GetIntArrayElements (JNIEnv *env, jintArray array, jboolean *isCopy)
2736 if (isCopy) *isCopy = JNI_FALSE;
2741 jlong * GetLongArrayElements (JNIEnv *env, jlongArray array, jboolean *isCopy)
2743 if (isCopy) *isCopy = JNI_FALSE;
2748 jfloat * GetFloatArrayElements (JNIEnv *env, jfloatArray array, jboolean *isCopy)
2750 if (isCopy) *isCopy = JNI_FALSE;
2755 jdouble * GetDoubleArrayElements (JNIEnv *env, jdoubleArray array, jboolean *isCopy)
2757 if (isCopy) *isCopy = JNI_FALSE;
2763 void ReleaseBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode)
2769 void ReleaseByteArrayElements (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode)
2775 void ReleaseCharArrayElements (JNIEnv *env, jcharArray array, jchar *elems, jint mode)
2781 void ReleaseShortArrayElements (JNIEnv *env, jshortArray array, jshort *elems, jint mode)
2787 void ReleaseIntArrayElements (JNIEnv *env, jintArray array, jint *elems, jint mode)
2793 void ReleaseLongArrayElements (JNIEnv *env, jlongArray array, jlong *elems, jint mode)
2799 void ReleaseFloatArrayElements (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode)
2805 void ReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode)
2811 void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *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 GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *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 GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *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 GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *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 GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *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 GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *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 GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *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 GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
2883 if (start < 0 || len < 0 || start+len>array->header.size)
2884 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2887 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2891 void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *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 SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *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]));
2911 void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
2913 if (start < 0 || len < 0 || start + len > array->header.size)
2914 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2917 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2922 void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *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]));
2932 void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
2934 if (start < 0 || len < 0 || start + len > array->header.size)
2935 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2938 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2943 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
2945 if (start < 0 || len < 0 || start + len > array->header.size)
2946 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2949 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2954 void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *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 SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *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]));
2975 jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
2977 log_text("JNI-Call: RegisterNatives");
2982 jint UnregisterNatives (JNIEnv* env, jclass clazz)
2984 log_text("JNI-Call: UnregisterNatives");
2988 /******************************* monitor operations ********************************/
2990 jint MonitorEnter (JNIEnv* env, jobject obj)
2992 builtin_monitorenter(obj);
2997 jint MonitorExit (JNIEnv* env, jobject obj)
2999 builtin_monitorexit(obj);
3004 /************************************* JavaVM interface ****************************/
3006 #error CPP mode not supported yet
3008 jint GetJavaVM (JNIEnv* env, JavaVM **vm)
3010 log_text("JNI-Call: GetJavaVM");
3014 #endif /*__cplusplus*/
3016 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3018 log_text("JNI-Call: GetStringRegion");
3022 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3024 log_text("JNI-Call: GetStringUTFRegion");
3028 /************** obtain direct pointer to array elements ***********************/
3030 void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
3032 java_objectheader *s = (java_objectheader*) array;
3033 arraydescriptor *desc = s->vftbl->arraydesc;
3035 if (!desc) return NULL;
3037 return ((u1*)s) + desc->dataoffset;
3041 void ReleasePrimitiveArrayCritical (JNIEnv* env, jarray array, void *carray, jint mode)
3043 log_text("JNI-Call: ReleasePrimitiveArrayCritical");
3048 /**** returns a pointer to an array of Unicode characters of the string *******/
3050 const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
3052 log_text("JNI-Call: GetStringCritical");
3054 return GetStringChars(env,string,isCopy);
3057 /*********** native code no longer needs access to chars **********************/
3059 void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
3061 log_text("JNI-Call: ReleaseStringCritical");
3063 ReleaseStringChars(env,string,cstring);
3067 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3069 log_text("JNI-Call: NewWeakGlobalRef");
3075 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
3077 log_text("JNI-Call: DeleteWeakGlobalRef");
3083 /** Creates a new global reference to the object referred to by the obj argument **/
3085 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
3091 MonitorEnter(env, *global_ref_table);
3093 refcount = CallObjectMethod(env, *global_ref_table, getmid, lobj);
3094 val = (refcount == NULL) ? 0 : CallIntMethod(env, refcount, intvalue);
3095 newval = NewObject(env, intclass, newint, val + 1);
3097 if (newval != NULL) {
3098 CallObjectMethod(env, *global_ref_table, putmid, lobj, newval);
3099 MonitorExit(env, *global_ref_table);
3103 log_text("JNI-NewGlobalRef: unable to create new java.lang.Integer");
3104 MonitorExit(env, *global_ref_table);
3109 /************* Deletes the global reference pointed to by globalRef **************/
3111 void DeleteGlobalRef(JNIEnv* env, jobject gref)
3116 MonitorEnter(env, *global_ref_table);
3117 refcount = CallObjectMethod(env, *global_ref_table, getmid, gref);
3119 if (refcount == NULL) {
3120 log_text("JNI-DeleteGlobalRef: unable to find global reference");
3124 val = CallIntMethod(env, refcount, intvalue);
3128 CallObjectMethod(env, *global_ref_table, removemid,refcount);
3131 jobject newval = NewObject(env, intclass, newint, val);
3133 if (newval != NULL) {
3134 CallObjectMethod(env,*global_ref_table, putmid,newval);
3137 log_text("JNI-DeleteGlobalRef: unable to create new java.lang.Integer");
3141 MonitorExit(env,*global_ref_table);
3144 /******************************* check for pending exception ***********************/
3147 jboolean ExceptionCheck(JNIEnv* env)
3149 log_text("JNI-Call: ExceptionCheck");
3151 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
3159 jint DestroyJavaVM(JavaVM *vm)
3161 log_text("DestroyJavaVM called");
3167 jint AttachCurrentThread(JavaVM *vm, void **par1, void *par2)
3169 log_text("AttachCurrentThread called");
3175 jint DetachCurrentThread(JavaVM *vm)
3177 log_text("DetachCurrentThread called");
3183 jint GetEnv(JavaVM *vm, void **environment, jint jniversion)
3185 *environment = &env;
3191 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
3193 log_text("AttachCurrentThreadAsDaemon called");
3198 /************* JNI Initialization ****************************************************/
3200 jobject jni_init1(JNIEnv* env, jobject lobj) {
3201 #if defined(USE_THREADS)
3202 while (initrunning) {yieldThread();} /* wait until init is done */
3204 if (global_ref_table == NULL) {
3207 #if defined(USE_THREADS)
3209 /* wait until jni_init is done */
3210 MonitorEnter(env, *global_ref_table) ;
3211 MonitorExit(env, *global_ref_table);
3214 return NewGlobalRef(env, lobj);
3216 void jni_init2(JNIEnv* env, jobject gref) {
3217 log_text("DeleteGlobalref called before NewGlobalref");
3218 #if defined(USE_THREADS)
3219 while (initrunning) {yieldThread();} /* wait until init is done */
3221 if (global_ref_table == NULL) {
3224 #if defined(USE_THREADS)
3226 /* wait until jni_init is done */
3227 MonitorEnter(env, *global_ref_table) ;
3228 MonitorExit(env, *global_ref_table);
3231 DeleteGlobalRef(env, gref);
3238 log_text("JNI-Init: initialize global_ref_table");
3239 /* initalize global reference table */
3240 ihmclass = FindClass(NULL, "java/util/IdentityHashMap");
3242 if (ihmclass == NULL) {
3243 log_text("JNI-Init: unable to find java.util.IdentityHashMap");
3246 mid = GetMethodID(NULL, ihmclass, "<init>","()V");
3248 log_text("JNI-Init: unable to find constructor in java.util.IdentityHashMap");
3251 global_ref_table = (jobject*)heap_allocate(sizeof(jobject),true,NULL);
3253 *global_ref_table = NewObject(NULL,ihmclass,mid);
3255 if (*global_ref_table == NULL) {
3256 log_text("JNI-Init: unable to create new global_ref_table");
3259 initrunning = false;
3261 getmid = GetMethodID(NULL, ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3263 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3266 getmid = GetMethodID(NULL ,ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3267 if (getmid == NULL) {
3268 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3271 putmid = GetMethodID(NULL, ihmclass, "put","(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
3272 if (putmid == NULL) {
3273 log_text("JNI-Init: unable to find method \"put\" in java.util.IdentityHashMap");
3276 intclass = FindClass(NULL, "java/lang/Integer");
3277 if (intclass == NULL) {
3278 log_text("JNI-Init: unable to find java.lang.Integer");
3281 newint = GetMethodID(NULL, intclass, "<init>","(I)V");
3282 if (newint == NULL) {
3283 log_text("JNI-Init: unable to find constructor in java.lang.Integer");
3286 intvalue = GetMethodID(NULL, intclass, "intValue","()I");
3287 if (intvalue == NULL) {
3288 log_text("JNI-Init: unable to find method \"intValue\" in java.lang.Integer");
3291 removemid = GetMethodID(NULL, ihmclass, "remove","(Ljava/lang/Object;)Ljava/lang/Object;");
3292 if (removemid == NULL) {
3293 log_text("JNI-DeleteGlobalRef: unable to find method \"remove\" in java.lang.Object");
3296 /* set NewGlobalRef, DeleteGlobalRef envTable entry to real implementation */
3297 envTable.NewGlobalRef = &NewGlobalRef;
3298 envTable.DeleteGlobalRef = &DeleteGlobalRef;
3302 /********************************* JNI invocation table ******************************/
3304 struct _JavaVM javaVMTable={
3309 &AttachCurrentThread,
3310 &DetachCurrentThread,
3312 &AttachCurrentThreadAsDaemon
3315 JavaVM javaVM = &javaVMTable;
3318 /********************************* JNI function table ******************************/
3320 struct JNI_Table envTable = {
3328 &FromReflectedMethod,
3329 &FromReflectedField,
3342 &jni_init1, /* &NewGlobalRef, initialize Global_Ref_Table*/
3343 &jni_init2, /* &DeleteGlobalRef,*/
3347 &EnsureLocalCapacity,
3359 &CallBooleanMethodV,
3360 &CallBooleanMethodA,
3385 &CallNonvirtualObjectMethod,
3386 &CallNonvirtualObjectMethodV,
3387 &CallNonvirtualObjectMethodA,
3388 &CallNonvirtualBooleanMethod,
3389 &CallNonvirtualBooleanMethodV,
3390 &CallNonvirtualBooleanMethodA,
3391 &CallNonvirtualByteMethod,
3392 &CallNonvirtualByteMethodV,
3393 &CallNonvirtualByteMethodA,
3394 &CallNonvirtualCharMethod,
3395 &CallNonvirtualCharMethodV,
3396 &CallNonvirtualCharMethodA,
3397 &CallNonvirtualShortMethod,
3398 &CallNonvirtualShortMethodV,
3399 &CallNonvirtualShortMethodA,
3400 &CallNonvirtualIntMethod,
3401 &CallNonvirtualIntMethodV,
3402 &CallNonvirtualIntMethodA,
3403 &CallNonvirtualLongMethod,
3404 &CallNonvirtualLongMethodV,
3405 &CallNonvirtualLongMethodA,
3406 &CallNonvirtualFloatMethod,
3407 &CallNonvirtualFloatMethodV,
3408 &CallNonvirtualFloatMethodA,
3409 &CallNonvirtualDoubleMethod,
3410 &CallNonvirtualDoubleMethodV,
3411 &CallNonvirtualDoubleMethodA,
3412 &CallNonvirtualVoidMethod,
3413 &CallNonvirtualVoidMethodV,
3414 &CallNonvirtualVoidMethodA,
3435 &CallStaticObjectMethod,
3436 &CallStaticObjectMethodV,
3437 &CallStaticObjectMethodA,
3438 &CallStaticBooleanMethod,
3439 &CallStaticBooleanMethodV,
3440 &CallStaticBooleanMethodA,
3441 &CallStaticByteMethod,
3442 &CallStaticByteMethodV,
3443 &CallStaticByteMethodA,
3444 &CallStaticCharMethod,
3445 &CallStaticCharMethodV,
3446 &CallStaticCharMethodA,
3447 &CallStaticShortMethod,
3448 &CallStaticShortMethodV,
3449 &CallStaticShortMethodA,
3450 &CallStaticIntMethod,
3451 &CallStaticIntMethodV,
3452 &CallStaticIntMethodA,
3453 &CallStaticLongMethod,
3454 &CallStaticLongMethodV,
3455 &CallStaticLongMethodA,
3456 &CallStaticFloatMethod,
3457 &CallStaticFloatMethodV,
3458 &CallStaticFloatMethodA,
3459 &CallStaticDoubleMethod,
3460 &CallStaticDoubleMethodV,
3461 &CallStaticDoubleMethodA,
3462 &CallStaticVoidMethod,
3463 &CallStaticVoidMethodV,
3464 &CallStaticVoidMethodA,
3466 &GetStaticObjectField,
3467 &GetStaticBooleanField,
3468 &GetStaticByteField,
3469 &GetStaticCharField,
3470 &GetStaticShortField,
3472 &GetStaticLongField,
3473 &GetStaticFloatField,
3474 &GetStaticDoubleField,
3475 &SetStaticObjectField,
3476 &SetStaticBooleanField,
3477 &SetStaticByteField,
3478 &SetStaticCharField,
3479 &SetStaticShortField,
3481 &SetStaticLongField,
3482 &SetStaticFloatField,
3483 &SetStaticDoubleField,
3487 &ReleaseStringChars,
3489 &GetStringUTFLength,
3491 &ReleaseStringUTFChars,
3494 &GetObjectArrayElement,
3495 &SetObjectArrayElement,
3504 &GetBooleanArrayElements,
3505 &GetByteArrayElements,
3506 &GetCharArrayElements,
3507 &GetShortArrayElements,
3508 &GetIntArrayElements,
3509 &GetLongArrayElements,
3510 &GetFloatArrayElements,
3511 &GetDoubleArrayElements,
3512 &ReleaseBooleanArrayElements,
3513 &ReleaseByteArrayElements,
3514 &ReleaseCharArrayElements,
3515 &ReleaseShortArrayElements,
3516 &ReleaseIntArrayElements,
3517 &ReleaseLongArrayElements,
3518 &ReleaseFloatArrayElements,
3519 &ReleaseDoubleArrayElements,
3520 &GetBooleanArrayRegion,
3521 &GetByteArrayRegion,
3522 &GetCharArrayRegion,
3523 &GetShortArrayRegion,
3525 &GetLongArrayRegion,
3526 &GetFloatArrayRegion,
3527 &GetDoubleArrayRegion,
3528 &SetBooleanArrayRegion,
3529 &SetByteArrayRegion,
3530 &SetCharArrayRegion,
3531 &SetShortArrayRegion,
3533 &SetLongArrayRegion,
3534 &SetFloatArrayRegion,
3535 &SetDoubleArrayRegion,
3542 &GetStringUTFRegion,
3543 &GetPrimitiveArrayCritical,
3544 &ReleasePrimitiveArrayCritical,
3546 &ReleaseStringCritical,
3548 &DeleteWeakGlobalRef,
3552 JNIEnv env = &envTable;
3555 jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID, jobject obj, java_objectarray *params)
3562 if (methodID == 0) {
3563 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
3567 argcount = get_parametercount(methodID);
3569 if (obj && (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
3570 *exceptionptr = new_exception_message(string_java_lang_IllegalArgumentException,
3571 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
3578 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3579 log_text("Too many arguments. invokeNativeHelper does not support that");
3584 if (((!params) && (argcount != 0)) || (params && (params->header.size != argcount))) {
3585 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3590 if (!(methodID->flags & ACC_STATIC) && (!obj)) {
3592 new_exception_message(string_java_lang_NullPointerException,
3593 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
3597 if ((methodID->flags & ACC_STATIC) && (obj)) obj = 0;
3599 blk = MNEW(jni_callblock, /*4 */argcount+2);
3601 retT = fill_callblock_objA(obj, methodID->descriptor, blk, params);
3605 (void) asm_calljavafunction2(methodID,
3607 (argcount + 1) * sizeof(jni_callblock),
3609 retVal = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
3614 intVal = (s4) asm_calljavafunction2(methodID,
3616 (argcount + 1) * sizeof(jni_callblock),
3618 retVal = builtin_new(class_new(utf_new_char("java/lang/Integer")));
3621 class_resolvemethod(retVal->vftbl->class,
3622 utf_new_char("<init>"),
3623 utf_new_char("(I)V")),
3630 intVal = (s4) asm_calljavafunction2(methodID,
3632 (argcount + 1) * sizeof(jni_callblock),
3634 retVal = builtin_new(class_new(utf_new_char("java/lang/Byte")));
3637 class_resolvemethod(retVal->vftbl->class,
3638 utf_new_char("<init>"),
3639 utf_new_char("(B)V")),
3646 intVal = (s4) asm_calljavafunction2(methodID,
3648 (argcount + 1) * sizeof(jni_callblock),
3650 retVal = builtin_new(class_new(utf_new_char("java/lang/Character")));
3653 class_resolvemethod(retVal->vftbl->class,
3654 utf_new_char("<init>"),
3655 utf_new_char("(C)V")),
3662 intVal = (s4) asm_calljavafunction2(methodID,
3664 (argcount + 1) * sizeof(jni_callblock),
3666 retVal = builtin_new(class_new(utf_new_char("java/lang/Short")));
3669 class_resolvemethod(retVal->vftbl->class,
3670 utf_new_char("<init>"),
3671 utf_new_char("(S)V")),
3678 intVal = (s4) asm_calljavafunction2(methodID,
3680 (argcount + 1) * sizeof(jni_callblock),
3682 retVal = builtin_new(class_new(utf_new_char("java/lang/Boolean")));
3685 class_resolvemethod(retVal->vftbl->class,
3686 utf_new_char("<init>"),
3687 utf_new_char("(Z)V")),
3694 intVal = asm_calljavafunction2long(methodID,
3696 (argcount + 1) * sizeof(jni_callblock),
3698 retVal = builtin_new(class_new(utf_new_char("java/lang/Long")));
3701 class_resolvemethod(retVal->vftbl->class,
3702 utf_new_char("<init>"),
3703 utf_new_char("(J)V")),
3710 floatVal = asm_calljavafunction2double(methodID,
3712 (argcount + 1) * sizeof(jni_callblock),
3714 retVal = builtin_new(class_new(utf_new_char("java/lang/Float")));
3717 class_resolvemethod(retVal->vftbl->class,
3718 utf_new_char("<init>"),
3719 utf_new_char("(F)V")),
3726 floatVal = asm_calljavafunction2double(methodID,
3728 (argcount + 1) * sizeof(jni_callblock),
3730 retVal = builtin_new(class_new(utf_new_char("java/lang/Double")));
3733 class_resolvemethod(retVal->vftbl->class,
3734 utf_new_char("<init>"),
3735 utf_new_char("(D)V")),
3740 case 'L': /* fall through */
3742 retVal = asm_calljavafunction2(methodID,
3744 (argcount + 1) * sizeof(jni_callblock),
3749 /* if this happens the acception has already been set by fill_callblock_objA*/
3750 MFREE(blk, jni_callblock, /*4 */ argcount+2);
3751 return (jobject *) 0;
3754 MFREE(blk, jni_callblock, /* 4 */ argcount+2);
3756 if (*exceptionptr) {
3757 java_objectheader *exceptionToWrap = *exceptionptr;
3759 java_objectheader *ivte;
3761 *exceptionptr = NULL;
3762 ivtec = class_new(utf_new_char("java/lang/reflect/InvocationTargetException"));
3763 ivte = builtin_new(ivtec);
3764 asm_calljavafunction(class_resolvemethod(ivtec,
3765 utf_new_char("<init>"),
3766 utf_new_char("(Ljava/lang/Throwable;)V")),
3772 if (*exceptionptr != NULL)
3773 panic("jni.c: error while creating InvocationTargetException wrapper");
3775 *exceptionptr = ivte;
3778 return (jobject *) retVal;
3785 * These are local overrides for various environment variables in Emacs.
3786 * Please do not remove this and leave it at the end of the file, where
3787 * Emacs will automagically detect them.
3788 * ---------------------------------------------------------------------
3791 * indent-tabs-mode: t