1 /* native/jni.c - implementation of the Java Native Interface functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Rainhard Grafl
30 Changes: Joseph Wenninger
34 $Id: jni.c 1969 2005-03-01 14:09:25Z motse $
42 #include "mm/memory.h"
43 #include "native/jni.h"
44 #include "native/native.h"
45 #include "native/include/java_lang_Byte.h"
46 #include "native/include/java_lang_Character.h"
47 #include "native/include/java_lang_Short.h"
48 #include "native/include/java_lang_Integer.h"
49 #include "native/include/java_lang_Boolean.h"
50 #include "native/include/java_lang_Long.h"
51 #include "native/include/java_lang_Float.h"
52 #include "native/include/java_lang_Double.h"
53 #include "native/include/java_lang_Throwable.h"
55 #if defined(USE_THREADS)
56 # if defined(NATIVE_THREADS)
57 # include "threads/native/threads.h"
59 # include "threads/green/threads.h"
63 #include "toolbox/logging.h"
64 #include "vm/builtin.h"
65 #include "vm/exceptions.h"
66 #include "vm/global.h"
67 #include "vm/loader.h"
68 #include "vm/options.h"
69 #include "vm/statistics.h"
70 #include "vm/stringlocal.h"
71 #include "vm/tables.h"
72 #include "vm/jit/asmpart.h"
73 #include "vm/jit/jit.h"
76 /* XXX TWISTI hack: define it extern so they can be found in this file */
77 extern const struct JNIInvokeInterface JNI_JavaVMTable;
78 extern struct JNINativeInterface JNI_JNIEnvTable;
80 /* pointers to VM and the environment needed by GetJavaVM and GetEnv */
81 static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
82 static void* ptr_env = (void*) &JNI_JNIEnvTable;
85 #define PTR_TO_ITEM(ptr) ((u8)(size_t)(ptr))
87 /* global reference table */
88 static jobject *global_ref_table;
89 static bool initrunning=false;
91 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
92 static jmethodID getmid = NULL;
93 static jmethodID putmid = NULL;
94 static jclass intclass = NULL;
95 static jmethodID intvalue = NULL;
96 static jmethodID newint = NULL;
97 static jclass ihmclass = NULL;
98 static jmethodID removemid = NULL;
101 /********************* accessing instance-fields **********************************/
103 #define setField(obj,typ,var,val) *((typ*) ((long int) obj + (long int) var->offset))=val;
104 #define getField(obj,typ,var) *((typ*) ((long int) obj + (long int) var->offset))
105 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) setField(obj,jdatatype,getFieldID_critical(env,clazz,name,sig),val);
109 u4 get_parametercount(methodinfo *m)
111 utf *descr = m->descriptor; /* method-descriptor */
112 char *utf_ptr = descr->text; /* current position in utf-text */
113 char *desc_end = utf_end(descr); /* points behind utf string */
114 u4 parametercount = 0;
117 utf_nextu2(&utf_ptr);
119 /* determine number of parameters */
120 while (*utf_ptr != ')') {
121 get_type(&utf_ptr, desc_end, true);
125 return parametercount;
130 void fill_callblock(void *obj, utf *descr, jni_callblock blk[], va_list data, char ret)
132 char *utf__ptr = descr->text; /* current position in utf-text */
133 char **utf_ptr = &utf__ptr;
134 char *desc_end = utf_end(descr); /* points behind utf string */
140 log_text("fill_callblock");
147 /* determine number of parameters */
149 blk[0].itemtype = TYPE_ADR;
150 blk[0].item = PTR_TO_ITEM(obj);
154 while (**utf_ptr != ')') {
155 if (*utf_ptr >= desc_end)
156 panic("illegal method descriptor");
158 switch (utf_nextu2(utf_ptr)) {
159 /* primitive types */
164 blk[cnt].itemtype = TYPE_INT;
165 blk[cnt].item = (u8) va_arg(data, int);
169 blk[cnt].itemtype = TYPE_INT;
170 dummy = va_arg(data, u4);
171 /*printf("fill_callblock: pos:%d, value:%d\n",cnt,dummy);*/
172 blk[cnt].item = (u8) dummy;
176 blk[cnt].itemtype = TYPE_LNG;
177 blk[cnt].item = (u8) va_arg(data, jlong);
181 blk[cnt].itemtype = TYPE_FLT;
182 *((jfloat *) (&blk[cnt].item)) = (jfloat) va_arg(data, jdouble);
186 blk[cnt].itemtype = TYPE_DBL;
187 *((jdouble *) (&blk[cnt].item)) = (jdouble) va_arg(data, jdouble);
191 panic ("V not allowed as function parameter");
195 while (utf_nextu2(utf_ptr) != ';')
196 blk[cnt].itemtype = TYPE_ADR;
197 blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
204 /* char *start = *utf_ptr; */
206 while ((ch = utf_nextu2(utf_ptr)) == '[')
208 while (utf_nextu2(utf_ptr) != ';') {}
211 ch = utf_nextu2(utf_ptr);
212 blk[cnt].itemtype = TYPE_ADR;
213 blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
220 /*the standard doesn't say anything about return value checking, but it appears to be usefull*/
221 c = utf_nextu2(utf_ptr);
222 c = utf_nextu2(utf_ptr);
223 /*printf("%c %c\n",ret,c);*/
225 if (!((c == 'L') || (c == '[')))
226 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
228 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
232 /* XXX it could be considered if we should do typechecking here in the future */
233 char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_objectarray* params)
235 char *utf__ptr = descr->text; /* current position in utf-text */
236 char **utf_ptr = &utf__ptr;
237 char *desc_end = utf_end(descr); /* points behind utf string */
245 log_text("fill_callblock");
252 /* determine number of parameters */
254 blk[0].itemtype = TYPE_ADR;
255 blk[0].item = PTR_TO_ITEM(obj);
263 while (**utf_ptr != ')') {
264 if (*utf_ptr >= desc_end)
265 panic("illegal method descriptor");
267 /* primitive types */
268 switch (utf_nextu2(utf_ptr)) {
270 param = params->data[cnts];
272 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
275 if (param->vftbl->class->name == utf_java_lang_Byte) {
276 blk[cnt].itemtype = TYPE_INT;
277 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
280 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
286 param = params->data[cnts];
288 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
291 if (param->vftbl->class->name == utf_java_lang_Character) {
292 blk[cnt].itemtype = TYPE_INT;
293 blk[cnt].item = (u8) ((java_lang_Character *) param)->value;
296 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
302 param = params->data[cnts];
304 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
307 if (param->vftbl->class->name == utf_java_lang_Short) {
308 blk[cnt].itemtype = TYPE_INT;
309 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
312 if (param->vftbl->class->name == utf_java_lang_Byte) {
313 blk[cnt].itemtype = TYPE_INT;
314 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
317 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
324 param = params->data[cnts];
326 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
329 if (param->vftbl->class->name == utf_java_lang_Boolean) {
330 blk[cnt].itemtype = TYPE_INT;
331 blk[cnt].item = (u8) ((java_lang_Boolean *) param)->value;
334 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
340 /*log_text("fill_callblock_objA: param 'I'");*/
341 param = params->data[cnts];
343 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
346 if (param->vftbl->class->name == utf_java_lang_Integer) {
347 blk[cnt].itemtype = TYPE_INT;
348 blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
349 /*printf("INT VALUE :%d\n",((struct java_lang_Integer * )param)->value);*/
351 if (param->vftbl->class->name == utf_java_lang_Short) {
352 blk[cnt].itemtype = TYPE_INT;
353 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
356 if (param->vftbl->class->name == utf_java_lang_Byte) {
357 blk[cnt].itemtype = TYPE_INT;
358 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
361 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
369 param = params->data[cnts];
371 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
374 if (param->vftbl->class->name == utf_java_lang_Long) {
375 blk[cnt].itemtype = TYPE_LNG;
376 blk[cnt].item = (u8) ((java_lang_Long *) param)->value;
379 if (param->vftbl->class->name == utf_java_lang_Integer) {
380 blk[cnt].itemtype = TYPE_LNG;
381 blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
384 if (param->vftbl->class->name == utf_java_lang_Short) {
385 blk[cnt].itemtype = TYPE_LNG;
386 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
389 if (param->vftbl->class->name == utf_java_lang_Byte) {
390 blk[cnt].itemtype = TYPE_LNG;
391 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
393 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
403 param = params->data[cnts];
405 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
409 if (param->vftbl->class->name == utf_java_lang_Float) {
410 blk[cnt].itemtype = TYPE_FLT;
411 *((jfloat *) (&blk[cnt].item)) = (jfloat) ((java_lang_Float *) param)->value;
414 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
420 param = params->data[cnts];
422 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
426 if (param->vftbl->class->name == utf_java_lang_Double) {
427 blk[cnt].itemtype = TYPE_DBL;
428 *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
431 if (param->vftbl->class->name == utf_java_lang_Float) {
432 blk[cnt].itemtype = TYPE_DBL;
433 *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
436 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
443 panic("V not allowed as function parameter");
448 char *start = (*utf_ptr) - 1;
451 while (utf_nextu2(utf_ptr) != ';')
452 end = (*utf_ptr) + 1;*/
454 if (!builtin_instanceof(params->data[cnts], class_from_descriptor(start, desc_end, utf_ptr, CLASSLOAD_LOAD))) {
455 if (params->data[cnts] != 0) {
456 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
460 blk[cnt].itemtype = TYPE_ADR;
461 blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
467 char *start = (*utf_ptr) - 1;
471 while ((ch = utf_nextu2(utf_ptr)) == '[')
473 while (utf_nextu2(utf_ptr) != ';') {}
476 end = (*utf_ptr) - 1;
477 ch = utf_nextu2(utf_ptr); */
479 if (!builtin_arrayinstanceof(params->data[cnts], class_from_descriptor(start, desc_end, utf_ptr, CLASSLOAD_LOAD)->vftbl)) {
480 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
484 blk[cnt].itemtype = TYPE_ADR;
485 blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
493 c = utf_nextu2(utf_ptr);
494 c = utf_nextu2(utf_ptr);
495 return c; /*return type needed usage of the right lowlevel methods*/
499 jmethodID get_virtual(jobject obj,jmethodID methodID) {
500 if (obj->vftbl->class==methodID->class) return methodID;
501 return class_resolvemethod (obj->vftbl->class, methodID->name, methodID->descriptor);
505 jmethodID get_nonvirtual(jclass clazz,jmethodID methodID) {
506 if (clazz==methodID->class) return methodID;
507 /*class_resolvemethod -> classfindmethod? (JOWENN)*/
508 return class_resolvemethod (clazz, methodID->name, methodID->descriptor);
512 jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
521 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
525 argcount = get_parametercount(methodID);
527 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
528 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
529 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
533 if (obj && !builtin_instanceof(obj, methodID->class)) {
534 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
541 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
542 log_text("Too many arguments. CallObjectMethod does not support that");
547 blk = MNEW(jni_callblock, /*4 */argcount+2);
549 fill_callblock(obj, methodID->descriptor, blk, args, 'O');
550 /* printf("parameter: obj: %p",blk[0].item); */
551 ret = asm_calljavafunction2(methodID,
553 (argcount + 1) * sizeof(jni_callblock),
555 MFREE(blk, jni_callblock, argcount + 1);
556 /* printf("(CallObjectMethodV)-->%p\n",ret); */
563 core function for integer class methods (bool, byte, short, integer)
564 This is basically needed for i386
566 jint callIntegerMethod(jobject obj, jmethodID methodID, char retType, va_list args)
572 /* printf("%p, %c\n",retType,methodID,retType);*/
575 log_text("JNI-Call: CallObjectMethodV");
576 utf_display(methodID->name);
577 utf_display(methodID->descriptor);
578 printf("\nParmaeter count: %d\n",argcount);
579 utf_display(obj->vftbl->class->name);
583 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
587 argcount = get_parametercount(methodID);
589 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
590 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
591 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
595 if (obj && !builtin_instanceof(obj, methodID->class)) {
596 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
602 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
603 log_text("Too many arguments. CallIntegerMethod does not support that");
608 blk = MNEW(jni_callblock, /*4 */ argcount+2);
610 fill_callblock(obj, methodID->descriptor, blk, args, retType);
612 /* printf("parameter: obj: %p",blk[0].item); */
613 ret = asm_calljavafunction2int(methodID,
615 (argcount + 1) * sizeof(jni_callblock),
618 MFREE(blk, jni_callblock, argcount + 1);
619 /* printf("(CallObjectMethodV)-->%p\n",ret); */
625 /*core function for long class functions*/
626 jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
633 log_text("JNI-Call: CallObjectMethodV");
634 utf_display(methodID->name);
635 utf_display(methodID->descriptor);
636 printf("\nParmaeter count: %d\n",argcount);
637 utf_display(obj->vftbl->class->name);
641 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
645 argcount = get_parametercount(methodID);
647 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
648 ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
649 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
653 if (obj && !builtin_instanceof(obj,methodID->class)) {
654 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
660 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
661 log_text("Too many arguments. CallObjectMethod does not support that");
666 blk = MNEW(jni_callblock,/* 4 */argcount+2);
668 fill_callblock(obj, methodID->descriptor, blk, args, 'J');
670 /* printf("parameter: obj: %p",blk[0].item); */
671 ret = asm_calljavafunction2long(methodID,
673 (argcount + 1) * sizeof(jni_callblock),
676 MFREE(blk, jni_callblock, argcount + 1);
677 /* printf("(CallObjectMethodV)-->%p\n",ret); */
683 /*core function for float class methods (float,double)*/
684 jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,char retType)
686 int argcount = get_parametercount(methodID);
691 log_text("JNI-Call: CallObjectMethodV");
692 utf_display(methodID->name);
693 utf_display(methodID->descriptor);
694 printf("\nParmaeter count: %d\n",argcount);
695 utf_display(obj->vftbl->class->name);
701 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
702 log_text("Too many arguments. CallObjectMethod does not support that");
707 blk = MNEW(jni_callblock, /*4 */ argcount+2);
709 fill_callblock(obj, methodID->descriptor, blk, args, retType);
711 /* printf("parameter: obj: %p",blk[0].item); */
712 ret = asm_calljavafunction2double(methodID,
714 (argcount + 1) * sizeof(jni_callblock),
717 MFREE(blk, jni_callblock, argcount + 1);
718 /* printf("(CallObjectMethodV)-->%p\n",ret); */
724 /*************************** function: jclass_findfield ****************************
726 searches for field with specified name and type in a 'classinfo'-structur
727 if no such field is found NULL is returned
729 ************************************************************************************/
731 fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
734 /* printf(" FieldCount: %d\n",c->fieldscount);
735 utf_display(c->name); */
736 for (i = 0; i < c->fieldscount; i++) {
737 /* utf_display(c->fields[i].name);
739 utf_display(c->fields[i].descriptor);
741 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
742 return &(c->fields[i]);
745 if (c->super) return jclass_findfield(c->super,name,desc);
751 /* GetVersion ******************************************************************
753 Returns the major version number in the higher 16 bits and the
754 minor version number in the lower 16 bits.
756 *******************************************************************************/
758 jint GetVersion(JNIEnv *env)
760 /* GNU classpath currently supports JNI 1.2 */
762 return JNI_VERSION_1_2;
766 /* Class Operations ***********************************************************/
768 /* DefineClass *****************************************************************
770 Loads a class from a buffer of raw class data. The buffer
771 containing the raw class data is not referenced by the VM after the
772 DefineClass call returns, and it may be discarded if desired.
774 *******************************************************************************/
776 jclass DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize bufLen)
782 c = class_new(utf_new_char_classname((char *) name));
784 #if defined(USE_THREADS)
785 /* enter a monitor on the class */
787 builtin_monitorenter((java_objectheader *) c);
794 /* build a classbuffer with the given data */
795 cb = NEW(classbuffer);
798 cb->data = (u1 *) buf;
799 cb->pos = cb->data - 1;
801 r = class_load_intern(cb);
803 /* if return value is NULL, we had a problem and the class is not loaded */
807 /* now free the allocated memory, otherwise we could ran into a DOS */
812 FREE(cb, classbuffer);
818 #if defined(USE_THREADS)
819 /* leave the monitor */
821 builtin_monitorexit((java_objectheader *) c);
824 /* XXX link the class here? */
825 /* if (class_link(c)) */
829 c->classloader = loader;
830 use_class_as_object(r);
837 /* FindClass *******************************************************************
839 This function loads a locally-defined class. It searches the
840 directories and zip files specified by the CLASSPATH environment
841 variable for the class with the specified name.
843 *******************************************************************************/
845 jclass FindClass(JNIEnv *env, const char *name)
849 c = class_new(utf_new_char_classname((char *) name));
851 if (!class_load(c) || !class_link(c))
854 use_class_as_object(c);
860 /*******************************************************************************
862 converts java.lang.reflect.Method or
863 java.lang.reflect.Constructor object to a method ID
865 *******************************************************************************/
867 jmethodID FromReflectedMethod(JNIEnv* env, jobject method)
869 log_text("JNI-Call: FromReflectedMethod: IMPLEMENT ME!!!");
875 /* GetSuperclass ***************************************************************
877 If clazz represents any class other than the class Object, then
878 this function returns the object that represents the superclass of
879 the class specified by clazz.
881 *******************************************************************************/
883 jclass GetSuperclass(JNIEnv* env, jclass sub)
887 c = ((classinfo *) sub)->super;
892 use_class_as_object(c);
898 /* IsAssignableFrom ************************************************************
900 Determines whether an object of sub can be safely cast to sup.
902 *******************************************************************************/
904 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
906 return builtin_isanysubclass(sub, sup);
910 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
912 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
914 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!!!");
920 /* Throw ***********************************************************************
922 Causes a java.lang.Throwable object to be thrown.
924 *******************************************************************************/
926 jint Throw(JNIEnv *env, jthrowable obj)
928 *exceptionptr = (java_objectheader *) obj;
934 /* ThrowNew ********************************************************************
936 Constructs an exception object from the specified class with the message
937 specified by message and causes that exception to be thrown.
939 *******************************************************************************/
941 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
943 java_lang_Throwable *o;
945 /* instantiate exception object */
947 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
948 (java_lang_String *) javastring_new_char(msg));
953 *exceptionptr = (java_objectheader *) o;
959 /* ExceptionOccurred ***********************************************************
961 Determines if an exception is being thrown. The exception stays
962 being thrown until either the native code calls ExceptionClear(),
963 or the Java code handles the exception.
965 *******************************************************************************/
967 jthrowable ExceptionOccurred(JNIEnv *env)
969 return (jthrowable) *exceptionptr;
973 /* ExceptionDescribe ***********************************************************
975 Prints an exception and a backtrace of the stack to a system
976 error-reporting channel, such as stderr. This is a convenience
977 routine provided for debugging.
979 *******************************************************************************/
981 void ExceptionDescribe(JNIEnv *env)
983 java_objectheader *e;
989 /* clear exception, because we are calling jit code again */
991 *exceptionptr = NULL;
993 /* get printStackTrace method from exception class */
995 m = class_resolveclassmethod(e->vftbl->class,
1002 /* XXX what should we do? */
1005 /* print the stacktrace */
1007 asm_calljavafunction(m, e, NULL, NULL, NULL);
1012 /* ExceptionClear **************************************************************
1014 Clears any exception that is currently being thrown. If no
1015 exception is currently being thrown, this routine has no effect.
1017 *******************************************************************************/
1019 void ExceptionClear(JNIEnv *env)
1021 *exceptionptr = NULL;
1025 /* FatalError ******************************************************************
1027 Raises a fatal error and does not expect the VM to recover. This
1028 function does not return.
1030 *******************************************************************************/
1032 void FatalError(JNIEnv *env, const char *msg)
1034 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
1038 /******************* creates a new local reference frame **************************/
1040 jint PushLocalFrame(JNIEnv* env, jint capacity)
1047 /**************** Pops off the current local reference frame **********************/
1049 jobject PopLocalFrame(JNIEnv* env, jobject result)
1051 log_text("JNI-Call: PopLocalFrame");
1058 /*************** Deletes the local reference pointed to by localRef ***************/
1060 void DeleteLocalRef (JNIEnv* env, jobject localRef)
1062 /* log_text("JNI-Call: DeleteLocalRef");*/
1067 /* IsSameObject ****************************************************************
1069 Tests whether two references refer to the same Java object.
1071 *******************************************************************************/
1073 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1075 return (ref1 == ref2);
1079 /***** Creates a new local reference that refers to the same object as ref *******/
1081 jobject NewLocalRef (JNIEnv* env, jobject ref)
1086 /***********************************************************************************
1088 Ensures that at least a given number of local references can
1089 be created in the current thread
1091 **********************************************************************************/
1093 jint EnsureLocalCapacity (JNIEnv* env, jint capacity)
1095 return 0; /* return 0 on success */
1099 /* AllocObject *****************************************************************
1101 Allocates a new Java object without invoking any of the constructors for the
1102 object. Returns a reference to the object.
1104 *******************************************************************************/
1106 jobject AllocObject(JNIEnv *env, jclass clazz)
1108 java_objectheader *o;
1110 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1112 new_exception_utfmessage(string_java_lang_InstantiationException,
1117 o = builtin_new(clazz);
1123 /* NewObject *******************************************************************
1125 Constructs a new Java object. The method ID indicates which constructor
1126 method to invoke. This ID must be obtained by calling GetMethodID() with
1127 <init> as the method name and void (V) as the return type.
1129 *******************************************************************************/
1131 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1133 java_objectheader *o;
1135 int argcount=get_parametercount(methodID);
1141 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
1142 log_text("Too many arguments. NewObject does not support that");
1149 o = builtin_new(clazz);
1154 va_start(vaargs, methodID);
1155 for (i = 0; i < argcount; i++) {
1156 args[i] = va_arg(vaargs, void*);
1160 /* call constructor */
1162 asm_calljavafunction(methodID, o, args[0], args[1], args[2]);
1168 /***********************************************************************************
1170 Constructs a new Java object
1171 arguments that are to be passed to the constructor are placed in va_list args
1173 ***********************************************************************************/
1175 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1177 /* log_text("JNI-Call: NewObjectV"); */
1183 /***********************************************************************************
1185 Constructs a new Java object
1186 arguments that are to be passed to the constructor are placed in
1187 args array of jvalues
1189 ***********************************************************************************/
1191 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1193 /* log_text("JNI-Call: NewObjectA"); */
1199 /************************ returns the class of an object **************************/
1201 jclass GetObjectClass(JNIEnv* env, jobject obj)
1203 classinfo *c = obj->vftbl->class;
1205 use_class_as_object(c);
1211 /************* tests whether an object is an instance of a class ******************/
1213 jboolean IsInstanceOf(JNIEnv* env, jobject obj, jclass clazz)
1215 return builtin_instanceof(obj,clazz);
1219 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1221 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1223 log_text("JNI-Call: FromReflectedField");
1229 /**********************************************************************************
1231 converts a method ID to a java.lang.reflect.Method or
1232 java.lang.reflect.Constructor object
1234 **********************************************************************************/
1236 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1238 log_text("JNI-Call: ToReflectedMethod");
1244 /* GetMethodID *****************************************************************
1246 returns the method ID for an instance method
1248 *******************************************************************************/
1250 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1254 m = class_resolvemethod(clazz,
1255 utf_new_char((char *) name),
1256 utf_new_char((char *) sig));
1258 if (!m || (m->flags & ACC_STATIC)) {
1260 new_exception_message(string_java_lang_NoSuchMethodError, name);
1269 /******************** JNI-functions for calling instance methods ******************/
1271 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1276 /* log_text("JNI-Call: CallObjectMethod");*/
1278 va_start(vaargs, methodID);
1279 ret = callObjectMethod(obj, methodID, vaargs);
1286 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1288 return callObjectMethod(obj,methodID,args);
1292 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1294 log_text("JNI-Call: CallObjectMethodA");
1302 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1307 /* log_text("JNI-Call: CallBooleanMethod");*/
1309 va_start(vaargs,methodID);
1310 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',vaargs);
1316 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1318 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',args);
1322 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1324 log_text("JNI-Call: CallBooleanMethodA");
1329 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1334 /* log_text("JNI-Call: CallVyteMethod");*/
1336 va_start(vaargs,methodID);
1337 ret = callIntegerMethod(obj,get_virtual(obj,methodID),'B',vaargs);
1343 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1345 /* log_text("JNI-Call: CallByteMethodV");*/
1346 return callIntegerMethod(obj,methodID,'B',args);
1350 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1352 log_text("JNI-Call: CallByteMethodA");
1358 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1363 /* log_text("JNI-Call: CallCharMethod");*/
1365 va_start(vaargs,methodID);
1366 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'C', vaargs);
1373 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1375 /* log_text("JNI-Call: CallCharMethodV");*/
1376 return callIntegerMethod(obj,get_virtual(obj,methodID),'C',args);
1380 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1382 log_text("JNI-Call: CallCharMethodA");
1388 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1393 /* log_text("JNI-Call: CallShortMethod");*/
1395 va_start(vaargs, methodID);
1396 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'S', vaargs);
1403 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1405 return callIntegerMethod(obj, get_virtual(obj, methodID), 'S', args);
1409 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1411 log_text("JNI-Call: CallShortMethodA");
1418 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1423 va_start(vaargs,methodID);
1424 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'I', vaargs);
1431 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1433 return callIntegerMethod(obj, get_virtual(obj, methodID), 'I', args);
1437 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1439 log_text("JNI-Call: CallIntMethodA");
1446 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1451 va_start(vaargs,methodID);
1452 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1459 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1461 return callLongMethod(obj,get_virtual(obj, methodID),args);
1465 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1467 log_text("JNI-Call: CallLongMethodA");
1474 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1479 /* log_text("JNI-Call: CallFloatMethod");*/
1481 va_start(vaargs,methodID);
1482 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'F');
1489 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1491 log_text("JNI-Call: CallFloatMethodV");
1492 return callFloatMethod(obj, get_virtual(obj, methodID), args, 'F');
1496 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1498 log_text("JNI-Call: CallFloatMethodA");
1505 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1510 /* log_text("JNI-Call: CallDoubleMethod");*/
1512 va_start(vaargs,methodID);
1513 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'D');
1520 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1522 log_text("JNI-Call: CallDoubleMethodV");
1523 return callFloatMethod(obj, get_virtual(obj, methodID), args, 'D');
1527 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1529 log_text("JNI-Call: CallDoubleMethodA");
1535 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1539 va_start(vaargs,methodID);
1540 (void) callIntegerMethod(obj, get_virtual(obj, methodID), 'V', vaargs);
1545 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1547 log_text("JNI-Call: CallVoidMethodV");
1548 (void)callIntegerMethod(obj,get_virtual(obj,methodID),'V',args);
1552 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1554 log_text("JNI-Call: CallVoidMethodA");
1559 jobject CallNonvirtualObjectMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1561 log_text("JNI-Call: CallNonvirtualObjectMethod");
1567 jobject CallNonvirtualObjectMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1569 log_text("JNI-Call: CallNonvirtualObjectMethodV");
1575 jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1577 log_text("JNI-Call: CallNonvirtualObjectMethodA");
1584 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1589 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1591 va_start(vaargs,methodID);
1592 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',vaargs);
1599 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1601 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1602 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',args);
1606 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1608 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1615 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1620 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1622 va_start(vaargs,methodID);
1623 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',vaargs);
1629 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1631 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1632 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',args);
1637 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1639 log_text("JNI-Call: CallNonvirtualByteMethodA");
1646 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1651 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1653 va_start(vaargs,methodID);
1654 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',vaargs);
1660 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1662 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1663 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',args);
1667 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1669 log_text("JNI-Call: CallNonvirtualCharMethodA");
1676 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1681 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1683 va_start(vaargs,methodID);
1684 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',vaargs);
1690 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1692 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1693 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',args);
1697 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1699 log_text("JNI-Call: CallNonvirtualShortMethodA");
1706 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1712 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1714 va_start(vaargs,methodID);
1715 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',vaargs);
1721 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1723 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1724 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',args);
1728 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1730 log_text("JNI-Call: CallNonvirtualIntMethodA");
1737 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1739 log_text("JNI-Call: CallNonvirtualLongMethod");
1745 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1747 log_text("JNI-Call: CallNonvirtualLongMethodV");
1753 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1755 log_text("JNI-Call: CallNonvirtualLongMethodA");
1762 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1767 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1770 va_start(vaargs,methodID);
1771 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'F');
1778 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1780 log_text("JNI-Call: CallNonvirtualFloatMethodV");
1781 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'F');
1785 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1787 log_text("JNI-Call: CallNonvirtualFloatMethodA");
1794 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1798 log_text("JNI-Call: CallNonvirtualDoubleMethod");
1800 va_start(vaargs,methodID);
1801 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'D');
1808 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1810 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
1811 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'D');
1815 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1817 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
1824 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1828 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
1830 va_start(vaargs,methodID);
1831 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',vaargs);
1837 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1839 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
1841 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',args);
1846 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1848 log_text("JNI-Call: CallNonvirtualVoidMethodA");
1851 /************************* JNI-functions for accessing fields ************************/
1853 jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
1857 /* log_text("========================= searching for:");
1860 f = jclass_findfield(clazz,
1861 utf_new_char ((char*) name),
1862 utf_new_char ((char*) sig)
1866 /*utf_display(clazz->name);
1869 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
1874 /*************************** retrieve fieldid, abort on error ************************/
1876 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
1878 jfieldID id = GetFieldID(env, clazz, name, sig);
1882 utf_display(clazz->name);
1883 log_text("\nfield:");
1888 panic("setfield_critical failed");
1893 jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
1896 jobject dbg,dretval,*dpretval;
1897 long int dli1, dli2, dli3;
1899 printf("GetObjectField(1): thread: %s obj: %p name: %s desc: %s \n",GetStringUTFChars(env,
1900 ((threadobject *) THREADOBJECT)->o
1902 ,obj,((fieldinfo*)fieldID)->name->text,(fieldID->descriptor)->text);
1904 dbg = getField(obj,jobject,fieldID);
1905 dli1 = (long int) obj;
1906 dli2 = (long int) fieldID->offset;
1908 dpretval = (jobject*) dli3;
1909 dretval = *dpretval;
1914 tmp = FindClass(env, "java/lang/Object");
1915 mid = GetMethodID(env,tmp,"toString","()Ljava/lang/String;");
1916 jstr = CallObjectMethod(env,dbg,mid);*/
1918 /* printf("GetObjectField(2): retval %p (obj: %#lx + offset: %#lx = %#lx (jobject*) %p (jobject) %p\n"
1919 ,dbg, dli1, dli2, dli3,dpretval, dretval);*/
1924 return getField(obj,jobject,fieldID);
1927 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
1929 return getField(obj,jboolean,fieldID);
1933 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
1935 return getField(obj,jbyte,fieldID);
1939 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
1941 return getField(obj,jchar,fieldID);
1945 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
1947 return getField(obj,jshort,fieldID);
1951 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
1953 return getField(obj,jint,fieldID);
1957 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
1959 return getField(obj,jlong,fieldID);
1963 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
1965 return getField(obj,jfloat,fieldID);
1969 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
1971 return getField(obj,jdouble,fieldID);
1974 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
1976 setField(obj,jobject,fieldID,val);
1980 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
1982 setField(obj,jboolean,fieldID,val);
1986 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
1988 setField(obj,jbyte,fieldID,val);
1992 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
1994 setField(obj,jchar,fieldID,val);
1998 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
2000 setField(obj,jshort,fieldID,val);
2004 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
2006 setField(obj,jint,fieldID,val);
2010 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
2012 setField(obj,jlong,fieldID,val);
2016 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
2018 setField(obj,jfloat,fieldID,val);
2022 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
2024 setField(obj,jdouble,fieldID,val);
2028 /**************** JNI-functions for calling static methods **********************/
2030 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2034 m = class_resolvemethod(clazz,
2035 utf_new_char((char *) name),
2036 utf_new_char((char *) sig));
2038 if (!m || !(m->flags & ACC_STATIC)) {
2040 new_exception_message(string_java_lang_NoSuchMethodError, name);
2049 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2054 /* log_text("JNI-Call: CallStaticObjectMethod");*/
2056 va_start(vaargs, methodID);
2057 ret = callObjectMethod(0, methodID, vaargs);
2064 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2066 /* log_text("JNI-Call: CallStaticObjectMethodV"); */
2068 return callObjectMethod(0,methodID,args);
2072 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2074 log_text("JNI-Call: CallStaticObjectMethodA");
2080 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2085 va_start(vaargs, methodID);
2086 ret = (jboolean) callIntegerMethod(0, methodID, 'Z', vaargs);
2093 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2095 return (jboolean) callIntegerMethod(0, methodID, 'Z', args);
2099 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2101 log_text("JNI-Call: CallStaticBooleanMethodA");
2107 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2112 /* log_text("JNI-Call: CallStaticByteMethod");*/
2114 va_start(vaargs, methodID);
2115 ret = (jbyte) callIntegerMethod(0, methodID, 'B', vaargs);
2122 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2124 return (jbyte) callIntegerMethod(0, methodID, 'B', args);
2128 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2130 log_text("JNI-Call: CallStaticByteMethodA");
2136 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2141 /* log_text("JNI-Call: CallStaticByteMethod");*/
2143 va_start(vaargs, methodID);
2144 ret = (jchar) callIntegerMethod(0, methodID, 'C', vaargs);
2151 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2153 return (jchar) callIntegerMethod(0, methodID, 'C', args);
2157 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2159 log_text("JNI-Call: CallStaticCharMethodA");
2166 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2171 /* log_text("JNI-Call: CallStaticByteMethod");*/
2173 va_start(vaargs, methodID);
2174 ret = (jshort) callIntegerMethod(0, methodID, 'S', vaargs);
2181 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2183 /*log_text("JNI-Call: CallStaticShortMethodV");*/
2184 return (jshort) callIntegerMethod(0, methodID, 'S', args);
2188 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2190 log_text("JNI-Call: CallStaticShortMethodA");
2197 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2202 /* log_text("JNI-Call: CallStaticIntMethod");*/
2204 va_start(vaargs, methodID);
2205 ret = callIntegerMethod(0, methodID, 'I', vaargs);
2212 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2214 log_text("JNI-Call: CallStaticIntMethodV");
2216 return callIntegerMethod(0, methodID, 'I', args);
2220 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2222 log_text("JNI-Call: CallStaticIntMethodA");
2229 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2234 /* log_text("JNI-Call: CallStaticLongMethod");*/
2236 va_start(vaargs, methodID);
2237 ret = callLongMethod(0, methodID, vaargs);
2244 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2246 log_text("JNI-Call: CallStaticLongMethodV");
2248 return callLongMethod(0,methodID,args);
2252 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2254 log_text("JNI-Call: CallStaticLongMethodA");
2261 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2266 /* log_text("JNI-Call: CallStaticLongMethod");*/
2268 va_start(vaargs, methodID);
2269 ret = callFloatMethod(0, methodID, vaargs, 'F');
2276 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2279 return callFloatMethod(0, methodID, args, 'F');
2284 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2286 log_text("JNI-Call: CallStaticFloatMethodA");
2293 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2298 /* log_text("JNI-Call: CallStaticDoubleMethod");*/
2300 va_start(vaargs,methodID);
2301 ret = callFloatMethod(0, methodID, vaargs, 'D');
2308 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2310 log_text("JNI-Call: CallStaticDoubleMethodV");
2312 return callFloatMethod(0, methodID, args, 'D');
2316 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2318 log_text("JNI-Call: CallStaticDoubleMethodA");
2324 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2328 va_start(vaargs, methodID);
2329 (void) callIntegerMethod(0, methodID, 'V', vaargs);
2334 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2336 log_text("JNI-Call: CallStaticVoidMethodV");
2337 (void)callIntegerMethod(0, methodID, 'V', args);
2341 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2343 log_text("JNI-Call: CallStaticVoidMethodA");
2347 /****************** JNI-functions for accessing static fields ********************/
2349 jfieldID GetStaticFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
2353 f = jclass_findfield(clazz,
2354 utf_new_char ((char*) name),
2355 utf_new_char ((char*) sig)
2358 if (!f) *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2364 jobject GetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2367 return fieldID->value.a;
2371 jboolean GetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2374 return fieldID->value.i;
2378 jbyte GetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2381 return fieldID->value.i;
2385 jchar GetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2388 return fieldID->value.i;
2392 jshort GetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2395 return fieldID->value.i;
2399 jint GetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2402 return fieldID->value.i;
2406 jlong GetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2409 return fieldID->value.l;
2413 jfloat GetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2416 return fieldID->value.f;
2420 jdouble GetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2423 return fieldID->value.d;
2428 void SetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2431 fieldID->value.a = value;
2435 void SetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2438 fieldID->value.i = value;
2442 void SetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2445 fieldID->value.i = value;
2449 void SetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2452 fieldID->value.i = value;
2456 void SetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2459 fieldID->value.i = value;
2463 void SetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2466 fieldID->value.i = value;
2470 void SetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2473 fieldID->value.l = value;
2477 void SetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2480 fieldID->value.f = value;
2484 void SetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2487 fieldID->value.d = value;
2491 /***** create new java.lang.String object from an array of Unicode characters ****/
2493 jstring NewString (JNIEnv *env, const jchar *buf, jsize len)
2496 java_lang_String *s;
2499 s = (java_lang_String*) builtin_new (class_java_lang_String);
2500 a = builtin_newarray_char (len);
2502 /* javastring or characterarray could not be created */
2503 if ( (!a) || (!s) ) return NULL;
2506 for (i=0; i<len; i++) a->data[i] = buf[i];
2515 static char emptyString[]="";
2516 static jchar emptyStringJ[]={0,0};
2518 /******************* returns the length of a Java string ***************************/
2520 jsize GetStringLength (JNIEnv *env, jstring str)
2522 return ((java_lang_String*) str)->count;
2526 /******************** convertes javastring to u2-array ****************************/
2528 u2 *javastring_tou2 (jstring so)
2530 java_lang_String *s = (java_lang_String*) so;
2535 if (!s) return NULL;
2538 if (!a) return NULL;
2540 /* allocate memory */
2541 stringbuffer = MNEW( u2 , s->count + 1 );
2544 for (i=0; i<s->count; i++) stringbuffer[i] = a->data[s->offset+i];
2546 /* terminate string */
2547 stringbuffer[i] = '\0';
2549 return stringbuffer;
2552 /********* returns a pointer to an array of Unicode characters of the string *******/
2554 const jchar *GetStringChars (JNIEnv *env, jstring str, jboolean *isCopy)
2556 jchar *jc=javastring_tou2(str);
2559 if (isCopy) *isCopy=JNI_TRUE;
2562 if (isCopy) *isCopy=JNI_TRUE;
2563 return emptyStringJ;
2566 /**************** native code no longer needs access to chars **********************/
2568 void ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars)
2570 if (chars==emptyStringJ) return;
2571 MFREE(((jchar*) chars),jchar,((java_lang_String*) str)->count+1);
2575 /* NewStringUTF ****************************************************************
2577 Constructs a new java.lang.String object from an array of UTF-8 characters.
2579 *******************************************************************************/
2581 jstring NewStringUTF(JNIEnv *env, const char *bytes)
2583 return (jstring) javastring_new(utf_new_char(bytes));
2587 /****************** returns the utf8 length in bytes of a string *******************/
2589 jsize GetStringUTFLength (JNIEnv *env, jstring string)
2591 java_lang_String *s = (java_lang_String*) string;
2593 return (jsize) u2_utflength(s->value->data, s->count);
2597 /************ converts a Javastring to an array of UTF-8 characters ****************/
2599 const char* GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
2603 u = javastring_toutf((java_lang_String *) string, false);
2606 *isCopy = JNI_FALSE;
2616 /***************** native code no longer needs access to utf ***********************/
2618 void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
2620 /*we don't release utf chars right now, perhaps that should be done later. Since there is always one reference
2621 the garbage collector will never get them*/
2623 log_text("JNI-Call: ReleaseStringUTFChars");
2624 utf_display(utf_new_char(chars));
2628 /************************** array operations ***************************************/
2630 jsize GetArrayLength(JNIEnv *env, jarray array)
2636 jobjectArray NewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init)
2638 java_objectarray *j;
2641 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2645 j = builtin_anewarray(len, clazz);
2651 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
2655 if (index < array->header.size)
2656 j = array->data[index];
2658 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2664 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
2666 if (index >= array->header.size)
2667 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2670 /* check if the class of value is a subclass of the element class of the array */
2671 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
2672 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
2675 array->data[index] = val;
2681 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
2683 java_booleanarray *j;
2686 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2690 j = builtin_newarray_boolean(len);
2696 jbyteArray NewByteArray(JNIEnv *env, jsize len)
2701 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2705 j = builtin_newarray_byte(len);
2711 jcharArray NewCharArray(JNIEnv *env, jsize len)
2716 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2720 j = builtin_newarray_char(len);
2726 jshortArray NewShortArray(JNIEnv *env, jsize len)
2731 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2735 j = builtin_newarray_short(len);
2741 jintArray NewIntArray(JNIEnv *env, jsize len)
2746 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2750 j = builtin_newarray_int(len);
2756 jlongArray NewLongArray(JNIEnv *env, jsize len)
2761 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2765 j = builtin_newarray_long(len);
2771 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
2776 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2780 j = builtin_newarray_float(len);
2786 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
2788 java_doublearray *j;
2791 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2795 j = builtin_newarray_double(len);
2801 jboolean * GetBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *isCopy)
2803 if (isCopy) *isCopy = JNI_FALSE;
2808 jbyte * GetByteArrayElements (JNIEnv *env, jbyteArray array, jboolean *isCopy)
2810 if (isCopy) *isCopy = JNI_FALSE;
2815 jchar * GetCharArrayElements (JNIEnv *env, jcharArray array, jboolean *isCopy)
2817 if (isCopy) *isCopy = JNI_FALSE;
2822 jshort * GetShortArrayElements (JNIEnv *env, jshortArray array, jboolean *isCopy)
2824 if (isCopy) *isCopy = JNI_FALSE;
2829 jint * GetIntArrayElements (JNIEnv *env, jintArray array, jboolean *isCopy)
2831 if (isCopy) *isCopy = JNI_FALSE;
2836 jlong * GetLongArrayElements (JNIEnv *env, jlongArray array, jboolean *isCopy)
2838 if (isCopy) *isCopy = JNI_FALSE;
2843 jfloat * GetFloatArrayElements (JNIEnv *env, jfloatArray array, jboolean *isCopy)
2845 if (isCopy) *isCopy = JNI_FALSE;
2850 jdouble * GetDoubleArrayElements (JNIEnv *env, jdoubleArray array, jboolean *isCopy)
2852 if (isCopy) *isCopy = JNI_FALSE;
2858 void ReleaseBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode)
2864 void ReleaseByteArrayElements (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode)
2870 void ReleaseCharArrayElements (JNIEnv *env, jcharArray array, jchar *elems, jint mode)
2876 void ReleaseShortArrayElements (JNIEnv *env, jshortArray array, jshort *elems, jint mode)
2882 void ReleaseIntArrayElements (JNIEnv *env, jintArray array, jint *elems, jint mode)
2888 void ReleaseLongArrayElements (JNIEnv *env, jlongArray array, jlong *elems, jint mode)
2894 void ReleaseFloatArrayElements (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode)
2900 void ReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode)
2906 void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2908 if (start < 0 || len < 0 || start + len > array->header.size)
2909 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2912 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2916 void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
2918 if (start < 0 || len < 0 || start + len > array->header.size)
2919 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2922 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2926 void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
2928 if (start < 0 || len < 0 || start + len > array->header.size)
2929 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2932 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2936 void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
2938 if (start < 0 || len < 0 || start + len > array->header.size)
2939 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2942 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2946 void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
2948 if (start < 0 || len < 0 || start + len > array->header.size)
2949 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2952 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2956 void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
2958 if (start < 0 || len < 0 || start + len > array->header.size)
2959 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2962 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2966 void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
2968 if (start < 0 || len < 0 || start + len > array->header.size)
2969 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2972 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2976 void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
2978 if (start < 0 || len < 0 || start+len>array->header.size)
2979 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2982 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2986 void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2988 if (start < 0 || len < 0 || start + len > array->header.size)
2989 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2992 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2996 void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
2998 if (start < 0 || len < 0 || start + len > array->header.size)
2999 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3002 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3006 void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
3008 if (start < 0 || len < 0 || start + len > array->header.size)
3009 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3012 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3017 void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
3019 if (start < 0 || len < 0 || start + len > array->header.size)
3020 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3023 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3027 void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
3029 if (start < 0 || len < 0 || start + len > array->header.size)
3030 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3033 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3038 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
3040 if (start < 0 || len < 0 || start + len > array->header.size)
3041 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3044 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3049 void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
3051 if (start < 0 || len < 0 || start + len > array->header.size)
3052 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3055 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3060 void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
3062 if (start < 0 || len < 0 || start + len > array->header.size)
3063 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3066 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3070 jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
3072 log_text("JNI-Call: RegisterNatives");
3077 jint UnregisterNatives (JNIEnv* env, jclass clazz)
3079 log_text("JNI-Call: UnregisterNatives");
3084 /* Monitor Operations *********************************************************/
3086 /* MonitorEnter ****************************************************************
3088 Enters the monitor associated with the underlying Java object
3091 *******************************************************************************/
3093 jint MonitorEnter(JNIEnv *env, jobject obj)
3096 *exceptionptr = new_nullpointerexception();
3100 #if defined(USE_THREADS)
3101 builtin_monitorenter(obj);
3108 /* MonitorExit *****************************************************************
3110 The current thread must be the owner of the monitor associated with
3111 the underlying Java object referred to by obj. The thread
3112 decrements the counter indicating the number of times it has
3113 entered this monitor. If the value of the counter becomes zero, the
3114 current thread releases the monitor.
3116 *******************************************************************************/
3118 jint MonitorExit(JNIEnv *env, jobject obj)
3121 *exceptionptr = new_nullpointerexception();
3125 #if defined(USE_THREADS)
3126 builtin_monitorexit(obj);
3133 /* JavaVM Interface ***********************************************************/
3135 /* GetJavaVM *******************************************************************
3137 Returns the Java VM interface (used in the Invocation API)
3138 associated with the current thread. The result is placed at the
3139 location pointed to by the second argument, vm.
3141 *******************************************************************************/
3143 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
3151 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3153 log_text("JNI-Call: GetStringRegion");
3157 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3159 log_text("JNI-Call: GetStringUTFRegion");
3163 /************** obtain direct pointer to array elements ***********************/
3165 void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
3167 java_objectheader *s = (java_objectheader*) array;
3168 arraydescriptor *desc = s->vftbl->arraydesc;
3170 if (!desc) return NULL;
3172 return ((u1*)s) + desc->dataoffset;
3176 void ReleasePrimitiveArrayCritical (JNIEnv* env, jarray array, void *carray, jint mode)
3178 log_text("JNI-Call: ReleasePrimitiveArrayCritical");
3183 /**** returns a pointer to an array of Unicode characters of the string *******/
3185 const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
3187 log_text("JNI-Call: GetStringCritical");
3189 return GetStringChars(env,string,isCopy);
3192 /*********** native code no longer needs access to chars **********************/
3194 void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
3196 log_text("JNI-Call: ReleaseStringCritical");
3198 ReleaseStringChars(env,string,cstring);
3202 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3204 log_text("JNI-Call: NewWeakGlobalRef");
3210 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
3212 log_text("JNI-Call: DeleteWeakGlobalRef");
3218 /** Creates a new global reference to the object referred to by the obj argument **/
3220 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
3226 MonitorEnter(env, *global_ref_table);
3228 refcount = CallObjectMethod(env, *global_ref_table, getmid, lobj);
3229 val = (refcount == NULL) ? 0 : CallIntMethod(env, refcount, intvalue);
3230 newval = NewObject(env, intclass, newint, val + 1);
3232 if (newval != NULL) {
3233 CallObjectMethod(env, *global_ref_table, putmid, lobj, newval);
3234 MonitorExit(env, *global_ref_table);
3238 log_text("JNI-NewGlobalRef: unable to create new java.lang.Integer");
3239 MonitorExit(env, *global_ref_table);
3244 /************* Deletes the global reference pointed to by globalRef **************/
3246 void DeleteGlobalRef(JNIEnv* env, jobject gref)
3251 MonitorEnter(env, *global_ref_table);
3252 refcount = CallObjectMethod(env, *global_ref_table, getmid, gref);
3254 if (refcount == NULL) {
3255 log_text("JNI-DeleteGlobalRef: unable to find global reference");
3259 val = CallIntMethod(env, refcount, intvalue);
3263 CallObjectMethod(env, *global_ref_table, removemid,refcount);
3266 jobject newval = NewObject(env, intclass, newint, val);
3268 if (newval != NULL) {
3269 CallObjectMethod(env,*global_ref_table, putmid,newval);
3272 log_text("JNI-DeleteGlobalRef: unable to create new java.lang.Integer");
3276 MonitorExit(env,*global_ref_table);
3280 /* ExceptionCheck *****************************************************************
3282 check for pending exception
3284 **********************************************************************************/
3286 jboolean ExceptionCheck(JNIEnv *env)
3288 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
3292 /* New JNI 1.4 functions ******************************************************/
3294 /* NewDirectByteBuffer *********************************************************
3296 Allocates and returns a direct java.nio.ByteBuffer referring to the block of
3297 memory starting at the memory address address and extending capacity bytes.
3299 *******************************************************************************/
3301 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3303 log_text("NewDirectByteBuffer: IMPLEMENT ME!");
3309 /* GetDirectBufferAddress ******************************************************
3311 Fetches and returns the starting address of the memory region referenced by
3312 the given direct java.nio.Buffer.
3314 *******************************************************************************/
3316 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
3318 log_text("GetDirectBufferAddress: IMPLEMENT ME!");
3324 /* GetDirectBufferCapacity *****************************************************
3326 Fetches and returns the capacity in bytes of the memory region referenced by
3327 the given direct java.nio.Buffer.
3329 *******************************************************************************/
3331 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3333 log_text("GetDirectBufferCapacity: IMPLEMENT ME!");
3339 jint DestroyJavaVM(JavaVM *vm)
3341 log_text("DestroyJavaVM called");
3347 jint AttachCurrentThread(JavaVM *vm, void **par1, void *par2)
3349 log_text("AttachCurrentThread called");
3355 jint DetachCurrentThread(JavaVM *vm)
3357 log_text("DetachCurrentThread called");
3363 jint GetEnv(JavaVM *vm, void **env, jint version)
3365 if ((version != JNI_VERSION_1_1) && (version != JNI_VERSION_1_2) &&
3366 (version != JNI_VERSION_1_4)) {
3368 return JNI_EVERSION;
3372 TODO: If the current thread is not attached to the VM...
3375 return JNI_EDETACHED;
3385 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
3387 log_text("AttachCurrentThreadAsDaemon called");
3392 /************* JNI Initialization ****************************************************/
3394 jobject jni_init1(JNIEnv* env, jobject lobj) {
3395 #if defined(USE_THREADS)
3396 while (initrunning) {yieldThread();} /* wait until init is done */
3398 if (global_ref_table == NULL) {
3401 #if defined(USE_THREADS)
3403 /* wait until jni_init is done */
3404 MonitorEnter(env, *global_ref_table) ;
3405 MonitorExit(env, *global_ref_table);
3408 return NewGlobalRef(env, lobj);
3410 void jni_init2(JNIEnv* env, jobject gref) {
3411 log_text("DeleteGlobalref called before NewGlobalref");
3412 #if defined(USE_THREADS)
3413 while (initrunning) {yieldThread();} /* wait until init is done */
3415 if (global_ref_table == NULL) {
3418 #if defined(USE_THREADS)
3420 /* wait until jni_init is done */
3421 MonitorEnter(env, *global_ref_table) ;
3422 MonitorExit(env, *global_ref_table);
3425 DeleteGlobalRef(env, gref);
3432 log_text("JNI-Init: initialize global_ref_table");
3433 /* initalize global reference table */
3434 ihmclass = FindClass(NULL, "java/util/IdentityHashMap");
3436 if (ihmclass == NULL) {
3437 log_text("JNI-Init: unable to find java.util.IdentityHashMap");
3440 mid = GetMethodID(NULL, ihmclass, "<init>","()V");
3442 log_text("JNI-Init: unable to find constructor in java.util.IdentityHashMap");
3445 global_ref_table = (jobject*)heap_allocate(sizeof(jobject),true,NULL);
3447 *global_ref_table = NewObject(NULL,ihmclass,mid);
3449 if (*global_ref_table == NULL) {
3450 log_text("JNI-Init: unable to create new global_ref_table");
3453 initrunning = false;
3455 getmid = GetMethodID(NULL, ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3457 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3460 getmid = GetMethodID(NULL ,ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3461 if (getmid == NULL) {
3462 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3465 putmid = GetMethodID(NULL, ihmclass, "put","(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
3466 if (putmid == NULL) {
3467 log_text("JNI-Init: unable to find method \"put\" in java.util.IdentityHashMap");
3470 intclass = FindClass(NULL, "java/lang/Integer");
3471 if (intclass == NULL) {
3472 log_text("JNI-Init: unable to find java.lang.Integer");
3475 newint = GetMethodID(NULL, intclass, "<init>","(I)V");
3476 if (newint == NULL) {
3477 log_text("JNI-Init: unable to find constructor in java.lang.Integer");
3480 intvalue = GetMethodID(NULL, intclass, "intValue","()I");
3481 if (intvalue == NULL) {
3482 log_text("JNI-Init: unable to find method \"intValue\" in java.lang.Integer");
3485 removemid = GetMethodID(NULL, ihmclass, "remove","(Ljava/lang/Object;)Ljava/lang/Object;");
3486 if (removemid == NULL) {
3487 log_text("JNI-DeleteGlobalRef: unable to find method \"remove\" in java.lang.Object");
3490 /* set NewGlobalRef, DeleteGlobalRef envTable entry to real implementation */
3492 JNI_JNIEnvTable.NewGlobalRef = &NewGlobalRef;
3493 JNI_JNIEnvTable.DeleteGlobalRef = &DeleteGlobalRef;
3497 /* JNI invocation table *******************************************************/
3499 const struct JNIInvokeInterface JNI_JavaVMTable = {
3505 AttachCurrentThread,
3506 DetachCurrentThread,
3508 AttachCurrentThreadAsDaemon
3512 /* JNI function table *********************************************************/
3514 struct JNINativeInterface JNI_JNIEnvTable = {
3523 &FromReflectedMethod,
3524 &FromReflectedField,
3539 &jni_init1, /* &NewGlobalRef, initialize Global_Ref_Table*/
3540 &jni_init2, /* &DeleteGlobalRef,*/
3544 &EnsureLocalCapacity,
3560 &CallBooleanMethodV,
3561 &CallBooleanMethodA,
3587 &CallNonvirtualObjectMethod,
3588 &CallNonvirtualObjectMethodV,
3589 &CallNonvirtualObjectMethodA,
3590 &CallNonvirtualBooleanMethod,
3591 &CallNonvirtualBooleanMethodV,
3592 &CallNonvirtualBooleanMethodA,
3593 &CallNonvirtualByteMethod,
3594 &CallNonvirtualByteMethodV,
3595 &CallNonvirtualByteMethodA,
3596 &CallNonvirtualCharMethod,
3597 &CallNonvirtualCharMethodV,
3598 &CallNonvirtualCharMethodA,
3599 &CallNonvirtualShortMethod,
3600 &CallNonvirtualShortMethodV,
3601 &CallNonvirtualShortMethodA,
3602 &CallNonvirtualIntMethod,
3603 &CallNonvirtualIntMethodV,
3604 &CallNonvirtualIntMethodA,
3605 &CallNonvirtualLongMethod,
3606 &CallNonvirtualLongMethodV,
3607 &CallNonvirtualLongMethodA,
3608 &CallNonvirtualFloatMethod,
3609 &CallNonvirtualFloatMethodV,
3610 &CallNonvirtualFloatMethodA,
3611 &CallNonvirtualDoubleMethod,
3612 &CallNonvirtualDoubleMethodV,
3613 &CallNonvirtualDoubleMethodA,
3614 &CallNonvirtualVoidMethod,
3615 &CallNonvirtualVoidMethodV,
3616 &CallNonvirtualVoidMethodA,
3641 &CallStaticObjectMethod,
3642 &CallStaticObjectMethodV,
3643 &CallStaticObjectMethodA,
3644 &CallStaticBooleanMethod,
3645 &CallStaticBooleanMethodV,
3646 &CallStaticBooleanMethodA,
3647 &CallStaticByteMethod,
3648 &CallStaticByteMethodV,
3649 &CallStaticByteMethodA,
3650 &CallStaticCharMethod,
3651 &CallStaticCharMethodV,
3652 &CallStaticCharMethodA,
3653 &CallStaticShortMethod,
3654 &CallStaticShortMethodV,
3655 &CallStaticShortMethodA,
3656 &CallStaticIntMethod,
3657 &CallStaticIntMethodV,
3658 &CallStaticIntMethodA,
3659 &CallStaticLongMethod,
3660 &CallStaticLongMethodV,
3661 &CallStaticLongMethodA,
3662 &CallStaticFloatMethod,
3663 &CallStaticFloatMethodV,
3664 &CallStaticFloatMethodA,
3665 &CallStaticDoubleMethod,
3666 &CallStaticDoubleMethodV,
3667 &CallStaticDoubleMethodA,
3668 &CallStaticVoidMethod,
3669 &CallStaticVoidMethodV,
3670 &CallStaticVoidMethodA,
3674 &GetStaticObjectField,
3675 &GetStaticBooleanField,
3676 &GetStaticByteField,
3677 &GetStaticCharField,
3678 &GetStaticShortField,
3680 &GetStaticLongField,
3681 &GetStaticFloatField,
3682 &GetStaticDoubleField,
3683 &SetStaticObjectField,
3684 &SetStaticBooleanField,
3685 &SetStaticByteField,
3686 &SetStaticCharField,
3687 &SetStaticShortField,
3689 &SetStaticLongField,
3690 &SetStaticFloatField,
3691 &SetStaticDoubleField,
3696 &ReleaseStringChars,
3699 &GetStringUTFLength,
3701 &ReleaseStringUTFChars,
3706 &GetObjectArrayElement,
3707 &SetObjectArrayElement,
3718 &GetBooleanArrayElements,
3719 &GetByteArrayElements,
3720 &GetCharArrayElements,
3721 &GetShortArrayElements,
3722 &GetIntArrayElements,
3723 &GetLongArrayElements,
3724 &GetFloatArrayElements,
3725 &GetDoubleArrayElements,
3727 &ReleaseBooleanArrayElements,
3728 &ReleaseByteArrayElements,
3729 &ReleaseCharArrayElements,
3730 &ReleaseShortArrayElements,
3731 &ReleaseIntArrayElements,
3732 &ReleaseLongArrayElements,
3733 &ReleaseFloatArrayElements,
3734 &ReleaseDoubleArrayElements,
3736 &GetBooleanArrayRegion,
3737 &GetByteArrayRegion,
3738 &GetCharArrayRegion,
3739 &GetShortArrayRegion,
3741 &GetLongArrayRegion,
3742 &GetFloatArrayRegion,
3743 &GetDoubleArrayRegion,
3744 &SetBooleanArrayRegion,
3745 &SetByteArrayRegion,
3746 &SetCharArrayRegion,
3747 &SetShortArrayRegion,
3749 &SetLongArrayRegion,
3750 &SetFloatArrayRegion,
3751 &SetDoubleArrayRegion,
3761 /* new JNI 1.2 functions */
3764 &GetStringUTFRegion,
3766 &GetPrimitiveArrayCritical,
3767 &ReleasePrimitiveArrayCritical,
3770 &ReleaseStringCritical,
3773 &DeleteWeakGlobalRef,
3777 /* new JNI 1.4 functions */
3779 &NewDirectByteBuffer,
3780 &GetDirectBufferAddress,
3781 &GetDirectBufferCapacity
3785 /* Invocation API Functions ***************************************************/
3787 /* JNI_GetDefaultJavaVMInitArgs ************************************************
3789 Returns a default configuration for the Java VM.
3791 *******************************************************************************/
3793 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
3795 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
3797 /* GNU classpath currently supports JNI 1.2 */
3799 _vm_args->version = JNI_VERSION_1_2;
3805 /* JNI_GetCreatedJavaVMs *******************************************************
3807 Returns all Java VMs that have been created. Pointers to VMs are written in
3808 the buffer vmBuf in the order they are created. At most bufLen number of
3809 entries will be written. The total number of created VMs is returned in
3812 *******************************************************************************/
3814 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
3816 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
3822 /* JNI_CreateJavaVM ************************************************************
3824 Loads and initializes a Java VM. The current thread becomes the main thread.
3825 Sets the env argument to the JNI interface pointer of the main thread.
3827 *******************************************************************************/
3829 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
3831 *p_vm = (JavaVM *) &JNI_JavaVMTable;
3832 *p_env = (JNIEnv *) &JNI_JNIEnvTable;
3838 jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID, jobject obj, java_objectarray *params)
3845 if (methodID == 0) {
3846 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
3850 argcount = get_parametercount(methodID);
3852 /* the method is an instance method the obj has to be an instance of the
3853 class the method belongs to. For static methods the obj parameter
3855 if (!(methodID->flags & ACC_STATIC) && obj &&
3856 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
3857 *exceptionptr = new_exception_message(string_java_lang_IllegalArgumentException,
3858 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
3865 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3866 log_text("Too many arguments. invokeNativeHelper does not support that");
3870 if (((params==0) && (argcount != 0)) || (params && (params->header.size != argcount))) {
3871 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3876 if (((methodID->flags & ACC_STATIC)==0) && (0==obj)) {
3878 new_exception_message(string_java_lang_NullPointerException,
3879 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
3883 if ((methodID->flags & ACC_STATIC) && (obj)) obj = 0;
3886 if ( (methodID->flags & ACC_ABSTRACT) || (methodID->class->flags & ACC_INTERFACE) ) {
3887 methodID=get_virtual(obj,methodID);
3891 blk = MNEW(jni_callblock, /*4 */argcount+2);
3893 retT = fill_callblock_objA(obj, methodID->descriptor, blk, params);
3897 (void) asm_calljavafunction2(methodID,
3899 (argcount + 1) * sizeof(jni_callblock),
3901 retVal = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
3906 intVal = asm_calljavafunction2int(methodID,
3908 (argcount + 1) * sizeof(jni_callblock),
3910 retVal = builtin_new(class_java_lang_Integer);
3913 class_resolvemethod(retVal->vftbl->class,
3922 intVal = asm_calljavafunction2int(methodID,
3924 (argcount + 1) * sizeof(jni_callblock),
3926 retVal = builtin_new(class_java_lang_Byte);
3929 class_resolvemethod(retVal->vftbl->class,
3938 intVal = asm_calljavafunction2int(methodID,
3940 (argcount + 1) * sizeof(jni_callblock),
3942 retVal = builtin_new(class_java_lang_Character);
3945 class_resolvemethod(retVal->vftbl->class,
3954 intVal = asm_calljavafunction2int(methodID,
3956 (argcount + 1) * sizeof(jni_callblock),
3958 retVal = builtin_new(class_java_lang_Short);
3961 class_resolvemethod(retVal->vftbl->class,
3970 intVal = asm_calljavafunction2int(methodID,
3972 (argcount + 1) * sizeof(jni_callblock),
3974 retVal = builtin_new(class_java_lang_Boolean);
3977 class_resolvemethod(retVal->vftbl->class,
3986 longVal = asm_calljavafunction2long(methodID,
3988 (argcount + 1) * sizeof(jni_callblock),
3990 retVal = builtin_new(class_java_lang_Long);
3993 class_resolvemethod(retVal->vftbl->class,
4002 floatVal = asm_calljavafunction2float(methodID,
4004 (argcount + 1) * sizeof(jni_callblock),
4006 retVal = builtin_new(class_java_lang_Float);
4009 class_resolvemethod(retVal->vftbl->class,
4018 doubleVal = asm_calljavafunction2double(methodID,
4020 (argcount + 1) * sizeof(jni_callblock),
4022 retVal = builtin_new(class_java_lang_Double);
4025 class_resolvemethod(retVal->vftbl->class,
4032 case 'L': /* fall through */
4034 retVal = asm_calljavafunction2(methodID,
4036 (argcount + 1) * sizeof(jni_callblock),
4041 /* if this happens the acception has already been set by fill_callblock_objA*/
4042 MFREE(blk, jni_callblock, /*4 */ argcount+2);
4043 return (jobject *) 0;
4046 MFREE(blk, jni_callblock, /* 4 */ argcount+2);
4048 if (*exceptionptr) {
4049 java_objectheader *exceptionToWrap = *exceptionptr;
4051 java_objectheader *ivte;
4053 *exceptionptr = NULL;
4054 ivtec = class_new(utf_new_char("java/lang/reflect/InvocationTargetException"));
4055 ivte = builtin_new(ivtec);
4056 asm_calljavafunction(class_resolvemethod(ivtec,
4057 utf_new_char("<init>"),
4058 utf_new_char("(Ljava/lang/Throwable;)V")),
4064 if (*exceptionptr != NULL)
4065 panic("jni.c: error while creating InvocationTargetException wrapper");
4067 *exceptionptr = ivte;
4070 return (jobject *) retVal;
4077 * These are local overrides for various environment variables in Emacs.
4078 * Please do not remove this and leave it at the end of the file, where
4079 * Emacs will automagically detect them.
4080 * ---------------------------------------------------------------------
4083 * indent-tabs-mode: t