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 1424 2004-10-30 11:15:23Z 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;
79 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
80 static jmethodID getmid = NULL;
81 static jmethodID putmid = NULL;
82 static jclass intclass = NULL;
83 static jmethodID intvalue = NULL;
84 static jmethodID newint = NULL;
85 static jclass ihmclass = NULL;
86 static jmethodID removemid = NULL;
89 /********************* accessing instance-fields **********************************/
91 #define setField(obj,typ,var,val) *((typ*) ((long int) obj + (long int) var->offset))=val;
92 #define getField(obj,typ,var) *((typ*) ((long int) obj + (long int) var->offset))
93 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) setField(obj,jdatatype,getFieldID_critical(env,clazz,name,sig),val);
97 u4 get_parametercount(methodinfo *m)
99 utf *descr = m->descriptor; /* method-descriptor */
100 char *utf_ptr = descr->text; /* current position in utf-text */
101 char *desc_end = utf_end(descr); /* points behind utf string */
102 u4 parametercount = 0;
105 utf_nextu2(&utf_ptr);
107 /* determine number of parameters */
108 while (*utf_ptr != ')') {
109 get_type(&utf_ptr, desc_end, true);
113 return parametercount;
118 void fill_callblock(void *obj, utf *descr, jni_callblock blk[], va_list data, char ret)
120 char *utf__ptr = descr->text; /* current position in utf-text */
121 char **utf_ptr = &utf__ptr;
122 char *desc_end = utf_end(descr); /* points behind utf string */
128 log_text("fill_callblock");
135 /* determine number of parameters */
137 blk[0].itemtype = TYPE_ADR;
138 blk[0].item = PTR_TO_ITEM(obj);
142 while (**utf_ptr != ')') {
143 if (*utf_ptr >= desc_end)
144 panic("illegal method descriptor");
146 switch (utf_nextu2(utf_ptr)) {
147 /* primitive types */
152 blk[cnt].itemtype = TYPE_INT;
153 blk[cnt].item = (u8) va_arg(data, int);
157 blk[cnt].itemtype = TYPE_INT;
158 dummy = va_arg(data, u4);
159 /*printf("fill_callblock: pos:%d, value:%d\n",cnt,dummy);*/
160 blk[cnt].item = (u8) dummy;
164 blk[cnt].itemtype = TYPE_LNG;
165 blk[cnt].item = (u8) va_arg(data, jlong);
169 blk[cnt].itemtype = TYPE_FLT;
170 *((jfloat *) (&blk[cnt].item)) = (jfloat) va_arg(data, jdouble);
174 blk[cnt].itemtype = TYPE_DBL;
175 *((jdouble *) (&blk[cnt].item)) = (jdouble) va_arg(data, jdouble);
179 panic ("V not allowed as function parameter");
183 while (utf_nextu2(utf_ptr) != ';')
184 blk[cnt].itemtype = TYPE_ADR;
185 blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
192 /* char *start = *utf_ptr; */
194 while ((ch = utf_nextu2(utf_ptr)) == '[')
196 while (utf_nextu2(utf_ptr) != ';') {}
199 ch = utf_nextu2(utf_ptr);
200 blk[cnt].itemtype = TYPE_ADR;
201 blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
208 /*the standard doesn't say anything about return value checking, but it appears to be usefull*/
209 c = utf_nextu2(utf_ptr);
210 c = utf_nextu2(utf_ptr);
211 /*printf("%c %c\n",ret,c);*/
213 if (!((c == 'L') || (c == '[')))
214 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
216 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
220 /* XXX it could be considered if we should do typechecking here in the future */
221 char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_objectarray* params)
223 char *utf__ptr = descr->text; /* current position in utf-text */
224 char **utf_ptr = &utf__ptr;
225 char *desc_end = utf_end(descr); /* points behind utf string */
232 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
236 utf_char=utf_new_char("java/lang/Character");
237 utf_bool=utf_new_char("java/lang/Boolean");
238 utf_byte=utf_new_char("java/lang/Byte");
239 utf_short=utf_new_char("java/lang/Short");
240 utf_int=utf_new_char("java/lang/Integer");
241 utf_long=utf_new_char("java/lang/Long");
242 utf_float=utf_new_char("java/lang/Float");
243 utf_double=utf_new_char("java/lang/Double");
245 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
250 log_text("fill_callblock");
257 /* determine number of parameters */
259 blk[0].itemtype = TYPE_ADR;
260 blk[0].item = PTR_TO_ITEM(obj);
268 while (**utf_ptr != ')') {
269 if (*utf_ptr >= desc_end)
270 panic("illegal method descriptor");
272 /* primitive types */
273 switch (utf_nextu2(utf_ptr)) {
275 param = params->data[cnts];
277 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
280 if (param->vftbl->class->name == utf_byte) {
281 blk[cnt].itemtype = TYPE_INT;
282 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
285 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
291 param = params->data[cnts];
293 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
296 if (param->vftbl->class->name == utf_char) {
297 blk[cnt].itemtype = TYPE_INT;
298 blk[cnt].item = (u8) ((java_lang_Character *) param)->value;
301 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
307 param = params->data[cnts];
309 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
312 if (param->vftbl->class->name == utf_short) {
313 blk[cnt].itemtype = TYPE_INT;
314 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
317 if (param->vftbl->class->name == utf_byte) {
318 blk[cnt].itemtype = TYPE_INT;
319 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
322 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
329 param = params->data[cnts];
331 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
334 if (param->vftbl->class->name == utf_bool) {
335 blk[cnt].itemtype = TYPE_INT;
336 blk[cnt].item = (u8) ((java_lang_Boolean *) param)->value;
339 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
345 /*log_text("fill_callblock_objA: param 'I'");*/
346 param = params->data[cnts];
348 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
351 if (param->vftbl->class->name == utf_int) {
352 blk[cnt].itemtype = TYPE_INT;
353 blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
354 /*printf("INT VALUE :%d\n",((struct java_lang_Integer * )param)->value);*/
356 if (param->vftbl->class->name == utf_short) {
357 blk[cnt].itemtype = TYPE_INT;
358 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
361 if (param->vftbl->class->name == utf_byte) {
362 blk[cnt].itemtype = TYPE_INT;
363 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
366 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
374 param = params->data[cnts];
376 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
379 if (param->vftbl->class->name == utf_long) {
380 blk[cnt].itemtype = TYPE_LNG;
381 blk[cnt].item = (u8) ((java_lang_Long *) param)->value;
384 if (param->vftbl->class->name == utf_int) {
385 blk[cnt].itemtype = TYPE_LNG;
386 blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
389 if (param->vftbl->class->name == utf_short) {
390 blk[cnt].itemtype = TYPE_LNG;
391 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
394 if (param->vftbl->class->name == utf_byte) {
395 blk[cnt].itemtype = TYPE_LNG;
396 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
398 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
408 param = params->data[cnts];
410 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
414 if (param->vftbl->class->name == utf_float) {
415 blk[cnt].itemtype = TYPE_FLT;
416 *((jfloat *) (&blk[cnt].item)) = (jfloat) ((java_lang_Float *) param)->value;
419 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
425 param = params->data[cnts];
427 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
431 if (param->vftbl->class->name == utf_double) {
432 blk[cnt].itemtype = TYPE_DBL;
433 *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
436 if (param->vftbl->class->name == utf_float) {
437 blk[cnt].itemtype = TYPE_DBL;
438 *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
441 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
448 panic("V not allowed as function parameter");
453 char *start = (*utf_ptr) - 1;
456 while (utf_nextu2(utf_ptr) != ';')
457 end = (*utf_ptr) + 1;
459 if (!builtin_instanceof(params->data[cnts], class_from_descriptor(start, end, 0, CLASSLOAD_LOAD))) {
460 if (params->data[cnts] != 0) {
461 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
466 blk[cnt].itemtype = TYPE_ADR;
467 blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
473 char *start = (*utf_ptr) - 1;
477 while ((ch = utf_nextu2(utf_ptr)) == '[')
479 while (utf_nextu2(utf_ptr) != ';') {}
482 end = (*utf_ptr) - 1;
483 ch = utf_nextu2(utf_ptr);
485 if (!builtin_arrayinstanceof(params->data[cnts], class_from_descriptor(start, end, 0, CLASSLOAD_LOAD)->vftbl)) {
486 *exceptionptr = new_exception("java/lang/IllegalArgumentException");
490 blk[cnt].itemtype = TYPE_ADR;
491 blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
499 c = utf_nextu2(utf_ptr);
500 c = utf_nextu2(utf_ptr);
501 return c; /*return type needed usage of the right lowlevel methods*/
518 jmethodID get_virtual(jobject obj,jmethodID methodID) {
519 if (obj->vftbl->class==methodID->class) return methodID;
520 return class_resolvemethod (obj->vftbl->class, methodID->name, methodID->descriptor);
523 jmethodID get_nonvirtual(jclass clazz,jmethodID methodID) {
524 if (clazz==methodID->class) return methodID;
525 /*class_resolvemethod -> classfindmethod? (JOWENN)*/
526 return class_resolvemethod (clazz, methodID->name, methodID->descriptor);
531 jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
540 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
544 argcount = get_parametercount(methodID);
546 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
547 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
548 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
552 if (obj && !builtin_instanceof(obj, methodID->class)) {
553 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
560 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
561 log_text("Too many arguments. CallObjectMethod does not support that");
566 blk = MNEW(jni_callblock, 4 /*argcount+2*/);
568 fill_callblock(obj, methodID->descriptor, blk, args, 'O');
569 /* printf("parameter: obj: %p",blk[0].item); */
570 ret = asm_calljavafunction2(methodID,
572 (argcount + 1) * sizeof(jni_callblock),
574 MFREE(blk, jni_callblock, argcount + 1);
575 /* printf("(CallObjectMethodV)-->%p\n",ret); */
582 core function for integer class methods (bool, byte, short, integer)
583 This is basically needed for i386
585 jint callIntegerMethod(jobject obj, jmethodID methodID, char retType, va_list args)
591 /* printf("%p, %c\n",retType,methodID,retType);*/
594 log_text("JNI-Call: CallObjectMethodV");
595 utf_display(methodID->name);
596 utf_display(methodID->descriptor);
597 printf("\nParmaeter count: %d\n",argcount);
598 utf_display(obj->vftbl->class->name);
602 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
606 argcount = get_parametercount(methodID);
608 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
609 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
610 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
614 if (obj && !builtin_instanceof(obj, methodID->class)) {
615 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
621 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
622 log_text("Too many arguments. CallIntegerMethod does not support that");
627 blk = MNEW(jni_callblock, 4 /*argcount+2*/);
629 fill_callblock(obj, methodID->descriptor, blk, args, retType);
631 /* printf("parameter: obj: %p",blk[0].item); */
632 ret = (jint) asm_calljavafunction2(methodID,
634 (argcount + 1) * sizeof(jni_callblock),
637 MFREE(blk, jni_callblock, argcount + 1);
638 /* printf("(CallObjectMethodV)-->%p\n",ret); */
644 /*core function for long class functions*/
645 jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
652 log_text("JNI-Call: CallObjectMethodV");
653 utf_display(methodID->name);
654 utf_display(methodID->descriptor);
655 printf("\nParmaeter count: %d\n",argcount);
656 utf_display(obj->vftbl->class->name);
660 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
664 argcount = get_parametercount(methodID);
666 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
667 ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
668 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
672 if (obj && !builtin_instanceof(obj,methodID->class)) {
673 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
679 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
680 log_text("Too many arguments. CallObjectMethod does not support that");
685 blk = MNEW(jni_callblock, 4 /*argcount+2*/);
687 fill_callblock(obj, methodID->descriptor, blk, args, 'J');
689 /* printf("parameter: obj: %p",blk[0].item); */
690 ret = asm_calljavafunction2long(methodID,
692 (argcount + 1) * sizeof(jni_callblock),
695 MFREE(blk, jni_callblock, argcount + 1);
696 /* printf("(CallObjectMethodV)-->%p\n",ret); */
702 /*core function for float class methods (float,double)*/
703 jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,char retType)
705 int argcount = get_parametercount(methodID);
710 log_text("JNI-Call: CallObjectMethodV");
711 utf_display(methodID->name);
712 utf_display(methodID->descriptor);
713 printf("\nParmaeter count: %d\n",argcount);
714 utf_display(obj->vftbl->class->name);
720 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
721 log_text("Too many arguments. CallObjectMethod does not support that");
726 blk = MNEW(jni_callblock, 4 /*argcount+2*/);
728 fill_callblock(obj, methodID->descriptor, blk, args, retType);
730 /* printf("parameter: obj: %p",blk[0].item); */
731 ret = asm_calljavafunction2double(methodID,
733 (argcount + 1) * sizeof(jni_callblock),
736 MFREE(blk, jni_callblock, argcount + 1);
737 /* printf("(CallObjectMethodV)-->%p\n",ret); */
743 /*************************** function: jclass_findfield ****************************
745 searches for field with specified name and type in a 'classinfo'-structur
746 if no such field is found NULL is returned
748 ************************************************************************************/
750 fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
753 /* printf(" FieldCount: %d\n",c->fieldscount);
754 utf_display(c->name); */
755 for (i = 0; i < c->fieldscount; i++) {
756 /* utf_display(c->fields[i].name);
758 utf_display(c->fields[i].descriptor);
760 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
761 return &(c->fields[i]);
764 if (c->super) return jclass_findfield(c->super,name,desc);
769 /********************* returns version of native method interface *****************/
771 jint GetVersion (JNIEnv* env)
777 /************** loads a class from a buffer of raw class data *****************/
779 jclass DefineClass(JNIEnv* env, const char *name, jobject loader, const jbyte *buf, jsize len)
785 c = class_new(utf_new_char_classname((char *) name));
787 /* enter a monitor on the class */
789 builtin_monitorenter((java_objectheader *) c);
795 /* build a classbuffer with the given data */
796 cb = NEW(classbuffer);
799 cb->data = (u1 *) buf;
800 cb->pos = cb->data - 1;
802 r = class_load_intern(cb);
804 /* if return value is NULL, we had a problem and the class is not loaded */
808 /* now free the allocated memory, otherwise we could ran into a DOS */
813 FREE(cb, classbuffer);
819 /* leave the monitor */
821 builtin_monitorexit((java_objectheader *) c);
823 /* XXX link the class here? */
824 /* if (class_link(c)) */
828 c->classloader = loader;
834 /*********** loads locally defined class with the specified name **************/
836 jclass FindClass(JNIEnv* env, const char *name)
840 c = class_new(utf_new_char_classname((char *) name));
852 /*******************************************************************************
854 converts java.lang.reflect.Method or
855 java.lang.reflect.Constructor object to a method ID
857 *******************************************************************************/
859 jmethodID FromReflectedMethod(JNIEnv* env, jobject method)
861 /* log_text("JNI-Call: FromReflectedMethod"); */
867 /*************** return superclass of the class represented by sub ****************/
869 jclass GetSuperclass(JNIEnv* env, jclass sub)
873 c = ((classinfo*) sub)->super;
877 use_class_as_object(c);
883 /*********************** check whether sub can be cast to sup ********************/
885 jboolean IsAssignableForm(JNIEnv* env, jclass sub, jclass sup)
887 return builtin_isanysubclass(sub, sup);
891 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
893 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
895 /* log_text("JNI-Call: ToReflectedField"); */
901 /***************** throw java.lang.Throwable object ******************************/
903 jint Throw(JNIEnv* env, jthrowable obj)
905 *exceptionptr = (java_objectheader*) obj;
911 /*******************************************************************************
913 create exception object from the class clazz with the
914 specified message and cause it to be thrown
916 *******************************************************************************/
918 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
920 java_lang_Throwable *o;
922 /* instantiate exception object */
923 o = (java_lang_Throwable *) native_new_and_init((classinfo*) clazz);
927 o->detailMessage = (java_lang_String *) javastring_new_char((char *) msg);
929 *exceptionptr = (java_objectheader *) o;
935 /************************* check if exception occured *****************************/
937 jthrowable ExceptionOccurred (JNIEnv* env)
939 return (jthrowable) *exceptionptr;
942 /********** print exception and a backtrace of the stack (for debugging) **********/
944 void ExceptionDescribe (JNIEnv* env)
946 utf_display((*exceptionptr)->vftbl->class->name);
952 /******************* clear any exception currently being thrown *******************/
954 void ExceptionClear (JNIEnv* env)
956 *exceptionptr = NULL;
960 /********** raises a fatal error and does not expect the VM to recover ************/
962 void FatalError (JNIEnv* env, const char *msg)
967 /******************* creates a new local reference frame **************************/
969 jint PushLocalFrame(JNIEnv* env, jint capacity)
976 /**************** Pops off the current local reference frame **********************/
978 jobject PopLocalFrame(JNIEnv* env, jobject result)
980 log_text("JNI-Call: PopLocalFrame");
987 /*************** Deletes the local reference pointed to by localRef ***************/
989 void DeleteLocalRef (JNIEnv* env, jobject localRef)
991 /* log_text("JNI-Call: DeleteLocalRef");*/
995 /********** Tests whether two references refer to the same Java object ************/
997 jboolean IsSameObject (JNIEnv* env, jobject obj1, jobject obj2)
1002 /***** Creates a new local reference that refers to the same object as ref *******/
1004 jobject NewLocalRef (JNIEnv* env, jobject ref)
1009 /***********************************************************************************
1011 Ensures that at least a given number of local references can
1012 be created in the current thread
1014 **********************************************************************************/
1016 jint EnsureLocalCapacity (JNIEnv* env, jint capacity)
1018 return 0; /* return 0 on success */
1022 /********* Allocates a new Java object without invoking a constructor *************/
1024 jobject AllocObject (JNIEnv* env, jclass clazz)
1026 java_objectheader *o = builtin_new(clazz);
1031 /***********************************************************************************
1033 Constructs a new Java object
1034 arguments that are to be passed to the constructor are placed after methodID
1036 ***********************************************************************************/
1038 jobject NewObject (JNIEnv* env, jclass clazz, jmethodID methodID, ...)
1040 java_objectheader *o;
1042 int argcount=get_parametercount(methodID);
1046 /* log_text("JNI-Call: NewObject"); */
1050 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
1051 log_text("Too many arguments. NewObject does not support that");
1056 o = builtin_new (clazz); /* create object */
1058 if (!o) return NULL;
1060 va_start(vaargs,methodID);
1061 for (i=0;i<argcount;i++) {
1062 args[i]=va_arg(vaargs,void*);
1065 asm_calljavafunction(methodID,o,args[0],args[1],args[2]);
1071 /***********************************************************************************
1073 Constructs a new Java object
1074 arguments that are to be passed to the constructor are placed in va_list args
1076 ***********************************************************************************/
1078 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1080 /* log_text("JNI-Call: NewObjectV"); */
1086 /***********************************************************************************
1088 Constructs a new Java object
1089 arguments that are to be passed to the constructor are placed in
1090 args array of jvalues
1092 ***********************************************************************************/
1094 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1096 /* log_text("JNI-Call: NewObjectA"); */
1102 /************************ returns the class of an object **************************/
1104 jclass GetObjectClass(JNIEnv* env, jobject obj)
1106 classinfo *c = obj->vftbl->class;
1108 use_class_as_object(c);
1114 /************* tests whether an object is an instance of a class ******************/
1116 jboolean IsInstanceOf(JNIEnv* env, jobject obj, jclass clazz)
1118 return builtin_instanceof(obj,clazz);
1122 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1124 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1126 log_text("JNI-Call: FromReflectedField");
1132 /**********************************************************************************
1134 converts a method ID to a java.lang.reflect.Method or
1135 java.lang.reflect.Constructor object
1137 **********************************************************************************/
1139 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1141 log_text("JNI-Call: ToReflectedMethod");
1147 /**************** returns the method ID for an instance method ********************/
1149 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1153 m = class_resolvemethod (
1155 utf_new_char ((char*) name),
1156 utf_new_char ((char*) sig)
1159 if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
1160 else if (m->flags & ACC_STATIC) {
1162 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
1168 /******************** JNI-functions for calling instance methods ******************/
1170 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1175 /* log_text("JNI-Call: CallObjectMethod");*/
1177 va_start(vaargs, methodID);
1178 ret = callObjectMethod(obj, methodID, vaargs);
1185 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1187 return callObjectMethod(obj,methodID,args);
1191 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1193 log_text("JNI-Call: CallObjectMethodA");
1201 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1206 /* log_text("JNI-Call: CallBooleanMethod");*/
1208 va_start(vaargs,methodID);
1209 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',vaargs);
1215 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1217 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',args);
1221 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1223 log_text("JNI-Call: CallBooleanMethodA");
1228 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1233 /* log_text("JNI-Call: CallVyteMethod");*/
1235 va_start(vaargs,methodID);
1236 ret = callIntegerMethod(obj,get_virtual(obj,methodID),'B',vaargs);
1242 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1244 /* log_text("JNI-Call: CallByteMethodV");*/
1245 return callIntegerMethod(obj,methodID,'B',args);
1249 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1251 log_text("JNI-Call: CallByteMethodA");
1257 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1262 /* log_text("JNI-Call: CallCharMethod");*/
1264 va_start(vaargs,methodID);
1265 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'C', vaargs);
1272 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1274 /* log_text("JNI-Call: CallCharMethodV");*/
1275 return callIntegerMethod(obj,get_virtual(obj,methodID),'C',args);
1279 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1281 log_text("JNI-Call: CallCharMethodA");
1287 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1292 /* log_text("JNI-Call: CallShortMethod");*/
1294 va_start(vaargs, methodID);
1295 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'S', vaargs);
1302 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1304 return callIntegerMethod(obj, get_virtual(obj, methodID), 'S', args);
1308 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1310 log_text("JNI-Call: CallShortMethodA");
1317 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1322 va_start(vaargs,methodID);
1323 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'I', vaargs);
1330 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1332 return callIntegerMethod(obj, get_virtual(obj, methodID), 'I', args);
1336 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1338 log_text("JNI-Call: CallIntMethodA");
1345 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1350 va_start(vaargs,methodID);
1351 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1358 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1360 return callLongMethod(obj,get_virtual(obj, methodID),args);
1364 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1366 log_text("JNI-Call: CallLongMethodA");
1373 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1378 /* log_text("JNI-Call: CallFloatMethod");*/
1380 va_start(vaargs,methodID);
1381 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'F');
1388 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1390 log_text("JNI-Call: CallFloatMethodV");
1391 return callFloatMethod(obj, get_virtual(obj, methodID), args, 'F');
1395 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1397 log_text("JNI-Call: CallFloatMethodA");
1404 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1409 /* log_text("JNI-Call: CallDoubleMethod");*/
1411 va_start(vaargs,methodID);
1412 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'D');
1419 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1421 log_text("JNI-Call: CallDoubleMethodV");
1422 return callFloatMethod(obj, get_virtual(obj, methodID), args, 'D');
1426 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1428 log_text("JNI-Call: CallDoubleMethodA");
1434 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1438 /* log_text("JNI-Call: CallVoidMethod");*/
1440 va_start(vaargs,methodID);
1441 (void) callIntegerMethod(obj, get_virtual(obj, methodID), 'V', vaargs);
1446 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1448 log_text("JNI-Call: CallVoidMethodV");
1449 (void)callIntegerMethod(obj,get_virtual(obj,methodID),'V',args);
1453 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1455 log_text("JNI-Call: CallVoidMethodA");
1460 jobject CallNonvirtualObjectMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1462 log_text("JNI-Call: CallNonvirtualObjectMethod");
1468 jobject CallNonvirtualObjectMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1470 log_text("JNI-Call: CallNonvirtualObjectMethodV");
1476 jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1478 log_text("JNI-Call: CallNonvirtualObjectMethodA");
1485 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1490 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1492 va_start(vaargs,methodID);
1493 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',vaargs);
1500 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1502 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1503 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',args);
1507 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1509 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1516 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1521 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1523 va_start(vaargs,methodID);
1524 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',vaargs);
1530 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1532 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1533 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',args);
1538 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1540 log_text("JNI-Call: CallNonvirtualByteMethodA");
1547 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1552 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1554 va_start(vaargs,methodID);
1555 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',vaargs);
1561 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1563 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1564 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',args);
1568 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1570 log_text("JNI-Call: CallNonvirtualCharMethodA");
1577 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1582 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1584 va_start(vaargs,methodID);
1585 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',vaargs);
1591 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1593 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1594 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',args);
1598 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1600 log_text("JNI-Call: CallNonvirtualShortMethodA");
1607 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1613 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1615 va_start(vaargs,methodID);
1616 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',vaargs);
1622 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1624 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1625 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',args);
1629 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1631 log_text("JNI-Call: CallNonvirtualIntMethodA");
1638 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1640 log_text("JNI-Call: CallNonvirtualLongMethod");
1646 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1648 log_text("JNI-Call: CallNonvirtualLongMethodV");
1654 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1656 log_text("JNI-Call: CallNonvirtualLongMethodA");
1663 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1668 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1671 va_start(vaargs,methodID);
1672 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'F');
1679 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1681 log_text("JNI-Call: CallNonvirtualFloatMethodV");
1682 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'F');
1686 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1688 log_text("JNI-Call: CallNonvirtualFloatMethodA");
1695 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1699 log_text("JNI-Call: CallNonvirtualDoubleMethod");
1701 va_start(vaargs,methodID);
1702 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'D');
1709 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1711 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
1712 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'D');
1716 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1718 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
1725 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1729 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
1731 va_start(vaargs,methodID);
1732 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',vaargs);
1738 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1740 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
1742 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',args);
1747 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1749 log_text("JNI-Call: CallNonvirtualVoidMethodA");
1752 /************************* JNI-functions for accessing fields ************************/
1754 jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
1758 /* log_text("========================= searching for:");
1761 f = jclass_findfield(clazz,
1762 utf_new_char ((char*) name),
1763 utf_new_char ((char*) sig)
1767 utf_display(clazz->name);
1770 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
1775 /*************************** retrieve fieldid, abort on error ************************/
1777 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
1779 jfieldID id = GetFieldID(env, clazz, name, sig);
1783 utf_display(clazz->name);
1784 log_text("\nfield:");
1789 panic("setfield_critical failed");
1794 jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
1796 jobject dbg,dretval,*dpretval;
1797 long int dli1, dli2, dli3;
1799 /* printf("GetObjectField(1): thread: %s obj: %p name: %s desc: %s \n",GetStringUTFChars(env,
1800 ((threadobject *) THREADOBJECT)->o
1802 ,obj,((fieldinfo*)fieldID)->name->text,(fieldID->descriptor)->text);*/
1804 dbg = getField(obj,jobject,fieldID);
1805 dli1 = (long int) obj;
1806 dli2 = (long int) fieldID->offset;
1808 dpretval = (jobject*) dli3;
1809 dretval = *dpretval;
1814 tmp = FindClass(env, "java/lang/Object");
1815 mid = GetMethodID(env,tmp,"toString","()Ljava/lang/String;");
1816 jstr = CallObjectMethod(env,dbg,mid);*/
1818 /* printf("GetObjectField(2): retval %p (obj: %#lx + offset: %#lx = %#lx (jobject*) %p (jobject) %p\n"
1819 ,dbg, dli1, dli2, dli3,dpretval, dretval);*/
1825 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
1827 return getField(obj,jboolean,fieldID);
1831 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
1833 return getField(obj,jbyte,fieldID);
1837 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
1839 return getField(obj,jchar,fieldID);
1843 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
1845 return getField(obj,jshort,fieldID);
1849 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
1851 return getField(obj,jint,fieldID);
1855 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
1857 return getField(obj,jlong,fieldID);
1861 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
1863 return getField(obj,jfloat,fieldID);
1867 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
1869 return getField(obj,jdouble,fieldID);
1872 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
1874 setField(obj,jobject,fieldID,val);
1878 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
1880 setField(obj,jboolean,fieldID,val);
1884 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
1886 setField(obj,jbyte,fieldID,val);
1890 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
1892 setField(obj,jchar,fieldID,val);
1896 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
1898 setField(obj,jshort,fieldID,val);
1902 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
1904 setField(obj,jint,fieldID,val);
1908 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
1910 setField(obj,jlong,fieldID,val);
1914 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
1916 setField(obj,jfloat,fieldID,val);
1920 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
1922 setField(obj,jdouble,fieldID,val);
1926 /**************** JNI-functions for calling static methods **********************/
1928 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
1932 m = class_resolvemethod(clazz,
1933 utf_new_char((char *) name),
1934 utf_new_char((char *) sig));
1936 if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
1937 else if (!(m->flags & ACC_STATIC)) {
1939 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
1946 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1951 /* log_text("JNI-Call: CallStaticObjectMethod");*/
1953 va_start(vaargs, methodID);
1954 ret = callObjectMethod(0, methodID, vaargs);
1961 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
1963 /* log_text("JNI-Call: CallStaticObjectMethodV"); */
1965 return callObjectMethod(0,methodID,args);
1969 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
1971 log_text("JNI-Call: CallStaticObjectMethodA");
1977 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1982 va_start(vaargs, methodID);
1983 ret = (jboolean) callIntegerMethod(0, methodID, 'Z', vaargs);
1990 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
1992 return (jboolean) callIntegerMethod(0, methodID, 'Z', args);
1996 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
1998 log_text("JNI-Call: CallStaticBooleanMethodA");
2004 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2009 /* log_text("JNI-Call: CallStaticByteMethod");*/
2011 va_start(vaargs, methodID);
2012 ret = (jbyte) callIntegerMethod(0, methodID, 'B', vaargs);
2019 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2021 return (jbyte) callIntegerMethod(0, methodID, 'B', args);
2025 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2027 log_text("JNI-Call: CallStaticByteMethodA");
2033 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2038 /* log_text("JNI-Call: CallStaticByteMethod");*/
2040 va_start(vaargs, methodID);
2041 ret = (jchar) callIntegerMethod(0, methodID, 'C', vaargs);
2048 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2050 return (jchar) callIntegerMethod(0, methodID, 'C', args);
2054 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2056 log_text("JNI-Call: CallStaticCharMethodA");
2063 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2068 /* log_text("JNI-Call: CallStaticByteMethod");*/
2070 va_start(vaargs, methodID);
2071 ret = (jshort) callIntegerMethod(0, methodID, 'S', vaargs);
2078 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2080 /*log_text("JNI-Call: CallStaticShortMethodV");*/
2081 return (jshort) callIntegerMethod(0, methodID, 'S', args);
2085 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2087 log_text("JNI-Call: CallStaticShortMethodA");
2094 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2099 /* log_text("JNI-Call: CallStaticIntMethod");*/
2101 va_start(vaargs, methodID);
2102 ret = callIntegerMethod(0, methodID, 'I', vaargs);
2109 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2111 log_text("JNI-Call: CallStaticIntMethodV");
2113 return callIntegerMethod(0, methodID, 'I', args);
2117 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2119 log_text("JNI-Call: CallStaticIntMethodA");
2126 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2131 /* log_text("JNI-Call: CallStaticLongMethod");*/
2133 va_start(vaargs, methodID);
2134 ret = callLongMethod(0, methodID, vaargs);
2141 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2143 log_text("JNI-Call: CallStaticLongMethodV");
2145 return callLongMethod(0,methodID,args);
2149 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2151 log_text("JNI-Call: CallStaticLongMethodA");
2158 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2163 /* log_text("JNI-Call: CallStaticLongMethod");*/
2165 va_start(vaargs, methodID);
2166 ret = callFloatMethod(0, methodID, vaargs, 'F');
2173 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2176 return callFloatMethod(0, methodID, args, 'F');
2181 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2183 log_text("JNI-Call: CallStaticFloatMethodA");
2190 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2195 /* log_text("JNI-Call: CallStaticDoubleMethod");*/
2197 va_start(vaargs,methodID);
2198 ret = callFloatMethod(0, methodID, vaargs, 'D');
2205 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2207 log_text("JNI-Call: CallStaticDoubleMethodV");
2209 return callFloatMethod(0, methodID, args, 'D');
2213 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2215 log_text("JNI-Call: CallStaticDoubleMethodA");
2221 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2225 /* log_text("JNI-Call: CallStaticVoidMethod");*/
2227 va_start(vaargs, methodID);
2228 (void) callIntegerMethod(0, methodID, 'V', vaargs);
2233 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2235 log_text("JNI-Call: CallStaticVoidMethodV");
2236 (void)callIntegerMethod(0, methodID, 'V', args);
2240 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2242 log_text("JNI-Call: CallStaticVoidMethodA");
2246 /****************** JNI-functions for accessing static fields ********************/
2248 jfieldID GetStaticFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
2252 f = jclass_findfield(clazz,
2253 utf_new_char ((char*) name),
2254 utf_new_char ((char*) sig)
2257 if (!f) *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2263 jobject GetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2266 return fieldID->value.a;
2270 jboolean GetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2273 return fieldID->value.i;
2277 jbyte GetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2280 return fieldID->value.i;
2284 jchar GetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2287 return fieldID->value.i;
2291 jshort GetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2294 return fieldID->value.i;
2298 jint GetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2301 return fieldID->value.i;
2305 jlong GetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2308 return fieldID->value.l;
2312 jfloat GetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2315 return fieldID->value.f;
2319 jdouble GetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2322 return fieldID->value.d;
2327 void SetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2330 fieldID->value.a = value;
2334 void SetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2337 fieldID->value.i = value;
2341 void SetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2344 fieldID->value.i = value;
2348 void SetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2351 fieldID->value.i = value;
2355 void SetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2358 fieldID->value.i = value;
2362 void SetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2365 fieldID->value.i = value;
2369 void SetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2372 fieldID->value.l = value;
2376 void SetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2379 fieldID->value.f = value;
2383 void SetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2386 fieldID->value.d = value;
2390 /***** create new java.lang.String object from an array of Unicode characters ****/
2392 jstring NewString (JNIEnv *env, const jchar *buf, jsize len)
2395 java_lang_String *s;
2398 s = (java_lang_String*) builtin_new (class_java_lang_String);
2399 a = builtin_newarray_char (len);
2401 /* javastring or characterarray could not be created */
2402 if ( (!a) || (!s) ) return NULL;
2405 for (i=0; i<len; i++) a->data[i] = buf[i];
2414 static char emptyString[]="";
2415 static jchar emptyStringJ[]={0,0};
2417 /******************* returns the length of a Java string ***************************/
2419 jsize GetStringLength (JNIEnv *env, jstring str)
2421 return ((java_lang_String*) str)->count;
2425 /******************** convertes javastring to u2-array ****************************/
2427 u2 *javastring_tou2 (jstring so)
2429 java_lang_String *s = (java_lang_String*) so;
2434 if (!s) return NULL;
2437 if (!a) return NULL;
2439 /* allocate memory */
2440 stringbuffer = MNEW( u2 , s->count + 1 );
2443 for (i=0; i<s->count; i++) stringbuffer[i] = a->data[s->offset+i];
2445 /* terminate string */
2446 stringbuffer[i] = '\0';
2448 return stringbuffer;
2451 /********* returns a pointer to an array of Unicode characters of the string *******/
2453 const jchar *GetStringChars (JNIEnv *env, jstring str, jboolean *isCopy)
2455 jchar *jc=javastring_tou2(str);
2458 if (isCopy) *isCopy=JNI_TRUE;
2461 if (isCopy) *isCopy=JNI_TRUE;
2462 return emptyStringJ;
2465 /**************** native code no longer needs access to chars **********************/
2467 void ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars)
2469 if (chars==emptyStringJ) return;
2470 MFREE(((jchar*) chars),jchar,((java_lang_String*) str)->count+1);
2473 /************ create new java.lang.String object from utf8-characterarray **********/
2475 jstring NewStringUTF (JNIEnv *env, const char *utf)
2477 /* log_text("NewStringUTF called");*/
2478 return (jstring) javastring_new(utf_new_char((char *) utf));
2481 /****************** returns the utf8 length in bytes of a string *******************/
2483 jsize GetStringUTFLength (JNIEnv *env, jstring string)
2485 java_lang_String *s = (java_lang_String*) string;
2487 return (jsize) u2_utflength(s->value->data, s->count);
2491 /************ converts a Javastring to an array of UTF-8 characters ****************/
2493 const char* GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
2497 u = javastring_toutf((java_lang_String *) string, false);
2500 *isCopy = JNI_FALSE;
2510 /***************** native code no longer needs access to utf ***********************/
2512 void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
2514 /*we don't release utf chars right now, perhaps that should be done later. Since there is always one reference
2515 the garbage collector will never get them*/
2517 log_text("JNI-Call: ReleaseStringUTFChars");
2518 utf_display(utf_new_char(chars));
2522 /************************** array operations ***************************************/
2524 jsize GetArrayLength(JNIEnv *env, jarray array)
2530 jobjectArray NewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init)
2532 java_objectarray *j;
2535 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2539 j = builtin_anewarray(len, clazz);
2545 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
2549 if (index < array->header.size)
2550 j = array->data[index];
2552 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2558 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
2560 if (index >= array->header.size)
2561 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2564 /* check if the class of value is a subclass of the element class of the array */
2565 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
2566 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
2569 array->data[index] = val;
2575 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
2577 java_booleanarray *j;
2580 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2584 j = builtin_newarray_boolean(len);
2590 jbyteArray NewByteArray(JNIEnv *env, jsize len)
2595 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2599 j = builtin_newarray_byte(len);
2605 jcharArray NewCharArray(JNIEnv *env, jsize len)
2610 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2614 j = builtin_newarray_char(len);
2620 jshortArray NewShortArray(JNIEnv *env, jsize len)
2625 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2629 j = builtin_newarray_short(len);
2635 jintArray NewIntArray(JNIEnv *env, jsize len)
2640 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2644 j = builtin_newarray_int(len);
2650 jlongArray NewLongArray(JNIEnv *env, jsize len)
2655 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2659 j = builtin_newarray_long(len);
2665 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
2670 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2674 j = builtin_newarray_float(len);
2680 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
2682 java_doublearray *j;
2685 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2689 j = builtin_newarray_double(len);
2695 jboolean * GetBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *isCopy)
2697 if (isCopy) *isCopy = JNI_FALSE;
2702 jbyte * GetByteArrayElements (JNIEnv *env, jbyteArray array, jboolean *isCopy)
2704 if (isCopy) *isCopy = JNI_FALSE;
2709 jchar * GetCharArrayElements (JNIEnv *env, jcharArray array, jboolean *isCopy)
2711 if (isCopy) *isCopy = JNI_FALSE;
2716 jshort * GetShortArrayElements (JNIEnv *env, jshortArray array, jboolean *isCopy)
2718 if (isCopy) *isCopy = JNI_FALSE;
2723 jint * GetIntArrayElements (JNIEnv *env, jintArray array, jboolean *isCopy)
2725 if (isCopy) *isCopy = JNI_FALSE;
2730 jlong * GetLongArrayElements (JNIEnv *env, jlongArray array, jboolean *isCopy)
2732 if (isCopy) *isCopy = JNI_FALSE;
2737 jfloat * GetFloatArrayElements (JNIEnv *env, jfloatArray array, jboolean *isCopy)
2739 if (isCopy) *isCopy = JNI_FALSE;
2744 jdouble * GetDoubleArrayElements (JNIEnv *env, jdoubleArray array, jboolean *isCopy)
2746 if (isCopy) *isCopy = JNI_FALSE;
2752 void ReleaseBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode)
2758 void ReleaseByteArrayElements (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode)
2764 void ReleaseCharArrayElements (JNIEnv *env, jcharArray array, jchar *elems, jint mode)
2770 void ReleaseShortArrayElements (JNIEnv *env, jshortArray array, jshort *elems, jint mode)
2776 void ReleaseIntArrayElements (JNIEnv *env, jintArray array, jint *elems, jint mode)
2782 void ReleaseLongArrayElements (JNIEnv *env, jlongArray array, jlong *elems, jint mode)
2788 void ReleaseFloatArrayElements (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode)
2794 void ReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode)
2800 void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2802 if (start < 0 || len < 0 || start + len > array->header.size)
2803 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2806 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2810 void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
2812 if (start < 0 || len < 0 || start + len > array->header.size)
2813 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2816 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2820 void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
2822 if (start < 0 || len < 0 || start + len > array->header.size)
2823 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2826 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2830 void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
2832 if (start < 0 || len < 0 || start + len > array->header.size)
2833 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2836 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2840 void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
2842 if (start < 0 || len < 0 || start + len > array->header.size)
2843 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2846 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2850 void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
2852 if (start < 0 || len < 0 || start + len > array->header.size)
2853 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2856 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2860 void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
2862 if (start < 0 || len < 0 || start + len > array->header.size)
2863 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2866 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2870 void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
2872 if (start < 0 || len < 0 || start+len>array->header.size)
2873 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2876 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2880 void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2882 if (start < 0 || len < 0 || start + len > array->header.size)
2883 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2886 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2890 void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
2892 if (start < 0 || len < 0 || start + len > array->header.size)
2893 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2896 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2900 void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
2902 if (start < 0 || len < 0 || start + len > array->header.size)
2903 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2906 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2911 void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *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]));
2921 void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
2923 if (start < 0 || len < 0 || start + len > array->header.size)
2924 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2927 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2932 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *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 SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *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 SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *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]));
2964 jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
2966 log_text("JNI-Call: RegisterNatives");
2971 jint UnregisterNatives (JNIEnv* env, jclass clazz)
2973 log_text("JNI-Call: UnregisterNatives");
2977 /******************************* monitor operations ********************************/
2979 jint MonitorEnter (JNIEnv* env, jobject obj)
2981 builtin_monitorenter(obj);
2986 jint MonitorExit (JNIEnv* env, jobject obj)
2988 builtin_monitorexit(obj);
2993 /************************************* JavaVM interface ****************************/
2995 #error CPP mode not supported yet
2997 jint GetJavaVM (JNIEnv* env, JavaVM **vm)
2999 log_text("JNI-Call: GetJavaVM");
3003 #endif /*__cplusplus*/
3005 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3007 log_text("JNI-Call: GetStringRegion");
3011 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3013 log_text("JNI-Call: GetStringUTFRegion");
3017 /************** obtain direct pointer to array elements ***********************/
3019 void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
3021 java_objectheader *s = (java_objectheader*) array;
3022 arraydescriptor *desc = s->vftbl->arraydesc;
3024 if (!desc) return NULL;
3026 return ((u1*)s) + desc->dataoffset;
3030 void ReleasePrimitiveArrayCritical (JNIEnv* env, jarray array, void *carray, jint mode)
3032 log_text("JNI-Call: ReleasePrimitiveArrayCritical");
3037 /**** returns a pointer to an array of Unicode characters of the string *******/
3039 const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
3041 log_text("JNI-Call: GetStringCritical");
3043 return GetStringChars(env,string,isCopy);
3046 /*********** native code no longer needs access to chars **********************/
3048 void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
3050 log_text("JNI-Call: ReleaseStringCritical");
3052 ReleaseStringChars(env,string,cstring);
3056 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3058 log_text("JNI-Call: NewWeakGlobalRef");
3064 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
3066 log_text("JNI-Call: DeleteWeakGlobalRef");
3072 /** Creates a new global reference to the object referred to by the obj argument **/
3074 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
3076 MonitorEnter(env,*global_ref_table);
3077 jobject refcount = CallObjectMethod(env, *global_ref_table, getmid, lobj);
3078 jint val = (refcount == NULL) ? 0 : CallIntMethod(env,refcount,intvalue);
3079 jobject newval = NewObject(env,intclass,newint,val+1);
3080 if (newval != NULL) {
3082 CallObjectMethod(env, *global_ref_table, putmid, lobj, newval);
3084 MonitorExit(env,*global_ref_table);
3087 log_text("JNI-NewGlobalRef: unable to create new java.lang.Integer");
3088 MonitorExit(env,*global_ref_table);
3093 /************* Deletes the global reference pointed to by globalRef **************/
3095 void DeleteGlobalRef (JNIEnv* env, jobject gref)
3097 MonitorEnter(env,*global_ref_table);
3098 jobject refcount = CallObjectMethod(env, *global_ref_table, getmid, gref);
3099 if (refcount == NULL) {
3100 log_text("JNI-DeleteGlobalRef: unable to find global reference");
3103 jint val = CallIntMethod(env,refcount,intvalue);
3106 CallObjectMethod(env, *global_ref_table, removemid,refcount);
3108 jobject newval = NewObject(env,intclass,newint,val);
3109 if (newval != NULL) {
3110 CallObjectMethod(env,*global_ref_table, putmid,newval);
3112 log_text("JNI-DeleteGlobalRef: unable to create new java.lang.Integer");
3115 MonitorExit(env,*global_ref_table);
3118 /******************************* check for pending exception ***********************/
3121 jboolean ExceptionCheck(JNIEnv* env)
3123 log_text("JNI-Call: ExceptionCheck");
3125 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
3133 jint DestroyJavaVM(JavaVM *vm)
3135 log_text("DestroyJavaVM called");
3141 jint AttachCurrentThread(JavaVM *vm, void **par1, void *par2)
3143 log_text("AttachCurrentThread called");
3149 jint DetachCurrentThread(JavaVM *vm)
3151 log_text("DetachCurrentThread called");
3157 jint GetEnv(JavaVM *vm, void **environment, jint jniversion)
3159 *environment = &env;
3165 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
3167 log_text("AttachCurrentThreadAsDaemon called");
3173 /********************************* JNI invocation table ******************************/
3175 struct _JavaVM javaVMTable={
3180 &AttachCurrentThread,
3181 &DetachCurrentThread,
3183 &AttachCurrentThreadAsDaemon
3186 JavaVM javaVM = &javaVMTable;
3189 /********************************* JNI function table ******************************/
3191 struct JNI_Table envTable = {
3199 &FromReflectedMethod,
3200 &FromReflectedField,
3218 &EnsureLocalCapacity,
3230 &CallBooleanMethodV,
3231 &CallBooleanMethodA,
3256 &CallNonvirtualObjectMethod,
3257 &CallNonvirtualObjectMethodV,
3258 &CallNonvirtualObjectMethodA,
3259 &CallNonvirtualBooleanMethod,
3260 &CallNonvirtualBooleanMethodV,
3261 &CallNonvirtualBooleanMethodA,
3262 &CallNonvirtualByteMethod,
3263 &CallNonvirtualByteMethodV,
3264 &CallNonvirtualByteMethodA,
3265 &CallNonvirtualCharMethod,
3266 &CallNonvirtualCharMethodV,
3267 &CallNonvirtualCharMethodA,
3268 &CallNonvirtualShortMethod,
3269 &CallNonvirtualShortMethodV,
3270 &CallNonvirtualShortMethodA,
3271 &CallNonvirtualIntMethod,
3272 &CallNonvirtualIntMethodV,
3273 &CallNonvirtualIntMethodA,
3274 &CallNonvirtualLongMethod,
3275 &CallNonvirtualLongMethodV,
3276 &CallNonvirtualLongMethodA,
3277 &CallNonvirtualFloatMethod,
3278 &CallNonvirtualFloatMethodV,
3279 &CallNonvirtualFloatMethodA,
3280 &CallNonvirtualDoubleMethod,
3281 &CallNonvirtualDoubleMethodV,
3282 &CallNonvirtualDoubleMethodA,
3283 &CallNonvirtualVoidMethod,
3284 &CallNonvirtualVoidMethodV,
3285 &CallNonvirtualVoidMethodA,
3306 &CallStaticObjectMethod,
3307 &CallStaticObjectMethodV,
3308 &CallStaticObjectMethodA,
3309 &CallStaticBooleanMethod,
3310 &CallStaticBooleanMethodV,
3311 &CallStaticBooleanMethodA,
3312 &CallStaticByteMethod,
3313 &CallStaticByteMethodV,
3314 &CallStaticByteMethodA,
3315 &CallStaticCharMethod,
3316 &CallStaticCharMethodV,
3317 &CallStaticCharMethodA,
3318 &CallStaticShortMethod,
3319 &CallStaticShortMethodV,
3320 &CallStaticShortMethodA,
3321 &CallStaticIntMethod,
3322 &CallStaticIntMethodV,
3323 &CallStaticIntMethodA,
3324 &CallStaticLongMethod,
3325 &CallStaticLongMethodV,
3326 &CallStaticLongMethodA,
3327 &CallStaticFloatMethod,
3328 &CallStaticFloatMethodV,
3329 &CallStaticFloatMethodA,
3330 &CallStaticDoubleMethod,
3331 &CallStaticDoubleMethodV,
3332 &CallStaticDoubleMethodA,
3333 &CallStaticVoidMethod,
3334 &CallStaticVoidMethodV,
3335 &CallStaticVoidMethodA,
3337 &GetStaticObjectField,
3338 &GetStaticBooleanField,
3339 &GetStaticByteField,
3340 &GetStaticCharField,
3341 &GetStaticShortField,
3343 &GetStaticLongField,
3344 &GetStaticFloatField,
3345 &GetStaticDoubleField,
3346 &SetStaticObjectField,
3347 &SetStaticBooleanField,
3348 &SetStaticByteField,
3349 &SetStaticCharField,
3350 &SetStaticShortField,
3352 &SetStaticLongField,
3353 &SetStaticFloatField,
3354 &SetStaticDoubleField,
3358 &ReleaseStringChars,
3360 &GetStringUTFLength,
3362 &ReleaseStringUTFChars,
3365 &GetObjectArrayElement,
3366 &SetObjectArrayElement,
3375 &GetBooleanArrayElements,
3376 &GetByteArrayElements,
3377 &GetCharArrayElements,
3378 &GetShortArrayElements,
3379 &GetIntArrayElements,
3380 &GetLongArrayElements,
3381 &GetFloatArrayElements,
3382 &GetDoubleArrayElements,
3383 &ReleaseBooleanArrayElements,
3384 &ReleaseByteArrayElements,
3385 &ReleaseCharArrayElements,
3386 &ReleaseShortArrayElements,
3387 &ReleaseIntArrayElements,
3388 &ReleaseLongArrayElements,
3389 &ReleaseFloatArrayElements,
3390 &ReleaseDoubleArrayElements,
3391 &GetBooleanArrayRegion,
3392 &GetByteArrayRegion,
3393 &GetCharArrayRegion,
3394 &GetShortArrayRegion,
3396 &GetLongArrayRegion,
3397 &GetFloatArrayRegion,
3398 &GetDoubleArrayRegion,
3399 &SetBooleanArrayRegion,
3400 &SetByteArrayRegion,
3401 &SetCharArrayRegion,
3402 &SetShortArrayRegion,
3404 &SetLongArrayRegion,
3405 &SetFloatArrayRegion,
3406 &SetDoubleArrayRegion,
3413 &GetStringUTFRegion,
3414 &GetPrimitiveArrayCritical,
3415 &ReleasePrimitiveArrayCritical,
3417 &ReleaseStringCritical,
3419 &DeleteWeakGlobalRef,
3423 JNIEnv env = &envTable;
3426 jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID, jobject obj, java_objectarray *params)
3433 if (methodID == 0) {
3434 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
3438 argcount = get_parametercount(methodID);
3440 if (obj && (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
3441 *exceptionptr = new_exception_message(string_java_lang_IllegalArgumentException,
3442 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
3449 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3450 log_text("Too many arguments. invokeNativeHelper does not support that");
3455 if (((!params) && (argcount != 0)) || (params && (params->header.size != argcount))) {
3456 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3461 if (!(methodID->flags & ACC_STATIC) && (!obj)) {
3462 *exceptionptr = new_exception_message(string_java_lang_NullPointerException,
3463 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
3467 if ((methodID->flags & ACC_STATIC) && (obj)) obj = 0;
3469 blk = MNEW(jni_callblock, 4 /*argcount+2*/);
3471 retT = fill_callblock_objA(obj, methodID->descriptor, blk, params);
3475 (void) asm_calljavafunction2(methodID,
3477 (argcount + 1) * sizeof(jni_callblock),
3479 retVal = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
3484 intVal = (s4) asm_calljavafunction2(methodID,
3486 (argcount + 1) * sizeof(jni_callblock),
3488 retVal = builtin_new(class_new(utf_new_char("java/lang/Integer")));
3491 class_resolvemethod(retVal->vftbl->class,
3492 utf_new_char("<init>"),
3493 utf_new_char("(I)V")),
3500 intVal = (s4) asm_calljavafunction2(methodID,
3502 (argcount + 1) * sizeof(jni_callblock),
3504 retVal = builtin_new(class_new(utf_new_char("java/lang/Byte")));
3507 class_resolvemethod(retVal->vftbl->class,
3508 utf_new_char("<init>"),
3509 utf_new_char("(B)V")),
3516 intVal = (s4) asm_calljavafunction2(methodID,
3518 (argcount + 1) * sizeof(jni_callblock),
3520 retVal = builtin_new(class_new(utf_new_char("java/lang/Character")));
3523 class_resolvemethod(retVal->vftbl->class,
3524 utf_new_char("<init>"),
3525 utf_new_char("(C)V")),
3532 intVal = (s4) asm_calljavafunction2(methodID,
3534 (argcount + 1) * sizeof(jni_callblock),
3536 retVal = builtin_new(class_new(utf_new_char("java/lang/Short")));
3539 class_resolvemethod(retVal->vftbl->class,
3540 utf_new_char("<init>"),
3541 utf_new_char("(S)V")),
3548 intVal = (s4) asm_calljavafunction2(methodID,
3550 (argcount + 1) * sizeof(jni_callblock),
3552 retVal = builtin_new(class_new(utf_new_char("java/lang/Boolean")));
3555 class_resolvemethod(retVal->vftbl->class,
3556 utf_new_char("<init>"),
3557 utf_new_char("(Z)V")),
3564 intVal = asm_calljavafunction2long(methodID,
3566 (argcount + 1) * sizeof(jni_callblock),
3568 retVal = builtin_new(class_new(utf_new_char("java/lang/Long")));
3571 class_resolvemethod(retVal->vftbl->class,
3572 utf_new_char("<init>"),
3573 utf_new_char("(J)V")),
3580 floatVal = asm_calljavafunction2double(methodID,
3582 (argcount + 1) * sizeof(jni_callblock),
3584 retVal = builtin_new(class_new(utf_new_char("java/lang/Float")));
3587 class_resolvemethod(retVal->vftbl->class,
3588 utf_new_char("<init>"),
3589 utf_new_char("(F)V")),
3596 floatVal = asm_calljavafunction2double(methodID,
3598 (argcount + 1) * sizeof(jni_callblock),
3600 retVal = builtin_new(class_new(utf_new_char("java/lang/Double")));
3603 class_resolvemethod(retVal->vftbl->class,
3604 utf_new_char("<init>"),
3605 utf_new_char("(D)V")),
3610 case 'L': /* fall through */
3612 retVal = asm_calljavafunction2(methodID,
3614 (argcount + 1) * sizeof(jni_callblock),
3619 /* if this happens the acception has already been set by fill_callblock_objA*/
3620 MFREE(blk, jni_callblock, 4 /*argcount+2*/);
3621 return (jobject *) 0;
3624 MFREE(blk, jni_callblock, 4 /*argcount+2*/);
3626 if (*exceptionptr) {
3627 java_objectheader *exceptionToWrap = *exceptionptr;
3629 java_objectheader *ivte;
3631 *exceptionptr = NULL;
3632 ivtec = class_new(utf_new_char("java/lang/reflect/InvocationTargetException"));
3633 ivte = builtin_new(ivtec);
3634 asm_calljavafunction(class_resolvemethod(ivtec,
3635 utf_new_char("<init>"),
3636 utf_new_char("(Ljava/lang/Throwable;)V")),
3642 if (*exceptionptr != NULL)
3643 panic("jni.c: error while creating InvocationTargetException wrapper");
3645 *exceptionptr = ivte;
3648 return (jobject *) retVal;
3654 log_text("JNI-Init: initialize global_ref_table");
3655 // initalize global reference table
3656 ihmclass = FindClass(NULL, "java/util/IdentityHashMap");
3658 if (ihmclass == NULL) {
3659 log_text("JNI-Init: unable to find java.util.IdentityHashMap");
3662 mid = GetMethodID(NULL, ihmclass, "<init>","()V");
3664 log_text("JNI-Init: unable to find constructor in java.util.IdentityHashMap");
3667 global_ref_table = (jobject*)heap_allocate(sizeof(jobject),true,NULL);
3669 *global_ref_table = NewObject(NULL,ihmclass,mid);
3671 if (*global_ref_table == NULL) {
3672 log_text("JNI-Init: unable to create new global_ref_table");
3675 getmid = GetMethodID(NULL, ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3677 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3680 getmid = GetMethodID(NULL ,ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3681 if (getmid == NULL) {
3682 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3685 putmid = GetMethodID(NULL, ihmclass, "put","(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
3686 if (putmid == NULL) {
3687 log_text("JNI-Init: unable to find method \"put\" in java.util.IdentityHashMap");
3690 intclass = FindClass(NULL, "java/lang/Integer");
3691 if (intclass == NULL) {
3692 log_text("JNI-Init: unable to find java.lang.Integer");
3695 newint = GetMethodID(NULL, intclass, "<init>","(I)V");
3696 if (newint == NULL) {
3697 log_text("JNI-Init: unable to find constructor in java.lang.Integer");
3700 intvalue = GetMethodID(NULL, intclass, "intValue","()I");
3701 if (intvalue == NULL) {
3702 log_text("JNI-Init: unable to find method \"intValue\" in java.lang.Integer");
3705 removemid = GetMethodID(NULL, ihmclass, "remove","(Ljava/lang/Object;)Ljava/lang/Object;");
3706 if (removemid == NULL) {
3707 log_text("JNI-DeleteGlobalRef: unable to find method \"remove\" in java.lang.Object");
3713 * These are local overrides for various environment variables in Emacs.
3714 * Please do not remove this and leave it at the end of the file, where
3715 * Emacs will automagically detect them.
3716 * ---------------------------------------------------------------------
3719 * indent-tabs-mode: t