1 /* src/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 2171 2005-03-31 19:23:51Z twisti $
43 #include "mm/memory.h"
44 #include "native/jni.h"
45 #include "native/native.h"
46 #include "native/include/java_lang_Byte.h"
47 #include "native/include/java_lang_Character.h"
48 #include "native/include/java_lang_Short.h"
49 #include "native/include/java_lang_Integer.h"
50 #include "native/include/java_lang_Boolean.h"
51 #include "native/include/java_lang_Long.h"
52 #include "native/include/java_lang_Float.h"
53 #include "native/include/java_lang_Double.h"
54 #include "native/include/java_lang_Throwable.h"
56 #include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
57 #include "native/include/java_lang_VMClass.h"
58 #include "native/include/java_lang_VMClassLoader.h"
60 #if defined(USE_THREADS)
61 # if defined(NATIVE_THREADS)
62 # include "threads/native/threads.h"
64 # include "threads/green/threads.h"
68 #include "toolbox/logging.h"
69 #include "vm/builtin.h"
70 #include "vm/exceptions.h"
71 #include "vm/global.h"
72 #include "vm/loader.h"
73 #include "vm/options.h"
74 #include "vm/statistics.h"
75 #include "vm/stringlocal.h"
76 #include "vm/tables.h"
77 #include "vm/jit/asmpart.h"
78 #include "vm/jit/jit.h"
81 /* XXX TWISTI hack: define it extern so they can be found in this file */
82 extern const struct JNIInvokeInterface JNI_JavaVMTable;
83 extern struct JNINativeInterface JNI_JNIEnvTable;
85 /* pointers to VM and the environment needed by GetJavaVM and GetEnv */
86 static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
87 static void* ptr_env = (void*) &JNI_JNIEnvTable;
90 #define PTR_TO_ITEM(ptr) ((u8)(size_t)(ptr))
92 /* global reference table */
93 static jobject *global_ref_table;
94 static bool initrunning=false;
96 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
97 static jmethodID getmid = NULL;
98 static jmethodID putmid = NULL;
99 static jclass intclass = NULL;
100 static jmethodID intvalue = NULL;
101 static jmethodID newint = NULL;
102 static jclass ihmclass = NULL;
103 static jmethodID removemid = NULL;
106 /********************* accessing instance-fields **********************************/
108 #define setField(obj,typ,var,val) *((typ*) ((long int) obj + (long int) var->offset))=val;
109 #define getField(obj,typ,var) *((typ*) ((long int) obj + (long int) var->offset))
110 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) setField(obj,jdatatype,getFieldID_critical(env,clazz,name,sig),val);
114 u4 get_parametercount(methodinfo *m)
116 utf *descr = m->descriptor; /* method-descriptor */
117 char *utf_ptr = descr->text; /* current position in utf-text */
118 char *desc_end = utf_end(descr); /* points behind utf string */
119 u4 parametercount = 0;
122 utf_nextu2(&utf_ptr);
124 /* determine number of parameters */
125 while (*utf_ptr != ')') {
126 get_type(&utf_ptr, desc_end, true);
130 return parametercount;
135 void fill_callblock(void *obj, utf *descr, jni_callblock blk[], va_list data, char ret)
137 char *utf__ptr = descr->text; /* current position in utf-text */
138 char **utf_ptr = &utf__ptr;
139 char *desc_end = utf_end(descr); /* points behind utf string */
145 log_text("fill_callblock");
152 /* determine number of parameters */
154 blk[0].itemtype = TYPE_ADR;
155 blk[0].item = PTR_TO_ITEM(obj);
159 while (**utf_ptr != ')') {
160 if (*utf_ptr >= desc_end)
161 panic("illegal method descriptor");
163 switch (utf_nextu2(utf_ptr)) {
164 /* primitive types */
169 blk[cnt].itemtype = TYPE_INT;
170 blk[cnt].item = (u8) va_arg(data, int);
174 blk[cnt].itemtype = TYPE_INT;
175 dummy = va_arg(data, u4);
176 /*printf("fill_callblock: pos:%d, value:%d\n",cnt,dummy);*/
177 blk[cnt].item = (u8) dummy;
181 blk[cnt].itemtype = TYPE_LNG;
182 blk[cnt].item = (u8) va_arg(data, jlong);
186 blk[cnt].itemtype = TYPE_FLT;
187 *((jfloat *) (&blk[cnt].item)) = (jfloat) va_arg(data, jdouble);
191 blk[cnt].itemtype = TYPE_DBL;
192 *((jdouble *) (&blk[cnt].item)) = (jdouble) va_arg(data, jdouble);
196 panic ("V not allowed as function parameter");
200 while (utf_nextu2(utf_ptr) != ';')
201 blk[cnt].itemtype = TYPE_ADR;
202 blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
209 /* char *start = *utf_ptr; */
211 while ((ch = utf_nextu2(utf_ptr)) == '[')
213 while (utf_nextu2(utf_ptr) != ';') {}
216 ch = utf_nextu2(utf_ptr);
217 blk[cnt].itemtype = TYPE_ADR;
218 blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
225 /*the standard doesn't say anything about return value checking, but it appears to be usefull*/
226 c = utf_nextu2(utf_ptr);
227 c = utf_nextu2(utf_ptr);
228 /*printf("%c %c\n",ret,c);*/
230 if (!((c == 'L') || (c == '[')))
231 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
233 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
237 /* XXX it could be considered if we should do typechecking here in the future */
238 char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_objectarray* params)
240 char *utf__ptr = descr->text; /* current position in utf-text */
241 char **utf_ptr = &utf__ptr;
242 char *desc_end = utf_end(descr); /* points behind utf string */
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(string_java_lang_IllegalArgumentException);
280 if (param->vftbl->class->name == utf_java_lang_Byte) {
281 blk[cnt].itemtype = TYPE_INT;
282 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
285 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
291 param = params->data[cnts];
293 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
296 if (param->vftbl->class->name == utf_java_lang_Character) {
297 blk[cnt].itemtype = TYPE_INT;
298 blk[cnt].item = (u8) ((java_lang_Character *) param)->value;
301 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
307 param = params->data[cnts];
309 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
312 if (param->vftbl->class->name == utf_java_lang_Short) {
313 blk[cnt].itemtype = TYPE_INT;
314 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
317 if (param->vftbl->class->name == utf_java_lang_Byte) {
318 blk[cnt].itemtype = TYPE_INT;
319 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
322 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
329 param = params->data[cnts];
331 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
334 if (param->vftbl->class->name == utf_java_lang_Boolean) {
335 blk[cnt].itemtype = TYPE_INT;
336 blk[cnt].item = (u8) ((java_lang_Boolean *) param)->value;
339 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
345 /*log_text("fill_callblock_objA: param 'I'");*/
346 param = params->data[cnts];
348 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
351 if (param->vftbl->class->name == utf_java_lang_Integer) {
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_java_lang_Short) {
357 blk[cnt].itemtype = TYPE_INT;
358 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
361 if (param->vftbl->class->name == utf_java_lang_Byte) {
362 blk[cnt].itemtype = TYPE_INT;
363 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
366 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
374 param = params->data[cnts];
376 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
379 if (param->vftbl->class->name == utf_java_lang_Long) {
380 blk[cnt].itemtype = TYPE_LNG;
381 blk[cnt].item = (u8) ((java_lang_Long *) param)->value;
384 if (param->vftbl->class->name == utf_java_lang_Integer) {
385 blk[cnt].itemtype = TYPE_LNG;
386 blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
389 if (param->vftbl->class->name == utf_java_lang_Short) {
390 blk[cnt].itemtype = TYPE_LNG;
391 blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
394 if (param->vftbl->class->name == utf_java_lang_Byte) {
395 blk[cnt].itemtype = TYPE_LNG;
396 blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
398 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
408 param = params->data[cnts];
410 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
414 if (param->vftbl->class->name == utf_java_lang_Float) {
415 blk[cnt].itemtype = TYPE_FLT;
416 *((jfloat *) (&blk[cnt].item)) = (jfloat) ((java_lang_Float *) param)->value;
419 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
425 param = params->data[cnts];
427 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
431 if (param->vftbl->class->name == utf_java_lang_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_java_lang_Float) {
437 blk[cnt].itemtype = TYPE_DBL;
438 *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
441 *exceptionptr = new_exception(string_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, desc_end, utf_ptr, CLASSLOAD_LOAD))) {
460 if (params->data[cnts] != 0) {
461 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
465 blk[cnt].itemtype = TYPE_ADR;
466 blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
472 char *start = (*utf_ptr) - 1;
476 while ((ch = utf_nextu2(utf_ptr)) == '[')
478 while (utf_nextu2(utf_ptr) != ';') {}
481 end = (*utf_ptr) - 1;
482 ch = utf_nextu2(utf_ptr); */
484 if (!builtin_arrayinstanceof(params->data[cnts], class_from_descriptor(start, desc_end, utf_ptr, CLASSLOAD_LOAD)->vftbl)) {
485 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
489 blk[cnt].itemtype = TYPE_ADR;
490 blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
498 c = utf_nextu2(utf_ptr);
499 c = utf_nextu2(utf_ptr);
500 return c; /*return type needed usage of the right lowlevel methods*/
504 jmethodID get_virtual(jobject obj,jmethodID methodID) {
505 if (obj->vftbl->class==methodID->class) return methodID;
506 return class_resolvemethod (obj->vftbl->class, methodID->name, methodID->descriptor);
510 jmethodID get_nonvirtual(jclass clazz,jmethodID methodID) {
511 if (clazz==methodID->class) return methodID;
512 /*class_resolvemethod -> classfindmethod? (JOWENN)*/
513 return class_resolvemethod (clazz, methodID->name, methodID->descriptor);
517 jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
526 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
530 argcount = get_parametercount(methodID);
532 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
533 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
534 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
538 if (obj && !builtin_instanceof(obj, methodID->class)) {
539 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
546 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
547 log_text("Too many arguments. CallObjectMethod does not support that");
552 blk = MNEW(jni_callblock, /*4 */argcount+2);
554 fill_callblock(obj, methodID->descriptor, blk, args, 'O');
555 /* printf("parameter: obj: %p",blk[0].item); */
556 ret = asm_calljavafunction2(methodID,
558 (argcount + 1) * sizeof(jni_callblock),
560 MFREE(blk, jni_callblock, argcount + 1);
561 /* printf("(CallObjectMethodV)-->%p\n",ret); */
568 core function for integer class methods (bool, byte, short, integer)
569 This is basically needed for i386
571 jint callIntegerMethod(jobject obj, jmethodID methodID, char retType, va_list args)
577 /* printf("%p, %c\n",retType,methodID,retType);*/
580 log_text("JNI-Call: CallObjectMethodV");
581 utf_display(methodID->name);
582 utf_display(methodID->descriptor);
583 printf("\nParmaeter count: %d\n",argcount);
584 utf_display(obj->vftbl->class->name);
588 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
592 argcount = get_parametercount(methodID);
594 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
595 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
596 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
600 if (obj && !builtin_instanceof(obj, methodID->class)) {
601 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
607 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
608 log_text("Too many arguments. CallIntegerMethod does not support that");
613 blk = MNEW(jni_callblock, /*4 */ argcount+2);
615 fill_callblock(obj, methodID->descriptor, blk, args, retType);
617 /* printf("parameter: obj: %p",blk[0].item); */
618 ret = asm_calljavafunction2int(methodID,
620 (argcount + 1) * sizeof(jni_callblock),
623 MFREE(blk, jni_callblock, argcount + 1);
624 /* printf("(CallObjectMethodV)-->%p\n",ret); */
630 /*core function for long class functions*/
631 jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
638 log_text("JNI-Call: CallObjectMethodV");
639 utf_display(methodID->name);
640 utf_display(methodID->descriptor);
641 printf("\nParmaeter count: %d\n",argcount);
642 utf_display(obj->vftbl->class->name);
646 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
650 argcount = get_parametercount(methodID);
652 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
653 ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
654 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
658 if (obj && !builtin_instanceof(obj,methodID->class)) {
659 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
665 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
666 log_text("Too many arguments. CallObjectMethod does not support that");
671 blk = MNEW(jni_callblock,/* 4 */argcount+2);
673 fill_callblock(obj, methodID->descriptor, blk, args, 'J');
675 /* printf("parameter: obj: %p",blk[0].item); */
676 ret = asm_calljavafunction2long(methodID,
678 (argcount + 1) * sizeof(jni_callblock),
681 MFREE(blk, jni_callblock, argcount + 1);
682 /* printf("(CallObjectMethodV)-->%p\n",ret); */
688 /*core function for float class methods (float,double)*/
689 jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,char retType)
691 int argcount = get_parametercount(methodID);
696 log_text("JNI-Call: CallObjectMethodV");
697 utf_display(methodID->name);
698 utf_display(methodID->descriptor);
699 printf("\nParmaeter count: %d\n",argcount);
700 utf_display(obj->vftbl->class->name);
706 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
707 log_text("Too many arguments. CallObjectMethod does not support that");
712 blk = MNEW(jni_callblock, /*4 */ argcount+2);
714 fill_callblock(obj, methodID->descriptor, blk, args, retType);
716 /* printf("parameter: obj: %p",blk[0].item); */
717 ret = asm_calljavafunction2double(methodID,
719 (argcount + 1) * sizeof(jni_callblock),
722 MFREE(blk, jni_callblock, argcount + 1);
723 /* printf("(CallObjectMethodV)-->%p\n",ret); */
729 /*************************** function: jclass_findfield ****************************
731 searches for field with specified name and type in a 'classinfo'-structur
732 if no such field is found NULL is returned
734 ************************************************************************************/
736 fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
739 /* printf(" FieldCount: %d\n",c->fieldscount);
740 utf_display(c->name); */
741 for (i = 0; i < c->fieldscount; i++) {
742 /* utf_display(c->fields[i].name);
744 utf_display(c->fields[i].descriptor);
746 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
747 return &(c->fields[i]);
750 if (c->super) return jclass_findfield(c->super,name,desc);
756 /* GetVersion ******************************************************************
758 Returns the major version number in the higher 16 bits and the
759 minor version number in the lower 16 bits.
761 *******************************************************************************/
763 jint GetVersion(JNIEnv *env)
765 /* GNU classpath currently supports JNI 1.2 */
767 return JNI_VERSION_1_2;
771 /* Class Operations ***********************************************************/
773 /* DefineClass *****************************************************************
775 Loads a class from a buffer of raw class data. The buffer
776 containing the raw class data is not referenced by the VM after the
777 DefineClass call returns, and it may be discarded if desired.
779 *******************************************************************************/
781 jclass DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize bufLen)
785 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env,
787 (java_lang_ClassLoader *) loader,
788 javastring_new_char(name),
789 (java_bytearray *) buf,
798 /* FindClass *******************************************************************
800 This function loads a locally-defined class. It searches the
801 directories and zip files specified by the CLASSPATH environment
802 variable for the class with the specified name.
804 *******************************************************************************/
806 jclass FindClass(JNIEnv *env, const char *name)
810 c = class_new(utf_new_char_classname((char *) name));
812 if (!load_class_bootstrap(c) || !link_class(c)) {
818 use_class_as_object(c);
824 /*******************************************************************************
826 converts java.lang.reflect.Method or
827 java.lang.reflect.Constructor object to a method ID
829 *******************************************************************************/
831 jmethodID FromReflectedMethod(JNIEnv* env, jobject method)
833 log_text("JNI-Call: FromReflectedMethod: IMPLEMENT ME!!!");
839 /* GetSuperclass ***************************************************************
841 If clazz represents any class other than the class Object, then
842 this function returns the object that represents the superclass of
843 the class specified by clazz.
845 *******************************************************************************/
847 jclass GetSuperclass(JNIEnv *env, jclass sub)
851 c = ((classinfo *) sub)->super;
856 use_class_as_object(c);
862 /* IsAssignableFrom ************************************************************
864 Determines whether an object of sub can be safely cast to sup.
866 *******************************************************************************/
868 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
870 return Java_java_lang_VMClass_isAssignableFrom(env,
872 (java_lang_Class *) sup,
873 (java_lang_Class *) sub);
877 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
879 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
881 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!!!");
887 /* Throw ***********************************************************************
889 Causes a java.lang.Throwable object to be thrown.
891 *******************************************************************************/
893 jint Throw(JNIEnv *env, jthrowable obj)
895 *exceptionptr = (java_objectheader *) obj;
901 /* ThrowNew ********************************************************************
903 Constructs an exception object from the specified class with the
904 message specified by message and causes that exception to be
907 *******************************************************************************/
909 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
911 java_lang_Throwable *o;
914 s = (java_lang_String *) javastring_new_char(msg);
916 /* instantiate exception object */
918 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
924 *exceptionptr = (java_objectheader *) o;
930 /* ExceptionOccurred ***********************************************************
932 Determines if an exception is being thrown. The exception stays
933 being thrown until either the native code calls ExceptionClear(),
934 or the Java code handles the exception.
936 *******************************************************************************/
938 jthrowable ExceptionOccurred(JNIEnv *env)
940 return (jthrowable) *exceptionptr;
944 /* ExceptionDescribe ***********************************************************
946 Prints an exception and a backtrace of the stack to a system
947 error-reporting channel, such as stderr. This is a convenience
948 routine provided for debugging.
950 *******************************************************************************/
952 void ExceptionDescribe(JNIEnv *env)
954 java_objectheader *e;
960 /* clear exception, because we are calling jit code again */
962 *exceptionptr = NULL;
964 /* get printStackTrace method from exception class */
966 m = class_resolveclassmethod(e->vftbl->class,
973 /* XXX what should we do? */
976 /* print the stacktrace */
978 asm_calljavafunction(m, e, NULL, NULL, NULL);
983 /* ExceptionClear **************************************************************
985 Clears any exception that is currently being thrown. If no
986 exception is currently being thrown, this routine has no effect.
988 *******************************************************************************/
990 void ExceptionClear(JNIEnv *env)
992 *exceptionptr = NULL;
996 /* FatalError ******************************************************************
998 Raises a fatal error and does not expect the VM to recover. This
999 function does not return.
1001 *******************************************************************************/
1003 void FatalError(JNIEnv *env, const char *msg)
1005 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
1009 /******************* creates a new local reference frame **************************/
1011 jint PushLocalFrame(JNIEnv* env, jint capacity)
1013 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
1018 /**************** Pops off the current local reference frame **********************/
1020 jobject PopLocalFrame(JNIEnv* env, jobject result)
1022 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
1028 /* DeleteLocalRef **************************************************************
1030 Deletes the local reference pointed to by localRef.
1032 *******************************************************************************/
1034 void DeleteLocalRef(JNIEnv *env, jobject localRef)
1036 log_text("JNI-Call: DeleteLocalRef: IMPLEMENT ME!");
1040 /* IsSameObject ****************************************************************
1042 Tests whether two references refer to the same Java object.
1044 *******************************************************************************/
1046 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1048 return (ref1 == ref2);
1052 /* NewLocalRef *****************************************************************
1054 Creates a new local reference that refers to the same object as ref.
1056 *******************************************************************************/
1058 jobject NewLocalRef(JNIEnv *env, jobject ref)
1060 log_text("JNI-Call: NewLocalRef: IMPLEMENT ME!");
1065 /***********************************************************************************
1067 Ensures that at least a given number of local references can
1068 be created in the current thread
1070 **********************************************************************************/
1072 jint EnsureLocalCapacity (JNIEnv* env, jint capacity)
1074 return 0; /* return 0 on success */
1078 /* AllocObject *****************************************************************
1080 Allocates a new Java object without invoking any of the
1081 constructors for the object. Returns a reference to the object.
1083 *******************************************************************************/
1085 jobject AllocObject(JNIEnv *env, jclass clazz)
1087 java_objectheader *o;
1089 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1091 new_exception_utfmessage(string_java_lang_InstantiationException,
1096 o = builtin_new(clazz);
1102 /* NewObject *******************************************************************
1104 Constructs a new Java object. The method ID indicates which
1105 constructor method to invoke. This ID must be obtained by calling
1106 GetMethodID() with <init> as the method name and void (V) as the
1109 *******************************************************************************/
1111 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1113 java_objectheader *o;
1115 int argcount=get_parametercount(methodID);
1121 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
1122 log_text("Too many arguments. NewObject does not support that");
1129 o = builtin_new(clazz);
1134 va_start(vaargs, methodID);
1135 for (i = 0; i < argcount; i++) {
1136 args[i] = va_arg(vaargs, void*);
1140 /* call constructor */
1142 asm_calljavafunction(methodID, o, args[0], args[1], args[2]);
1148 /***********************************************************************************
1150 Constructs a new Java object
1151 arguments that are to be passed to the constructor are placed in va_list args
1153 ***********************************************************************************/
1155 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1157 log_text("JNI-Call: NewObjectV");
1163 /***********************************************************************************
1165 Constructs a new Java object
1166 arguments that are to be passed to the constructor are placed in
1167 args array of jvalues
1169 ***********************************************************************************/
1171 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1173 log_text("JNI-Call: NewObjectA");
1179 /* GetObjectClass **************************************************************
1181 Returns the class of an object.
1183 *******************************************************************************/
1185 jclass GetObjectClass(JNIEnv *env, jobject obj)
1187 classinfo *c = obj->vftbl->class;
1189 use_class_as_object(c);
1195 /* IsInstanceOf ****************************************************************
1197 Tests whether an object is an instance of a class.
1199 *******************************************************************************/
1201 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1203 return Java_java_lang_VMClass_isInstance(env,
1205 (java_lang_Class *) clazz,
1206 (java_lang_Object *) obj);
1210 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1212 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1214 log_text("JNI-Call: FromReflectedField");
1220 /**********************************************************************************
1222 converts a method ID to a java.lang.reflect.Method or
1223 java.lang.reflect.Constructor object
1225 **********************************************************************************/
1227 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1229 log_text("JNI-Call: ToReflectedMethod");
1235 /* GetMethodID *****************************************************************
1237 returns the method ID for an instance method
1239 *******************************************************************************/
1241 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1245 m = class_resolvemethod(clazz,
1246 utf_new_char((char *) name),
1247 utf_new_char((char *) sig));
1249 if (!m || (m->flags & ACC_STATIC)) {
1251 new_exception_message(string_java_lang_NoSuchMethodError, name);
1260 /******************** JNI-functions for calling instance methods ******************/
1262 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1267 /* log_text("JNI-Call: CallObjectMethod");*/
1269 va_start(vaargs, methodID);
1270 ret = callObjectMethod(obj, methodID, vaargs);
1277 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1279 return callObjectMethod(obj,methodID,args);
1283 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1285 log_text("JNI-Call: CallObjectMethodA");
1293 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1298 /* log_text("JNI-Call: CallBooleanMethod");*/
1300 va_start(vaargs,methodID);
1301 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',vaargs);
1307 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1309 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',args);
1313 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1315 log_text("JNI-Call: CallBooleanMethodA");
1320 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1325 /* log_text("JNI-Call: CallVyteMethod");*/
1327 va_start(vaargs,methodID);
1328 ret = callIntegerMethod(obj,get_virtual(obj,methodID),'B',vaargs);
1334 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1336 /* log_text("JNI-Call: CallByteMethodV");*/
1337 return callIntegerMethod(obj,methodID,'B',args);
1341 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1343 log_text("JNI-Call: CallByteMethodA");
1349 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1354 /* log_text("JNI-Call: CallCharMethod");*/
1356 va_start(vaargs,methodID);
1357 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'C', vaargs);
1364 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1366 /* log_text("JNI-Call: CallCharMethodV");*/
1367 return callIntegerMethod(obj,get_virtual(obj,methodID),'C',args);
1371 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1373 log_text("JNI-Call: CallCharMethodA");
1379 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1384 /* log_text("JNI-Call: CallShortMethod");*/
1386 va_start(vaargs, methodID);
1387 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'S', vaargs);
1394 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1396 return callIntegerMethod(obj, get_virtual(obj, methodID), 'S', args);
1400 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1402 log_text("JNI-Call: CallShortMethodA");
1409 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1414 va_start(vaargs,methodID);
1415 ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'I', vaargs);
1422 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1424 return callIntegerMethod(obj, get_virtual(obj, methodID), 'I', args);
1428 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1430 log_text("JNI-Call: CallIntMethodA");
1437 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1442 va_start(vaargs,methodID);
1443 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1450 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1452 return callLongMethod(obj,get_virtual(obj, methodID),args);
1456 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1458 log_text("JNI-Call: CallLongMethodA");
1465 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1470 /* log_text("JNI-Call: CallFloatMethod");*/
1472 va_start(vaargs,methodID);
1473 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'F');
1480 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1482 log_text("JNI-Call: CallFloatMethodV");
1483 return callFloatMethod(obj, get_virtual(obj, methodID), args, 'F');
1487 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1489 log_text("JNI-Call: CallFloatMethodA");
1496 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1501 /* log_text("JNI-Call: CallDoubleMethod");*/
1503 va_start(vaargs,methodID);
1504 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'D');
1511 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1513 log_text("JNI-Call: CallDoubleMethodV");
1514 return callFloatMethod(obj, get_virtual(obj, methodID), args, 'D');
1518 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1520 log_text("JNI-Call: CallDoubleMethodA");
1526 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1530 va_start(vaargs,methodID);
1531 (void) callIntegerMethod(obj, get_virtual(obj, methodID), 'V', vaargs);
1536 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1538 log_text("JNI-Call: CallVoidMethodV");
1539 (void)callIntegerMethod(obj,get_virtual(obj,methodID),'V',args);
1543 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1545 log_text("JNI-Call: CallVoidMethodA");
1550 jobject CallNonvirtualObjectMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1552 log_text("JNI-Call: CallNonvirtualObjectMethod");
1558 jobject CallNonvirtualObjectMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1560 log_text("JNI-Call: CallNonvirtualObjectMethodV");
1566 jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1568 log_text("JNI-Call: CallNonvirtualObjectMethodA");
1575 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1580 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1582 va_start(vaargs,methodID);
1583 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',vaargs);
1590 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1592 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1593 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',args);
1597 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1599 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1606 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1611 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1613 va_start(vaargs,methodID);
1614 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',vaargs);
1620 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1622 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1623 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',args);
1628 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1630 log_text("JNI-Call: CallNonvirtualByteMethodA");
1637 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1642 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1644 va_start(vaargs,methodID);
1645 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',vaargs);
1651 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1653 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1654 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',args);
1658 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1660 log_text("JNI-Call: CallNonvirtualCharMethodA");
1667 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1672 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1674 va_start(vaargs,methodID);
1675 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',vaargs);
1681 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1683 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1684 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',args);
1688 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1690 log_text("JNI-Call: CallNonvirtualShortMethodA");
1697 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1703 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1705 va_start(vaargs,methodID);
1706 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',vaargs);
1712 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1714 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1715 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',args);
1719 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1721 log_text("JNI-Call: CallNonvirtualIntMethodA");
1728 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1730 log_text("JNI-Call: CallNonvirtualLongMethod");
1736 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1738 log_text("JNI-Call: CallNonvirtualLongMethodV");
1744 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1746 log_text("JNI-Call: CallNonvirtualLongMethodA");
1753 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1758 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1761 va_start(vaargs,methodID);
1762 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'F');
1769 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1771 log_text("JNI-Call: CallNonvirtualFloatMethodV");
1772 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'F');
1776 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1778 log_text("JNI-Call: CallNonvirtualFloatMethodA");
1785 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1789 log_text("JNI-Call: CallNonvirtualDoubleMethod");
1791 va_start(vaargs,methodID);
1792 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'D');
1799 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1801 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
1802 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'D');
1806 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1808 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
1815 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1819 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
1821 va_start(vaargs,methodID);
1822 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',vaargs);
1828 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1830 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
1832 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',args);
1837 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1839 log_text("JNI-Call: CallNonvirtualVoidMethodA");
1842 /************************* JNI-functions for accessing fields ************************/
1844 jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
1848 /* log_text("========================= searching for:");
1851 f = jclass_findfield(clazz,
1852 utf_new_char ((char*) name),
1853 utf_new_char ((char*) sig)
1857 /*utf_display(clazz->name);
1860 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
1865 /*************************** retrieve fieldid, abort on error ************************/
1867 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
1869 jfieldID id = GetFieldID(env, clazz, name, sig);
1873 utf_display(clazz->name);
1874 log_text("\nfield:");
1879 panic("setfield_critical failed");
1884 jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
1887 jobject dbg,dretval,*dpretval;
1888 long int dli1, dli2, dli3;
1890 printf("GetObjectField(1): thread: %s obj: %p name: %s desc: %s \n",GetStringUTFChars(env,
1891 ((threadobject *) THREADOBJECT)->o
1893 ,obj,((fieldinfo*)fieldID)->name->text,(fieldID->descriptor)->text);
1895 dbg = getField(obj,jobject,fieldID);
1896 dli1 = (long int) obj;
1897 dli2 = (long int) fieldID->offset;
1899 dpretval = (jobject*) dli3;
1900 dretval = *dpretval;
1905 tmp = FindClass(env, "java/lang/Object");
1906 mid = GetMethodID(env,tmp,"toString","()Ljava/lang/String;");
1907 jstr = CallObjectMethod(env,dbg,mid);*/
1909 /* printf("GetObjectField(2): retval %p (obj: %#lx + offset: %#lx = %#lx (jobject*) %p (jobject) %p\n"
1910 ,dbg, dli1, dli2, dli3,dpretval, dretval);*/
1915 return getField(obj,jobject,fieldID);
1918 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
1920 return getField(obj,jboolean,fieldID);
1924 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
1926 return getField(obj,jbyte,fieldID);
1930 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
1932 return getField(obj,jchar,fieldID);
1936 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
1938 return getField(obj,jshort,fieldID);
1942 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
1944 return getField(obj,jint,fieldID);
1948 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
1950 return getField(obj,jlong,fieldID);
1954 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
1956 return getField(obj,jfloat,fieldID);
1960 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
1962 return getField(obj,jdouble,fieldID);
1965 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
1967 setField(obj,jobject,fieldID,val);
1971 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
1973 setField(obj,jboolean,fieldID,val);
1977 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
1979 setField(obj,jbyte,fieldID,val);
1983 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
1985 setField(obj,jchar,fieldID,val);
1989 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
1991 setField(obj,jshort,fieldID,val);
1995 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
1997 setField(obj,jint,fieldID,val);
2001 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
2003 setField(obj,jlong,fieldID,val);
2007 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
2009 setField(obj,jfloat,fieldID,val);
2013 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
2015 setField(obj,jdouble,fieldID,val);
2019 /**************** JNI-functions for calling static methods **********************/
2021 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2025 m = class_resolvemethod(clazz,
2026 utf_new_char((char *) name),
2027 utf_new_char((char *) sig));
2029 if (!m || !(m->flags & ACC_STATIC)) {
2031 new_exception_message(string_java_lang_NoSuchMethodError, name);
2040 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2045 /* log_text("JNI-Call: CallStaticObjectMethod");*/
2047 va_start(vaargs, methodID);
2048 ret = callObjectMethod(0, methodID, vaargs);
2055 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2057 /* log_text("JNI-Call: CallStaticObjectMethodV"); */
2059 return callObjectMethod(0,methodID,args);
2063 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2065 log_text("JNI-Call: CallStaticObjectMethodA");
2071 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2076 va_start(vaargs, methodID);
2077 ret = (jboolean) callIntegerMethod(0, methodID, 'Z', vaargs);
2084 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2086 return (jboolean) callIntegerMethod(0, methodID, 'Z', args);
2090 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2092 log_text("JNI-Call: CallStaticBooleanMethodA");
2098 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2103 /* log_text("JNI-Call: CallStaticByteMethod");*/
2105 va_start(vaargs, methodID);
2106 ret = (jbyte) callIntegerMethod(0, methodID, 'B', vaargs);
2113 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2115 return (jbyte) callIntegerMethod(0, methodID, 'B', args);
2119 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2121 log_text("JNI-Call: CallStaticByteMethodA");
2127 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2132 /* log_text("JNI-Call: CallStaticByteMethod");*/
2134 va_start(vaargs, methodID);
2135 ret = (jchar) callIntegerMethod(0, methodID, 'C', vaargs);
2142 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2144 return (jchar) callIntegerMethod(0, methodID, 'C', args);
2148 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2150 log_text("JNI-Call: CallStaticCharMethodA");
2157 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2162 /* log_text("JNI-Call: CallStaticByteMethod");*/
2164 va_start(vaargs, methodID);
2165 ret = (jshort) callIntegerMethod(0, methodID, 'S', vaargs);
2172 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2174 /*log_text("JNI-Call: CallStaticShortMethodV");*/
2175 return (jshort) callIntegerMethod(0, methodID, 'S', args);
2179 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2181 log_text("JNI-Call: CallStaticShortMethodA");
2188 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2193 /* log_text("JNI-Call: CallStaticIntMethod");*/
2195 va_start(vaargs, methodID);
2196 ret = callIntegerMethod(0, methodID, 'I', vaargs);
2203 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2205 log_text("JNI-Call: CallStaticIntMethodV");
2207 return callIntegerMethod(0, methodID, 'I', args);
2211 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2213 log_text("JNI-Call: CallStaticIntMethodA");
2220 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2225 /* log_text("JNI-Call: CallStaticLongMethod");*/
2227 va_start(vaargs, methodID);
2228 ret = callLongMethod(0, methodID, vaargs);
2235 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2237 log_text("JNI-Call: CallStaticLongMethodV");
2239 return callLongMethod(0,methodID,args);
2243 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2245 log_text("JNI-Call: CallStaticLongMethodA");
2252 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2257 /* log_text("JNI-Call: CallStaticLongMethod");*/
2259 va_start(vaargs, methodID);
2260 ret = callFloatMethod(0, methodID, vaargs, 'F');
2267 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2270 return callFloatMethod(0, methodID, args, 'F');
2275 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2277 log_text("JNI-Call: CallStaticFloatMethodA");
2284 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2289 /* log_text("JNI-Call: CallStaticDoubleMethod");*/
2291 va_start(vaargs,methodID);
2292 ret = callFloatMethod(0, methodID, vaargs, 'D');
2299 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2301 log_text("JNI-Call: CallStaticDoubleMethodV");
2303 return callFloatMethod(0, methodID, args, 'D');
2307 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2309 log_text("JNI-Call: CallStaticDoubleMethodA");
2315 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2319 va_start(vaargs, methodID);
2320 (void) callIntegerMethod(0, methodID, 'V', vaargs);
2325 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2327 log_text("JNI-Call: CallStaticVoidMethodV");
2328 (void)callIntegerMethod(0, methodID, 'V', args);
2332 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2334 log_text("JNI-Call: CallStaticVoidMethodA");
2338 /****************** JNI-functions for accessing static fields ********************/
2340 jfieldID GetStaticFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
2344 f = jclass_findfield(clazz,
2345 utf_new_char ((char*) name),
2346 utf_new_char ((char*) sig)
2349 if (!f) *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2355 jobject GetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2358 return fieldID->value.a;
2362 jboolean GetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2365 return fieldID->value.i;
2369 jbyte GetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2372 return fieldID->value.i;
2376 jchar GetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2379 return fieldID->value.i;
2383 jshort GetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2386 return fieldID->value.i;
2390 jint GetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2393 return fieldID->value.i;
2397 jlong GetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2400 return fieldID->value.l;
2404 jfloat GetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2407 return fieldID->value.f;
2411 jdouble GetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2414 return fieldID->value.d;
2419 void SetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2422 fieldID->value.a = value;
2426 void SetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2429 fieldID->value.i = value;
2433 void SetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2436 fieldID->value.i = value;
2440 void SetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2443 fieldID->value.i = value;
2447 void SetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2450 fieldID->value.i = value;
2454 void SetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2457 fieldID->value.i = value;
2461 void SetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2464 fieldID->value.l = value;
2468 void SetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2471 fieldID->value.f = value;
2475 void SetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2478 fieldID->value.d = value;
2482 /***** create new java.lang.String object from an array of Unicode characters ****/
2484 jstring NewString (JNIEnv *env, const jchar *buf, jsize len)
2487 java_lang_String *s;
2490 s = (java_lang_String*) builtin_new (class_java_lang_String);
2491 a = builtin_newarray_char (len);
2493 /* javastring or characterarray could not be created */
2494 if ( (!a) || (!s) ) return NULL;
2497 for (i=0; i<len; i++) a->data[i] = buf[i];
2506 static char emptyString[]="";
2507 static jchar emptyStringJ[]={0,0};
2509 /******************* returns the length of a Java string ***************************/
2511 jsize GetStringLength (JNIEnv *env, jstring str)
2513 return ((java_lang_String*) str)->count;
2517 /******************** convertes javastring to u2-array ****************************/
2519 u2 *javastring_tou2 (jstring so)
2521 java_lang_String *s = (java_lang_String*) so;
2526 if (!s) return NULL;
2529 if (!a) return NULL;
2531 /* allocate memory */
2532 stringbuffer = MNEW( u2 , s->count + 1 );
2535 for (i=0; i<s->count; i++) stringbuffer[i] = a->data[s->offset+i];
2537 /* terminate string */
2538 stringbuffer[i] = '\0';
2540 return stringbuffer;
2543 /********* returns a pointer to an array of Unicode characters of the string *******/
2545 const jchar *GetStringChars (JNIEnv *env, jstring str, jboolean *isCopy)
2547 jchar *jc=javastring_tou2(str);
2550 if (isCopy) *isCopy=JNI_TRUE;
2553 if (isCopy) *isCopy=JNI_TRUE;
2554 return emptyStringJ;
2557 /**************** native code no longer needs access to chars **********************/
2559 void ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars)
2561 if (chars==emptyStringJ) return;
2562 MFREE(((jchar*) chars),jchar,((java_lang_String*) str)->count+1);
2566 /* NewStringUTF ****************************************************************
2568 Constructs a new java.lang.String object from an array of UTF-8 characters.
2570 *******************************************************************************/
2572 jstring NewStringUTF(JNIEnv *env, const char *bytes)
2574 return (jstring) javastring_new(utf_new_char(bytes));
2578 /****************** returns the utf8 length in bytes of a string *******************/
2580 jsize GetStringUTFLength (JNIEnv *env, jstring string)
2582 java_lang_String *s = (java_lang_String*) string;
2584 return (jsize) u2_utflength(s->value->data, s->count);
2588 /************ converts a Javastring to an array of UTF-8 characters ****************/
2590 const char* GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
2594 u = javastring_toutf((java_lang_String *) string, false);
2597 *isCopy = JNI_FALSE;
2607 /***************** native code no longer needs access to utf ***********************/
2609 void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
2611 /*we don't release utf chars right now, perhaps that should be done later. Since there is always one reference
2612 the garbage collector will never get them*/
2614 log_text("JNI-Call: ReleaseStringUTFChars");
2615 utf_display(utf_new_char(chars));
2619 /************************** array operations ***************************************/
2621 jsize GetArrayLength(JNIEnv *env, jarray array)
2627 jobjectArray NewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init)
2629 java_objectarray *j;
2632 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2636 j = builtin_anewarray(len, clazz);
2642 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
2646 if (index < array->header.size)
2647 j = array->data[index];
2649 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2655 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
2657 if (index >= array->header.size)
2658 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2661 /* check if the class of value is a subclass of the element class of the array */
2662 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
2663 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
2666 array->data[index] = val;
2672 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
2674 java_booleanarray *j;
2677 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2681 j = builtin_newarray_boolean(len);
2687 jbyteArray NewByteArray(JNIEnv *env, jsize len)
2692 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2696 j = builtin_newarray_byte(len);
2702 jcharArray NewCharArray(JNIEnv *env, jsize len)
2707 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2711 j = builtin_newarray_char(len);
2717 jshortArray NewShortArray(JNIEnv *env, jsize len)
2722 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2726 j = builtin_newarray_short(len);
2732 jintArray NewIntArray(JNIEnv *env, jsize len)
2737 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2741 j = builtin_newarray_int(len);
2747 jlongArray NewLongArray(JNIEnv *env, jsize len)
2752 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2756 j = builtin_newarray_long(len);
2762 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
2767 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2771 j = builtin_newarray_float(len);
2777 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
2779 java_doublearray *j;
2782 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2786 j = builtin_newarray_double(len);
2792 jboolean * GetBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *isCopy)
2794 if (isCopy) *isCopy = JNI_FALSE;
2799 jbyte * GetByteArrayElements (JNIEnv *env, jbyteArray array, jboolean *isCopy)
2801 if (isCopy) *isCopy = JNI_FALSE;
2806 jchar * GetCharArrayElements (JNIEnv *env, jcharArray array, jboolean *isCopy)
2808 if (isCopy) *isCopy = JNI_FALSE;
2813 jshort * GetShortArrayElements (JNIEnv *env, jshortArray array, jboolean *isCopy)
2815 if (isCopy) *isCopy = JNI_FALSE;
2820 jint * GetIntArrayElements (JNIEnv *env, jintArray array, jboolean *isCopy)
2822 if (isCopy) *isCopy = JNI_FALSE;
2827 jlong * GetLongArrayElements (JNIEnv *env, jlongArray array, jboolean *isCopy)
2829 if (isCopy) *isCopy = JNI_FALSE;
2834 jfloat * GetFloatArrayElements (JNIEnv *env, jfloatArray array, jboolean *isCopy)
2836 if (isCopy) *isCopy = JNI_FALSE;
2841 jdouble * GetDoubleArrayElements (JNIEnv *env, jdoubleArray array, jboolean *isCopy)
2843 if (isCopy) *isCopy = JNI_FALSE;
2849 void ReleaseBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode)
2855 void ReleaseByteArrayElements (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode)
2861 void ReleaseCharArrayElements (JNIEnv *env, jcharArray array, jchar *elems, jint mode)
2867 void ReleaseShortArrayElements (JNIEnv *env, jshortArray array, jshort *elems, jint mode)
2873 void ReleaseIntArrayElements (JNIEnv *env, jintArray array, jint *elems, jint mode)
2879 void ReleaseLongArrayElements (JNIEnv *env, jlongArray array, jlong *elems, jint mode)
2885 void ReleaseFloatArrayElements (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode)
2891 void ReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode)
2897 void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2899 if (start < 0 || len < 0 || start + len > array->header.size)
2900 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2903 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2907 void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
2909 if (start < 0 || len < 0 || start + len > array->header.size)
2910 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2913 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2917 void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
2919 if (start < 0 || len < 0 || start + len > array->header.size)
2920 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2923 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2927 void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
2929 if (start < 0 || len < 0 || start + len > array->header.size)
2930 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2933 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2937 void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
2939 if (start < 0 || len < 0 || start + len > array->header.size)
2940 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2943 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2947 void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
2949 if (start < 0 || len < 0 || start + len > array->header.size)
2950 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2953 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2957 void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
2959 if (start < 0 || len < 0 || start + len > array->header.size)
2960 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2963 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2967 void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
2969 if (start < 0 || len < 0 || start+len>array->header.size)
2970 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2973 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2977 void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2979 if (start < 0 || len < 0 || start + len > array->header.size)
2980 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2983 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2987 void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
2989 if (start < 0 || len < 0 || start + len > array->header.size)
2990 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2993 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2997 void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
2999 if (start < 0 || len < 0 || start + len > array->header.size)
3000 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3003 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3008 void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
3010 if (start < 0 || len < 0 || start + len > array->header.size)
3011 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3014 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3018 void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
3020 if (start < 0 || len < 0 || start + len > array->header.size)
3021 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3024 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3029 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
3031 if (start < 0 || len < 0 || start + len > array->header.size)
3032 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3035 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3040 void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
3042 if (start < 0 || len < 0 || start + len > array->header.size)
3043 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3046 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3051 void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
3053 if (start < 0 || len < 0 || start + len > array->header.size)
3054 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3057 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
3061 jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
3063 log_text("JNI-Call: RegisterNatives");
3068 jint UnregisterNatives (JNIEnv* env, jclass clazz)
3070 log_text("JNI-Call: UnregisterNatives");
3075 /* Monitor Operations *********************************************************/
3077 /* MonitorEnter ****************************************************************
3079 Enters the monitor associated with the underlying Java object
3082 *******************************************************************************/
3084 jint MonitorEnter(JNIEnv *env, jobject obj)
3087 *exceptionptr = new_nullpointerexception();
3091 #if defined(USE_THREADS)
3092 builtin_monitorenter(obj);
3099 /* MonitorExit *****************************************************************
3101 The current thread must be the owner of the monitor associated with
3102 the underlying Java object referred to by obj. The thread
3103 decrements the counter indicating the number of times it has
3104 entered this monitor. If the value of the counter becomes zero, the
3105 current thread releases the monitor.
3107 *******************************************************************************/
3109 jint MonitorExit(JNIEnv *env, jobject obj)
3112 *exceptionptr = new_nullpointerexception();
3116 #if defined(USE_THREADS)
3117 builtin_monitorexit(obj);
3124 /* JavaVM Interface ***********************************************************/
3126 /* GetJavaVM *******************************************************************
3128 Returns the Java VM interface (used in the Invocation API)
3129 associated with the current thread. The result is placed at the
3130 location pointed to by the second argument, vm.
3132 *******************************************************************************/
3134 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
3142 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3144 log_text("JNI-Call: GetStringRegion");
3148 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3150 log_text("JNI-Call: GetStringUTFRegion");
3154 /************** obtain direct pointer to array elements ***********************/
3156 void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
3158 java_objectheader *s = (java_objectheader*) array;
3159 arraydescriptor *desc = s->vftbl->arraydesc;
3161 if (!desc) return NULL;
3163 return ((u1*)s) + desc->dataoffset;
3167 void ReleasePrimitiveArrayCritical (JNIEnv* env, jarray array, void *carray, jint mode)
3169 log_text("JNI-Call: ReleasePrimitiveArrayCritical");
3174 /**** returns a pointer to an array of Unicode characters of the string *******/
3176 const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
3178 log_text("JNI-Call: GetStringCritical");
3180 return GetStringChars(env,string,isCopy);
3183 /*********** native code no longer needs access to chars **********************/
3185 void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
3187 log_text("JNI-Call: ReleaseStringCritical");
3189 ReleaseStringChars(env,string,cstring);
3193 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3195 log_text("JNI-Call: NewWeakGlobalRef");
3201 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
3203 log_text("JNI-Call: DeleteWeakGlobalRef");
3209 /** Creates a new global reference to the object referred to by the obj argument **/
3211 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
3217 MonitorEnter(env, *global_ref_table);
3219 refcount = CallObjectMethod(env, *global_ref_table, getmid, lobj);
3220 val = (refcount == NULL) ? 0 : CallIntMethod(env, refcount, intvalue);
3221 newval = NewObject(env, intclass, newint, val + 1);
3223 if (newval != NULL) {
3224 CallObjectMethod(env, *global_ref_table, putmid, lobj, newval);
3225 MonitorExit(env, *global_ref_table);
3229 log_text("JNI-NewGlobalRef: unable to create new java.lang.Integer");
3230 MonitorExit(env, *global_ref_table);
3235 /************* Deletes the global reference pointed to by globalRef **************/
3237 void DeleteGlobalRef(JNIEnv* env, jobject gref)
3242 MonitorEnter(env, *global_ref_table);
3243 refcount = CallObjectMethod(env, *global_ref_table, getmid, gref);
3245 if (refcount == NULL) {
3246 log_text("JNI-DeleteGlobalRef: unable to find global reference");
3250 val = CallIntMethod(env, refcount, intvalue);
3254 CallObjectMethod(env, *global_ref_table, removemid,refcount);
3257 jobject newval = NewObject(env, intclass, newint, val);
3259 if (newval != NULL) {
3260 CallObjectMethod(env,*global_ref_table, putmid,newval);
3263 log_text("JNI-DeleteGlobalRef: unable to create new java.lang.Integer");
3267 MonitorExit(env,*global_ref_table);
3271 /* ExceptionCheck **************************************************************
3273 Returns JNI_TRUE when there is a pending exception; otherwise,
3276 *******************************************************************************/
3278 jboolean ExceptionCheck(JNIEnv *env)
3280 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
3284 /* New JNI 1.4 functions ******************************************************/
3286 /* NewDirectByteBuffer *********************************************************
3288 Allocates and returns a direct java.nio.ByteBuffer referring to the block of
3289 memory starting at the memory address address and extending capacity bytes.
3291 *******************************************************************************/
3293 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3295 log_text("NewDirectByteBuffer: IMPLEMENT ME!");
3301 /* GetDirectBufferAddress ******************************************************
3303 Fetches and returns the starting address of the memory region referenced by
3304 the given direct java.nio.Buffer.
3306 *******************************************************************************/
3308 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
3310 log_text("GetDirectBufferAddress: IMPLEMENT ME!");
3316 /* GetDirectBufferCapacity *****************************************************
3318 Fetches and returns the capacity in bytes of the memory region referenced by
3319 the given direct java.nio.Buffer.
3321 *******************************************************************************/
3323 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3325 log_text("GetDirectBufferCapacity: IMPLEMENT ME!");
3331 jint DestroyJavaVM(JavaVM *vm)
3333 log_text("DestroyJavaVM called");
3339 jint AttachCurrentThread(JavaVM *vm, void **par1, void *par2)
3341 log_text("AttachCurrentThread called");
3347 jint DetachCurrentThread(JavaVM *vm)
3349 log_text("DetachCurrentThread called");
3355 jint GetEnv(JavaVM *vm, void **env, jint version)
3357 if ((version != JNI_VERSION_1_1) && (version != JNI_VERSION_1_2) &&
3358 (version != JNI_VERSION_1_4)) {
3360 return JNI_EVERSION;
3364 TODO: If the current thread is not attached to the VM...
3367 return JNI_EDETACHED;
3377 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
3379 log_text("AttachCurrentThreadAsDaemon called");
3384 /************* JNI Initialization ****************************************************/
3386 jobject jni_init1(JNIEnv* env, jobject lobj) {
3387 #if defined(USE_THREADS)
3388 while (initrunning) {yieldThread();} /* wait until init is done */
3390 if (global_ref_table == NULL) {
3393 #if defined(USE_THREADS)
3395 /* wait until jni_init is done */
3396 MonitorEnter(env, *global_ref_table) ;
3397 MonitorExit(env, *global_ref_table);
3400 return NewGlobalRef(env, lobj);
3402 void jni_init2(JNIEnv* env, jobject gref) {
3403 log_text("DeleteGlobalref called before NewGlobalref");
3404 #if defined(USE_THREADS)
3405 while (initrunning) {yieldThread();} /* wait until init is done */
3407 if (global_ref_table == NULL) {
3410 #if defined(USE_THREADS)
3412 /* wait until jni_init is done */
3413 MonitorEnter(env, *global_ref_table) ;
3414 MonitorExit(env, *global_ref_table);
3417 DeleteGlobalRef(env, gref);
3424 log_text("JNI-Init: initialize global_ref_table");
3425 /* initalize global reference table */
3426 ihmclass = FindClass(NULL, "java/util/IdentityHashMap");
3428 if (ihmclass == NULL) {
3429 log_text("JNI-Init: unable to find java.util.IdentityHashMap");
3432 mid = GetMethodID(NULL, ihmclass, "<init>","()V");
3434 log_text("JNI-Init: unable to find constructor in java.util.IdentityHashMap");
3437 global_ref_table = (jobject*)heap_allocate(sizeof(jobject),true,NULL);
3439 *global_ref_table = NewObject(NULL,ihmclass,mid);
3441 if (*global_ref_table == NULL) {
3442 log_text("JNI-Init: unable to create new global_ref_table");
3445 initrunning = false;
3447 getmid = GetMethodID(NULL, ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3449 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3452 getmid = GetMethodID(NULL ,ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3453 if (getmid == NULL) {
3454 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3457 putmid = GetMethodID(NULL, ihmclass, "put","(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
3458 if (putmid == NULL) {
3459 log_text("JNI-Init: unable to find method \"put\" in java.util.IdentityHashMap");
3462 intclass = FindClass(NULL, "java/lang/Integer");
3463 if (intclass == NULL) {
3464 log_text("JNI-Init: unable to find java.lang.Integer");
3467 newint = GetMethodID(NULL, intclass, "<init>","(I)V");
3468 if (newint == NULL) {
3469 log_text("JNI-Init: unable to find constructor in java.lang.Integer");
3472 intvalue = GetMethodID(NULL, intclass, "intValue","()I");
3473 if (intvalue == NULL) {
3474 log_text("JNI-Init: unable to find method \"intValue\" in java.lang.Integer");
3477 removemid = GetMethodID(NULL, ihmclass, "remove","(Ljava/lang/Object;)Ljava/lang/Object;");
3478 if (removemid == NULL) {
3479 log_text("JNI-DeleteGlobalRef: unable to find method \"remove\" in java.lang.Object");
3482 /* set NewGlobalRef, DeleteGlobalRef envTable entry to real implementation */
3484 JNI_JNIEnvTable.NewGlobalRef = &NewGlobalRef;
3485 JNI_JNIEnvTable.DeleteGlobalRef = &DeleteGlobalRef;
3489 /* JNI invocation table *******************************************************/
3491 const struct JNIInvokeInterface JNI_JavaVMTable = {
3497 AttachCurrentThread,
3498 DetachCurrentThread,
3500 AttachCurrentThreadAsDaemon
3504 /* JNI function table *********************************************************/
3506 struct JNINativeInterface JNI_JNIEnvTable = {
3515 &FromReflectedMethod,
3516 &FromReflectedField,
3531 &jni_init1, /* &NewGlobalRef, initialize Global_Ref_Table*/
3532 &jni_init2, /* &DeleteGlobalRef,*/
3536 &EnsureLocalCapacity,
3552 &CallBooleanMethodV,
3553 &CallBooleanMethodA,
3579 &CallNonvirtualObjectMethod,
3580 &CallNonvirtualObjectMethodV,
3581 &CallNonvirtualObjectMethodA,
3582 &CallNonvirtualBooleanMethod,
3583 &CallNonvirtualBooleanMethodV,
3584 &CallNonvirtualBooleanMethodA,
3585 &CallNonvirtualByteMethod,
3586 &CallNonvirtualByteMethodV,
3587 &CallNonvirtualByteMethodA,
3588 &CallNonvirtualCharMethod,
3589 &CallNonvirtualCharMethodV,
3590 &CallNonvirtualCharMethodA,
3591 &CallNonvirtualShortMethod,
3592 &CallNonvirtualShortMethodV,
3593 &CallNonvirtualShortMethodA,
3594 &CallNonvirtualIntMethod,
3595 &CallNonvirtualIntMethodV,
3596 &CallNonvirtualIntMethodA,
3597 &CallNonvirtualLongMethod,
3598 &CallNonvirtualLongMethodV,
3599 &CallNonvirtualLongMethodA,
3600 &CallNonvirtualFloatMethod,
3601 &CallNonvirtualFloatMethodV,
3602 &CallNonvirtualFloatMethodA,
3603 &CallNonvirtualDoubleMethod,
3604 &CallNonvirtualDoubleMethodV,
3605 &CallNonvirtualDoubleMethodA,
3606 &CallNonvirtualVoidMethod,
3607 &CallNonvirtualVoidMethodV,
3608 &CallNonvirtualVoidMethodA,
3633 &CallStaticObjectMethod,
3634 &CallStaticObjectMethodV,
3635 &CallStaticObjectMethodA,
3636 &CallStaticBooleanMethod,
3637 &CallStaticBooleanMethodV,
3638 &CallStaticBooleanMethodA,
3639 &CallStaticByteMethod,
3640 &CallStaticByteMethodV,
3641 &CallStaticByteMethodA,
3642 &CallStaticCharMethod,
3643 &CallStaticCharMethodV,
3644 &CallStaticCharMethodA,
3645 &CallStaticShortMethod,
3646 &CallStaticShortMethodV,
3647 &CallStaticShortMethodA,
3648 &CallStaticIntMethod,
3649 &CallStaticIntMethodV,
3650 &CallStaticIntMethodA,
3651 &CallStaticLongMethod,
3652 &CallStaticLongMethodV,
3653 &CallStaticLongMethodA,
3654 &CallStaticFloatMethod,
3655 &CallStaticFloatMethodV,
3656 &CallStaticFloatMethodA,
3657 &CallStaticDoubleMethod,
3658 &CallStaticDoubleMethodV,
3659 &CallStaticDoubleMethodA,
3660 &CallStaticVoidMethod,
3661 &CallStaticVoidMethodV,
3662 &CallStaticVoidMethodA,
3666 &GetStaticObjectField,
3667 &GetStaticBooleanField,
3668 &GetStaticByteField,
3669 &GetStaticCharField,
3670 &GetStaticShortField,
3672 &GetStaticLongField,
3673 &GetStaticFloatField,
3674 &GetStaticDoubleField,
3675 &SetStaticObjectField,
3676 &SetStaticBooleanField,
3677 &SetStaticByteField,
3678 &SetStaticCharField,
3679 &SetStaticShortField,
3681 &SetStaticLongField,
3682 &SetStaticFloatField,
3683 &SetStaticDoubleField,
3688 &ReleaseStringChars,
3691 &GetStringUTFLength,
3693 &ReleaseStringUTFChars,
3698 &GetObjectArrayElement,
3699 &SetObjectArrayElement,
3710 &GetBooleanArrayElements,
3711 &GetByteArrayElements,
3712 &GetCharArrayElements,
3713 &GetShortArrayElements,
3714 &GetIntArrayElements,
3715 &GetLongArrayElements,
3716 &GetFloatArrayElements,
3717 &GetDoubleArrayElements,
3719 &ReleaseBooleanArrayElements,
3720 &ReleaseByteArrayElements,
3721 &ReleaseCharArrayElements,
3722 &ReleaseShortArrayElements,
3723 &ReleaseIntArrayElements,
3724 &ReleaseLongArrayElements,
3725 &ReleaseFloatArrayElements,
3726 &ReleaseDoubleArrayElements,
3728 &GetBooleanArrayRegion,
3729 &GetByteArrayRegion,
3730 &GetCharArrayRegion,
3731 &GetShortArrayRegion,
3733 &GetLongArrayRegion,
3734 &GetFloatArrayRegion,
3735 &GetDoubleArrayRegion,
3736 &SetBooleanArrayRegion,
3737 &SetByteArrayRegion,
3738 &SetCharArrayRegion,
3739 &SetShortArrayRegion,
3741 &SetLongArrayRegion,
3742 &SetFloatArrayRegion,
3743 &SetDoubleArrayRegion,
3753 /* new JNI 1.2 functions */
3756 &GetStringUTFRegion,
3758 &GetPrimitiveArrayCritical,
3759 &ReleasePrimitiveArrayCritical,
3762 &ReleaseStringCritical,
3765 &DeleteWeakGlobalRef,
3769 /* new JNI 1.4 functions */
3771 &NewDirectByteBuffer,
3772 &GetDirectBufferAddress,
3773 &GetDirectBufferCapacity
3777 /* Invocation API Functions ***************************************************/
3779 /* JNI_GetDefaultJavaVMInitArgs ************************************************
3781 Returns a default configuration for the Java VM.
3783 *******************************************************************************/
3785 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
3787 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
3789 /* GNU classpath currently supports JNI 1.2 */
3791 _vm_args->version = JNI_VERSION_1_2;
3797 /* JNI_GetCreatedJavaVMs *******************************************************
3799 Returns all Java VMs that have been created. Pointers to VMs are written in
3800 the buffer vmBuf in the order they are created. At most bufLen number of
3801 entries will be written. The total number of created VMs is returned in
3804 *******************************************************************************/
3806 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
3808 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
3814 /* JNI_CreateJavaVM ************************************************************
3816 Loads and initializes a Java VM. The current thread becomes the main thread.
3817 Sets the env argument to the JNI interface pointer of the main thread.
3819 *******************************************************************************/
3821 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
3823 *p_vm = (JavaVM *) &JNI_JavaVMTable;
3824 *p_env = (JNIEnv *) &JNI_JNIEnvTable;
3830 jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID, jobject obj, java_objectarray *params)
3837 if (methodID == 0) {
3838 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
3842 argcount = get_parametercount(methodID);
3844 /* the method is an instance method the obj has to be an instance of the
3845 class the method belongs to. For static methods the obj parameter
3847 if (!(methodID->flags & ACC_STATIC) && obj &&
3848 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
3849 *exceptionptr = new_exception_message(string_java_lang_IllegalArgumentException,
3850 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
3857 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3858 log_text("Too many arguments. invokeNativeHelper does not support that");
3862 if (((params==0) && (argcount != 0)) || (params && (params->header.size != argcount))) {
3863 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3868 if (((methodID->flags & ACC_STATIC)==0) && (0==obj)) {
3870 new_exception_message(string_java_lang_NullPointerException,
3871 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
3875 if ((methodID->flags & ACC_STATIC) && (obj)) obj = 0;
3878 if ( (methodID->flags & ACC_ABSTRACT) || (methodID->class->flags & ACC_INTERFACE) ) {
3879 methodID=get_virtual(obj,methodID);
3883 blk = MNEW(jni_callblock, /*4 */argcount+2);
3885 retT = fill_callblock_objA(obj, methodID->descriptor, blk, params);
3889 (void) asm_calljavafunction2(methodID,
3891 (argcount + 1) * sizeof(jni_callblock),
3893 retVal = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
3898 intVal = asm_calljavafunction2int(methodID,
3900 (argcount + 1) * sizeof(jni_callblock),
3902 retVal = builtin_new(class_java_lang_Integer);
3905 class_resolvemethod(retVal->vftbl->class,
3914 intVal = asm_calljavafunction2int(methodID,
3916 (argcount + 1) * sizeof(jni_callblock),
3918 retVal = builtin_new(class_java_lang_Byte);
3921 class_resolvemethod(retVal->vftbl->class,
3930 intVal = asm_calljavafunction2int(methodID,
3932 (argcount + 1) * sizeof(jni_callblock),
3934 retVal = builtin_new(class_java_lang_Character);
3937 class_resolvemethod(retVal->vftbl->class,
3946 intVal = asm_calljavafunction2int(methodID,
3948 (argcount + 1) * sizeof(jni_callblock),
3950 retVal = builtin_new(class_java_lang_Short);
3953 class_resolvemethod(retVal->vftbl->class,
3962 intVal = asm_calljavafunction2int(methodID,
3964 (argcount + 1) * sizeof(jni_callblock),
3966 retVal = builtin_new(class_java_lang_Boolean);
3969 class_resolvemethod(retVal->vftbl->class,
3978 longVal = asm_calljavafunction2long(methodID,
3980 (argcount + 1) * sizeof(jni_callblock),
3982 retVal = builtin_new(class_java_lang_Long);
3985 class_resolvemethod(retVal->vftbl->class,
3994 floatVal = asm_calljavafunction2float(methodID,
3996 (argcount + 1) * sizeof(jni_callblock),
3998 retVal = builtin_new(class_java_lang_Float);
4001 class_resolvemethod(retVal->vftbl->class,
4010 doubleVal = asm_calljavafunction2double(methodID,
4012 (argcount + 1) * sizeof(jni_callblock),
4014 retVal = builtin_new(class_java_lang_Double);
4017 class_resolvemethod(retVal->vftbl->class,
4024 case 'L': /* fall through */
4026 retVal = asm_calljavafunction2(methodID,
4028 (argcount + 1) * sizeof(jni_callblock),
4033 /* if this happens the acception has already been set by fill_callblock_objA*/
4034 MFREE(blk, jni_callblock, /*4 */ argcount+2);
4035 return (jobject *) 0;
4038 MFREE(blk, jni_callblock, /* 4 */ argcount+2);
4040 if (*exceptionptr) {
4041 java_objectheader *exceptionToWrap = *exceptionptr;
4043 java_objectheader *ivte;
4045 *exceptionptr = NULL;
4046 ivtec = class_new(utf_new_char("java/lang/reflect/InvocationTargetException"));
4047 ivte = builtin_new(ivtec);
4048 asm_calljavafunction(class_resolvemethod(ivtec,
4049 utf_new_char("<init>"),
4050 utf_new_char("(Ljava/lang/Throwable;)V")),
4056 if (*exceptionptr != NULL)
4057 panic("jni.c: error while creating InvocationTargetException wrapper");
4059 *exceptionptr = ivte;
4062 return (jobject *) retVal;
4069 * These are local overrides for various environment variables in Emacs.
4070 * Please do not remove this and leave it at the end of the file, where
4071 * Emacs will automagically detect them.
4072 * ---------------------------------------------------------------------
4075 * indent-tabs-mode: t