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 3248 2005-09-21 15:32:13Z twisti $
44 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/native.h"
47 #include "native/include/java_lang_Object.h"
48 #include "native/include/java_lang_Byte.h"
49 #include "native/include/java_lang_Character.h"
50 #include "native/include/java_lang_Short.h"
51 #include "native/include/java_lang_Integer.h"
52 #include "native/include/java_lang_Boolean.h"
53 #include "native/include/java_lang_Long.h"
54 #include "native/include/java_lang_Float.h"
55 #include "native/include/java_lang_Double.h"
56 #include "native/include/java_lang_Throwable.h"
57 #include "native/include/java_lang_reflect_Method.h"
58 #include "native/include/java_lang_reflect_Constructor.h"
59 #include "native/include/java_lang_reflect_Field.h"
61 #include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
62 #include "native/include/java_lang_VMClass.h"
63 #include "native/include/java_lang_VMClassLoader.h"
65 #if defined(ENABLE_JVMTI)
66 # include "native/jvmti/jvmti.h"
69 #if defined(USE_THREADS)
70 # if defined(NATIVE_THREADS)
71 # include "threads/native/threads.h"
73 # include "threads/green/threads.h"
77 #include "toolbox/logging.h"
78 #include "vm/builtin.h"
79 #include "vm/exceptions.h"
80 #include "vm/global.h"
81 #include "vm/initialize.h"
82 #include "vm/loader.h"
83 #include "vm/options.h"
84 #include "vm/resolve.h"
85 #include "vm/statistics.h"
86 #include "vm/stringlocal.h"
87 #include "vm/tables.h"
88 #include "vm/jit/asmpart.h"
89 #include "vm/jit/jit.h"
90 #include "vm/statistics.h"
93 /* XXX TWISTI hack: define it extern so they can be found in this file */
95 extern const struct JNIInvokeInterface JNI_JavaVMTable;
96 extern struct JNINativeInterface JNI_JNIEnvTable;
98 /* pointers to VM and the environment needed by GetJavaVM and GetEnv */
100 static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
101 void* ptr_env = (void*) &JNI_JNIEnvTable;
104 #define PTR_TO_ITEM(ptr) ((u8)(size_t)(ptr))
106 /* global reference table */
107 static jobject *global_ref_table;
108 static bool initrunning=false;
110 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
111 static jmethodID getmid = NULL;
112 static jmethodID putmid = NULL;
113 static jclass intclass = NULL;
114 static jmethodID intvalue = NULL;
115 static jmethodID newint = NULL;
116 static jclass ihmclass = NULL;
117 static jmethodID removemid = NULL;
119 #define JWCLINITDEBUG(x)
122 /********************* accessing instance-fields **********************************/
124 #define setField(obj,typ,var,val) *((typ*) ((long int) obj + (long int) var->offset))=val;
125 #define getField(obj,typ,var) *((typ*) ((long int) obj + (long int) var->offset))
126 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) \
127 setField(obj, jdatatype, getFieldID_critical(env,clazz,name,sig), val);
130 static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
131 jni_callblock blk[], va_list data,
134 typedesc *paramtypes;
137 paramtypes = descr->paramtypes;
139 /* if method is non-static fill first block and skip `this' pointer */
144 /* the `this' pointer */
145 blk[0].itemtype = TYPE_ADR;
146 blk[0].item = PTR_TO_ITEM(obj);
152 for (; i < descr->paramcount; i++, paramtypes++) {
153 switch (paramtypes->decltype) {
154 /* primitive types */
155 case PRIMITIVETYPE_BYTE:
156 case PRIMITIVETYPE_CHAR:
157 case PRIMITIVETYPE_SHORT:
158 case PRIMITIVETYPE_BOOLEAN:
159 blk[i].itemtype = TYPE_INT;
160 blk[i].item = (s8) va_arg(data, s4);
163 case PRIMITIVETYPE_INT:
164 blk[i].itemtype = TYPE_INT;
165 blk[i].item = (s8) va_arg(data, s4);
168 case PRIMITIVETYPE_LONG:
169 blk[i].itemtype = TYPE_LNG;
170 blk[i].item = (s8) va_arg(data, s8);
173 case PRIMITIVETYPE_FLOAT:
174 blk[i].itemtype = TYPE_FLT;
175 #if defined(__ALPHA__)
176 /* this keeps the assembler function much simpler */
178 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
180 *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
184 case PRIMITIVETYPE_DOUBLE:
185 blk[i].itemtype = TYPE_DBL;
186 *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
190 blk[i].itemtype = TYPE_ADR;
191 blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
196 /* The standard doesn't say anything about return value checking, but it */
197 /* appears to be useful. */
199 if (rettype != descr->returntype.decltype)
200 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
204 /* XXX it could be considered if we should do typechecking here in the future */
206 static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
208 java_objectarray *params)
212 typedesc *paramtypes;
217 paramcount = descr->paramcount;
218 paramtypes = descr->paramtypes;
220 /* if method is non-static fill first block and skip `this' pointer */
226 blk[0].itemtype = TYPE_ADR;
227 blk[0].item = PTR_TO_ITEM(obj);
234 for (j = 0; j < paramcount; i++, j++, paramtypes++) {
235 switch (paramtypes->type) {
236 /* primitive types */
241 param = params->data[j];
245 /* internally used data type */
246 blk[i].itemtype = paramtypes->type;
248 /* convert the value according to its declared type */
250 c = param->vftbl->class;
252 switch (paramtypes->decltype) {
253 case PRIMITIVETYPE_BOOLEAN:
254 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
255 blk[i].item = (s8) ((java_lang_Boolean *) param)->value;
260 case PRIMITIVETYPE_BYTE:
261 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
262 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
267 case PRIMITIVETYPE_CHAR:
268 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
269 blk[i].item = (s8) ((java_lang_Character *) param)->value;
274 case PRIMITIVETYPE_SHORT:
275 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
276 blk[i].item = (s8) ((java_lang_Short *) param)->value;
277 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
278 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
283 case PRIMITIVETYPE_INT:
284 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
285 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
286 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
287 blk[i].item = (s8) ((java_lang_Short *) param)->value;
288 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
289 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
294 case PRIMITIVETYPE_LONG:
295 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
296 blk[i].item = (s8) ((java_lang_Long *) param)->value;
297 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
298 blk[i].item = (s8) ((java_lang_Integer *) param)->value;
299 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
300 blk[i].item = (s8) ((java_lang_Short *) param)->value;
301 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
302 blk[i].item = (s8) ((java_lang_Byte *) param)->value;
307 case PRIMITIVETYPE_FLOAT:
308 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
309 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
314 case PRIMITIVETYPE_DOUBLE:
315 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
316 *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Float *) param)->value;
317 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
318 *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
325 } /* end declared type switch */
329 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
332 if (params->data[j] != 0) {
333 if (paramtypes->arraydim > 0) {
334 if (!builtin_arrayinstanceof(params->data[j], c->vftbl))
338 if (!builtin_instanceof(params->data[j], c))
342 blk[i].itemtype = TYPE_ADR;
343 blk[i].item = PTR_TO_ITEM(params->data[j]);
348 } /* end param type switch */
350 } /* end param loop */
353 /* *rettype = descr->returntype.decltype; */
358 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
363 static jmethodID get_virtual(jobject obj, jmethodID methodID)
365 if (obj->vftbl->class == methodID->class)
368 return class_resolvemethod(obj->vftbl->class, methodID->name,
369 methodID->descriptor);
373 static jmethodID get_nonvirtual(jclass clazz, jmethodID methodID)
375 if (clazz == methodID->class)
378 /* class_resolvemethod -> classfindmethod? (JOWENN) */
379 return class_resolvemethod(clazz, methodID->name, methodID->descriptor);
383 static jobject callObjectMethod(jobject obj, jmethodID methodID, va_list args)
390 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
394 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
395 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
396 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
400 if (obj && !builtin_instanceof(obj, methodID->class)) {
401 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
405 argcount = methodID->parseddesc->paramcount;
407 blk = MNEW(jni_callblock, argcount);
409 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_ADR);
411 STATS(jnicallXmethodnvokation();)
413 ret = asm_calljavafunction2(methodID,
415 argcount * sizeof(jni_callblock),
418 MFREE(blk, jni_callblock, argcount);
425 core function for integer class methods (bool, byte, short, integer)
426 This is basically needed for i386
428 static jint callIntegerMethod(jobject obj, jmethodID methodID, int retType, va_list args)
434 STATS(jniinvokation();)
437 log_text("JNI-Call: CallObjectMethodV");
438 utf_display(methodID->name);
439 utf_display(methodID->descriptor);
440 printf("\nParmaeter count: %d\n",argcount);
441 utf_display(obj->vftbl->class->name);
445 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
449 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
450 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
451 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
455 if (obj && !builtin_instanceof(obj, methodID->class)) {
456 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
460 argcount = methodID->parseddesc->paramcount;
462 blk = MNEW(jni_callblock, argcount);
464 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
466 STATS(jnicallXmethodnvokation();)
468 ret = asm_calljavafunction2int(methodID,
470 argcount * sizeof(jni_callblock),
473 MFREE(blk, jni_callblock, argcount);
479 /*core function for long class functions*/
480 static jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
486 STATS(jniinvokation();)
491 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
495 argcount = methodID->parseddesc->paramcount;
497 if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
498 ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
499 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
503 if (obj && !builtin_instanceof(obj,methodID->class)) {
504 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
509 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
510 log_text("Too many arguments. CallObjectMethod does not support that");
514 blk = MNEW(jni_callblock,/* 4 */argcount+2);
516 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_LNG);
518 STATS(jnicallXmethodnvokation();)
519 ret = asm_calljavafunction2long(methodID,
521 (argcount + 1) * sizeof(jni_callblock),
524 MFREE(blk, jni_callblock, argcount + 1);
530 /*core function for float class methods (float,double)*/
531 static jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,int retType)
533 int argcount = methodID->parseddesc->paramcount;
537 STATS(jniinvokation();)
542 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
543 log_text("Too many arguments. CallObjectMethod does not support that");
547 blk = MNEW(jni_callblock, /*4 */ argcount+2);
549 fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
551 /* printf("parameter: obj: %p",blk[0].item); */
552 STATS(jnicallXmethodnvokation();)
553 ret = asm_calljavafunction2double(methodID,
555 (argcount + 1) * sizeof(jni_callblock),
558 MFREE(blk, jni_callblock, argcount + 1);
559 /* printf("(CallObjectMethodV)-->%p\n",ret); */
565 /*************************** function: jclass_findfield ****************************
567 searches for field with specified name and type in a 'classinfo'-structur
568 if no such field is found NULL is returned
570 ************************************************************************************/
572 static fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
575 STATS(jniinvokation();)
577 /* printf(" FieldCount: %d\n",c->fieldscount);
578 utf_display(c->name); */
579 for (i = 0; i < c->fieldscount; i++) {
580 /* utf_display(c->fields[i].name);
582 utf_display(c->fields[i].descriptor);
584 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
585 return &(c->fields[i]);
588 if (c->super.cls) return jclass_findfield(c->super.cls,name,desc);
594 /* GetVersion ******************************************************************
596 Returns the major version number in the higher 16 bits and the
597 minor version number in the lower 16 bits.
599 *******************************************************************************/
601 jint GetVersion(JNIEnv *env)
603 STATS(jniinvokation();)
605 /* just say we support JNI 1.4 */
607 return JNI_VERSION_1_4;
611 /* Class Operations ***********************************************************/
613 /* DefineClass *****************************************************************
615 Loads a class from a buffer of raw class data. The buffer
616 containing the raw class data is not referenced by the VM after the
617 DefineClass call returns, and it may be discarded if desired.
619 *******************************************************************************/
621 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
622 const jbyte *buf, jsize bufLen)
624 java_lang_ClassLoader *cl;
629 STATS(jniinvokation();)
631 cl = (java_lang_ClassLoader *) loader;
632 s = javastring_new_char(name);
633 ba = (java_bytearray *) buf;
635 c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
642 /* FindClass *******************************************************************
644 This function loads a locally-defined class. It searches the
645 directories and zip files specified by the CLASSPATH environment
646 variable for the class with the specified name.
648 *******************************************************************************/
650 jclass FindClass(JNIEnv *env, const char *name)
654 java_objectheader *cl;
656 STATS(jniinvokation();)
658 u = utf_new_char_classname((char *) name);
660 /* check stacktrace for classloader, if one found use it, otherwise use */
661 /* the system classloader */
663 #if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__)
664 /* these JITs support stacktraces, and so does the interpreter */
666 cl = cacao_currentClassLoader();
668 # if defined(ENABLE_INTRP)
669 /* the interpreter supports stacktraces, even if the JIT does not */
672 cl = cacao_currentClassLoader();
678 if (!(c = load_class_from_classloader(u, cl)))
684 use_class_as_object(c);
690 /* FromReflectedMethod *********************************************************
692 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
693 object to a method ID.
695 *******************************************************************************/
697 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
703 STATS(jniinvokation();)
708 if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
709 java_lang_reflect_Method *rm;
711 rm = (java_lang_reflect_Method *) method;
712 c = (classinfo *) (rm->declaringClass);
715 } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
716 java_lang_reflect_Constructor *rc;
718 rc = (java_lang_reflect_Constructor *) method;
719 c = (classinfo *) (rc->clazz);
725 if ((slot < 0) || (slot >= c->methodscount)) {
726 /* this usually means a severe internal cacao error or somebody
727 tempered around with the reflected method */
728 log_text("error illegal slot for method in class(FromReflectedMethod)");
732 mi = &(c->methods[slot]);
738 /* GetSuperclass ***************************************************************
740 If clazz represents any class other than the class Object, then
741 this function returns the object that represents the superclass of
742 the class specified by clazz.
744 *******************************************************************************/
746 jclass GetSuperclass(JNIEnv *env, jclass sub)
749 STATS(jniinvokation();)
751 c = ((classinfo *) sub)->super.cls;
756 use_class_as_object(c);
762 /* IsAssignableFrom ************************************************************
764 Determines whether an object of sub can be safely cast to sup.
766 *******************************************************************************/
768 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
770 STATS(jniinvokation();)
771 return Java_java_lang_VMClass_isAssignableFrom(env,
773 (java_lang_Class *) sup,
774 (java_lang_Class *) sub);
778 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
780 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
782 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!!!");
783 STATS(jniinvokation();)
788 /* Throw ***********************************************************************
790 Causes a java.lang.Throwable object to be thrown.
792 *******************************************************************************/
794 jint Throw(JNIEnv *env, jthrowable obj)
796 *exceptionptr = (java_objectheader *) obj;
797 STATS(jniinvokation();)
803 /* ThrowNew ********************************************************************
805 Constructs an exception object from the specified class with the
806 message specified by message and causes that exception to be
809 *******************************************************************************/
811 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
813 java_lang_Throwable *o;
815 STATS(jniinvokation();)
817 s = (java_lang_String *) javastring_new_char(msg);
819 /* instantiate exception object */
821 o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
827 *exceptionptr = (java_objectheader *) o;
833 /* ExceptionOccurred ***********************************************************
835 Determines if an exception is being thrown. The exception stays
836 being thrown until either the native code calls ExceptionClear(),
837 or the Java code handles the exception.
839 *******************************************************************************/
841 jthrowable ExceptionOccurred(JNIEnv *env)
843 STATS(jniinvokation();)
844 return (jthrowable) *exceptionptr;
848 /* ExceptionDescribe ***********************************************************
850 Prints an exception and a backtrace of the stack to a system
851 error-reporting channel, such as stderr. This is a convenience
852 routine provided for debugging.
854 *******************************************************************************/
856 void ExceptionDescribe(JNIEnv *env)
858 java_objectheader *e;
860 STATS(jniinvokation();)
865 /* clear exception, because we are calling jit code again */
867 *exceptionptr = NULL;
869 /* get printStackTrace method from exception class */
871 m = class_resolveclassmethod(e->vftbl->class,
878 /* XXX what should we do? */
881 /* print the stacktrace */
883 asm_calljavafunction(m, e, NULL, NULL, NULL);
888 /* ExceptionClear **************************************************************
890 Clears any exception that is currently being thrown. If no
891 exception is currently being thrown, this routine has no effect.
893 *******************************************************************************/
895 void ExceptionClear(JNIEnv *env)
897 STATS(jniinvokation();)
898 *exceptionptr = NULL;
902 /* FatalError ******************************************************************
904 Raises a fatal error and does not expect the VM to recover. This
905 function does not return.
907 *******************************************************************************/
909 void FatalError(JNIEnv *env, const char *msg)
911 STATS(jniinvokation();)
912 throw_cacao_exception_exit(string_java_lang_InternalError, msg);
916 /******************* creates a new local reference frame **************************/
918 jint PushLocalFrame(JNIEnv* env, jint capacity)
920 log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
921 STATS(jniinvokation();)
926 /**************** Pops off the current local reference frame **********************/
928 jobject PopLocalFrame(JNIEnv* env, jobject result)
930 log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
931 STATS(jniinvokation();)
937 /* DeleteLocalRef **************************************************************
939 Deletes the local reference pointed to by localRef.
941 *******************************************************************************/
943 void DeleteLocalRef(JNIEnv *env, jobject localRef)
945 STATS(jniinvokation();)
947 log_text("JNI-Call: DeleteLocalRef: IMPLEMENT ME!");
951 /* IsSameObject ****************************************************************
953 Tests whether two references refer to the same Java object.
955 *******************************************************************************/
957 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
959 STATS(jniinvokation();)
960 return (ref1 == ref2);
964 /* NewLocalRef *****************************************************************
966 Creates a new local reference that refers to the same object as ref.
968 *******************************************************************************/
970 jobject NewLocalRef(JNIEnv *env, jobject ref)
972 log_text("JNI-Call: NewLocalRef: IMPLEMENT ME!");
973 STATS(jniinvokation();)
977 /***********************************************************************************
979 Ensures that at least a given number of local references can
980 be created in the current thread
982 **********************************************************************************/
984 jint EnsureLocalCapacity (JNIEnv* env, jint capacity)
986 STATS(jniinvokation();)
987 return 0; /* return 0 on success */
991 /* AllocObject *****************************************************************
993 Allocates a new Java object without invoking any of the
994 constructors for the object. Returns a reference to the object.
996 *******************************************************************************/
998 jobject AllocObject(JNIEnv *env, jclass clazz)
1000 java_objectheader *o;
1001 STATS(jniinvokation();)
1003 if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1005 new_exception_utfmessage(string_java_lang_InstantiationException,
1010 o = builtin_new(clazz);
1016 /* NewObject *******************************************************************
1018 Constructs a new Java object. The method ID indicates which
1019 constructor method to invoke. This ID must be obtained by calling
1020 GetMethodID() with <init> as the method name and void (V) as the
1023 *******************************************************************************/
1025 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1027 java_objectheader *o;
1029 int argcount=methodID->parseddesc->paramcount;
1032 STATS(jniinvokation();)
1035 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
1036 log_text("Too many arguments. NewObject does not support that");
1042 o = builtin_new(clazz);
1047 va_start(vaargs, methodID);
1048 for (i = 0; i < argcount; i++) {
1049 args[i] = va_arg(vaargs, void*);
1053 /* call constructor */
1055 asm_calljavafunction(methodID, o, args[0], args[1], args[2]);
1061 /***********************************************************************************
1063 Constructs a new Java object
1064 arguments that are to be passed to the constructor are placed in va_list args
1066 ***********************************************************************************/
1068 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1070 log_text("JNI-Call: NewObjectV");
1071 STATS(jniinvokation();)
1077 /***********************************************************************************
1079 Constructs a new Java object
1080 arguments that are to be passed to the constructor are placed in
1081 args array of jvalues
1083 ***********************************************************************************/
1085 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1087 log_text("JNI-Call: NewObjectA");
1088 STATS(jniinvokation();)
1094 /* GetObjectClass **************************************************************
1096 Returns the class of an object.
1098 *******************************************************************************/
1100 jclass GetObjectClass(JNIEnv *env, jobject obj)
1103 STATS(jniinvokation();)
1105 if (!obj || !obj->vftbl)
1108 c = obj->vftbl->class;
1109 use_class_as_object(c);
1114 /* IsInstanceOf ****************************************************************
1116 Tests whether an object is an instance of a class.
1118 *******************************************************************************/
1120 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1122 STATS(jniinvokation();)
1124 return Java_java_lang_VMClass_isInstance(env,
1126 (java_lang_Class *) clazz,
1127 (java_lang_Object *) obj);
1131 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1133 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1135 java_lang_reflect_Field *f;
1137 jfieldID fid; /* the JNI-fieldid of the wrapping object */
1138 STATS(jniinvokation();)
1139 /*log_text("JNI-Call: FromReflectedField");*/
1141 f=(java_lang_reflect_Field *)field;
1143 c=(classinfo*)(f->declaringClass);
1144 if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1145 /*this usually means a severe internal cacao error or somebody
1146 tempered around with the reflected method*/
1147 log_text("error illegal slot for field in class(FromReflectedField)");
1150 fid=&(c->fields[f->slot]);
1155 /**********************************************************************************
1157 converts a method ID to a java.lang.reflect.Method or
1158 java.lang.reflect.Constructor object
1160 **********************************************************************************/
1162 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1164 log_text("JNI-Call: ToReflectedMethod");
1165 STATS(jniinvokation();)
1171 /* GetMethodID *****************************************************************
1173 returns the method ID for an instance method
1175 *******************************************************************************/
1177 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1180 STATS(jniinvokation();)
1182 m = class_resolvemethod(clazz,
1183 utf_new_char((char *) name),
1184 utf_new_char((char *) sig));
1186 if (!m || (m->flags & ACC_STATIC)) {
1188 new_exception_message(string_java_lang_NoSuchMethodError, name);
1197 /******************** JNI-functions for calling instance methods ******************/
1199 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1203 STATS(jniinvokation();)
1205 /* log_text("JNI-Call: CallObjectMethod");*/
1207 va_start(vaargs, methodID);
1208 ret = callObjectMethod(obj, methodID, vaargs);
1215 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1217 STATS(jniinvokation();)
1218 return callObjectMethod(obj,methodID,args);
1222 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1224 log_text("JNI-Call: CallObjectMethodA");
1225 STATS(jniinvokation();)
1233 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1237 STATS(jniinvokation();)
1239 /* log_text("JNI-Call: CallBooleanMethod");*/
1241 va_start(vaargs,methodID);
1242 ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1248 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1250 STATS(jniinvokation();)
1252 return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
1256 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1258 STATS(jniinvokation();)
1259 log_text("JNI-Call: CallBooleanMethodA");
1264 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1268 STATS(jniinvokation();)
1270 /* log_text("JNI-Call: CallVyteMethod");*/
1272 va_start(vaargs,methodID);
1273 ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
1279 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1281 /* log_text("JNI-Call: CallByteMethodV");*/
1282 STATS(jniinvokation();)
1284 return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
1288 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1290 log_text("JNI-Call: CallByteMethodA");
1291 STATS(jniinvokation();)
1297 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1301 STATS(jniinvokation();)
1303 /* log_text("JNI-Call: CallCharMethod");*/
1305 va_start(vaargs,methodID);
1306 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
1313 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1315 STATS(jniinvokation();)
1317 /* log_text("JNI-Call: CallCharMethodV");*/
1318 return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
1322 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1324 STATS(jniinvokation();)
1326 log_text("JNI-Call: CallCharMethodA");
1332 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1336 STATS(jniinvokation();)
1338 /* log_text("JNI-Call: CallShortMethod");*/
1340 va_start(vaargs, methodID);
1341 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
1348 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1350 STATS(jniinvokation();)
1351 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
1355 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1357 STATS(jniinvokation();)
1358 log_text("JNI-Call: CallShortMethodA");
1365 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1369 STATS(jniinvokation();)
1371 va_start(vaargs,methodID);
1372 ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
1379 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1381 STATS(jniinvokation();)
1382 return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
1386 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1388 STATS(jniinvokation();)
1389 log_text("JNI-Call: CallIntMethodA");
1396 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1400 STATS(jniinvokation();)
1402 va_start(vaargs,methodID);
1403 ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1410 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1412 STATS(jniinvokation();)
1413 return callLongMethod(obj,get_virtual(obj, methodID),args);
1417 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1419 STATS(jniinvokation();)
1420 log_text("JNI-Call: CallLongMethodA");
1427 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1432 STATS(jniinvokation();)
1433 /* log_text("JNI-Call: CallFloatMethod");*/
1435 va_start(vaargs,methodID);
1436 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
1443 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1445 STATS(jniinvokation();)
1446 log_text("JNI-Call: CallFloatMethodV");
1447 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
1451 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1453 STATS(jniinvokation();)
1454 log_text("JNI-Call: CallFloatMethodA");
1461 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1465 STATS(jniinvokation();)
1467 /* log_text("JNI-Call: CallDoubleMethod");*/
1469 va_start(vaargs,methodID);
1470 ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
1477 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1479 STATS(jniinvokation();)
1480 log_text("JNI-Call: CallDoubleMethodV");
1481 return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
1485 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1487 STATS(jniinvokation();)
1488 log_text("JNI-Call: CallDoubleMethodA");
1494 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1497 STATS(jniinvokation();)
1499 va_start(vaargs,methodID);
1500 (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
1505 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1507 log_text("JNI-Call: CallVoidMethodV");
1508 STATS(jniinvokation();)
1509 (void)callIntegerMethod(obj,get_virtual(obj,methodID),TYPE_VOID,args);
1513 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1515 STATS(jniinvokation();)
1516 log_text("JNI-Call: CallVoidMethodA");
1521 jobject CallNonvirtualObjectMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1523 STATS(jniinvokation();)
1524 log_text("JNI-Call: CallNonvirtualObjectMethod");
1530 jobject CallNonvirtualObjectMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1532 STATS(jniinvokation();)
1533 log_text("JNI-Call: CallNonvirtualObjectMethodV");
1539 jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1541 STATS(jniinvokation();)
1542 log_text("JNI-Call: CallNonvirtualObjectMethodA");
1549 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1553 STATS(jniinvokation();)
1555 /* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1557 va_start(vaargs,methodID);
1558 ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1565 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1567 STATS(jniinvokation();)
1568 /* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1569 return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
1573 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1575 STATS(jniinvokation();)
1576 log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1583 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1588 STATS(jniinvokation();)
1589 /* log_text("JNI-Call: CallNonvirutalByteMethod");*/
1591 va_start(vaargs,methodID);
1592 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
1598 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1600 STATS(jniinvokation();)
1601 /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1602 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
1607 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1609 STATS(jniinvokation();)
1610 log_text("JNI-Call: CallNonvirtualByteMethodA");
1617 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1622 STATS(jniinvokation();)
1623 /* log_text("JNI-Call: CallNonVirtualCharMethod");*/
1625 va_start(vaargs,methodID);
1626 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
1632 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1634 STATS(jniinvokation();)
1635 /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1636 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
1640 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1642 STATS(jniinvokation();)
1643 log_text("JNI-Call: CallNonvirtualCharMethodA");
1650 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1654 STATS(jniinvokation();)
1656 /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1658 va_start(vaargs,methodID);
1659 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
1665 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1667 STATS(jniinvokation();)
1668 /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1669 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
1673 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1675 STATS(jniinvokation();)
1676 log_text("JNI-Call: CallNonvirtualShortMethodA");
1683 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1688 STATS(jniinvokation();)
1690 /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1692 va_start(vaargs,methodID);
1693 ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
1699 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1701 STATS(jniinvokation();)
1702 /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1703 return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
1707 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1709 STATS(jniinvokation();)
1710 log_text("JNI-Call: CallNonvirtualIntMethodA");
1717 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1719 STATS(jniinvokation();)
1720 log_text("JNI-Call: CallNonvirtualLongMethod");
1726 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1728 STATS(jniinvokation();)
1729 log_text("JNI-Call: CallNonvirtualLongMethodV");
1735 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1737 STATS(jniinvokation();)
1738 log_text("JNI-Call: CallNonvirtualLongMethodA");
1745 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1749 STATS(jniinvokation();)
1751 /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1754 va_start(vaargs,methodID);
1755 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
1762 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1764 STATS(jniinvokation();)
1765 log_text("JNI-Call: CallNonvirtualFloatMethodV");
1766 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
1770 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1772 STATS(jniinvokation();)
1773 log_text("JNI-Call: CallNonvirtualFloatMethodA");
1780 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1784 STATS(jniinvokation();)
1785 log_text("JNI-Call: CallNonvirtualDoubleMethod");
1787 va_start(vaargs,methodID);
1788 ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
1795 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1797 STATS(jniinvokation();)
1798 /* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
1799 return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
1803 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1805 STATS(jniinvokation();)
1806 log_text("JNI-Call: CallNonvirtualDoubleMethodA");
1813 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1816 STATS(jniinvokation();)
1818 /* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
1820 va_start(vaargs,methodID);
1821 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
1827 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1829 /* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
1830 STATS(jniinvokation();)
1832 (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
1837 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1839 STATS(jniinvokation();)
1840 log_text("JNI-Call: CallNonvirtualVoidMethodA");
1843 /************************* JNI-functions for accessing fields ************************/
1845 jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
1849 STATS(jniinvokation();)
1851 /* log_text("========================= searching for:");
1854 f = jclass_findfield(clazz,
1855 utf_new_char ((char*) name),
1856 utf_new_char ((char*) sig)
1860 /*utf_display(clazz->name);
1863 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
1868 /*************************** retrieve fieldid, abort on error ************************/
1870 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
1872 jfieldID id = GetFieldID(env, clazz, name, sig);
1873 STATS(jniinvokation();)
1877 utf_display(clazz->name);
1878 log_text("\nfield:");
1883 log_text("setfield_critical failed");
1889 jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
1892 jobject dbg,dretval,*dpretval;
1893 long int dli1, dli2, dli3;
1895 printf("GetObjectField(1): thread: %s obj: %p name: %s desc: %s \n",GetStringUTFChars(env,
1896 ((threadobject *) THREADOBJECT)->o
1898 ,obj,((fieldinfo*)fieldID)->name->text,(fieldID->descriptor)->text);
1900 dbg = getField(obj,jobject,fieldID);
1901 dli1 = (long int) obj;
1902 dli2 = (long int) fieldID->offset;
1904 dpretval = (jobject*) dli3;
1905 dretval = *dpretval;
1910 tmp = FindClass(env, "java/lang/Object");
1911 mid = GetMethodID(env,tmp,"toString","()Ljava/lang/String;");
1912 jstr = CallObjectMethod(env,dbg,mid);*/
1914 /* printf("GetObjectField(2): retval %p (obj: %#lx + offset: %#lx = %#lx (jobject*) %p (jobject) %p\n"
1915 ,dbg, dli1, dli2, dli3,dpretval, dretval);*/
1919 STATS(jniinvokation();)
1921 return getField(obj,jobject,fieldID);
1924 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
1926 STATS(jniinvokation();)
1927 return getField(obj,jboolean,fieldID);
1931 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
1933 STATS(jniinvokation();)
1934 return getField(obj,jbyte,fieldID);
1938 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
1940 STATS(jniinvokation();)
1941 return getField(obj,jchar,fieldID);
1945 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
1947 STATS(jniinvokation();)
1948 return getField(obj,jshort,fieldID);
1952 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
1954 STATS(jniinvokation();)
1955 return getField(obj,jint,fieldID);
1959 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
1961 STATS(jniinvokation();)
1962 return getField(obj,jlong,fieldID);
1966 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
1968 STATS(jniinvokation();)
1969 return getField(obj,jfloat,fieldID);
1973 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
1975 STATS(jniinvokation();)
1976 return getField(obj,jdouble,fieldID);
1979 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
1981 STATS(jniinvokation();)
1982 setField(obj,jobject,fieldID,val);
1986 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
1988 STATS(jniinvokation();)
1989 setField(obj,jboolean,fieldID,val);
1993 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
1995 STATS(jniinvokation();)
1996 setField(obj,jbyte,fieldID,val);
2000 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
2002 STATS(jniinvokation();)
2003 setField(obj,jchar,fieldID,val);
2007 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
2009 STATS(jniinvokation();)
2010 setField(obj,jshort,fieldID,val);
2014 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
2016 STATS(jniinvokation();)
2017 setField(obj,jint,fieldID,val);
2021 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
2023 STATS(jniinvokation();)
2024 setField(obj,jlong,fieldID,val);
2028 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
2030 STATS(jniinvokation();)
2031 setField(obj,jfloat,fieldID,val);
2035 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
2037 STATS(jniinvokation();)
2038 setField(obj,jdouble,fieldID,val);
2042 /**************** JNI-functions for calling static methods **********************/
2044 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2047 STATS(jniinvokation();)
2049 m = class_resolvemethod(clazz,
2050 utf_new_char((char *) name),
2051 utf_new_char((char *) sig));
2053 if (!m || !(m->flags & ACC_STATIC)) {
2055 new_exception_message(string_java_lang_NoSuchMethodError, name);
2064 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2068 STATS(jniinvokation();)
2070 /* log_text("JNI-Call: CallStaticObjectMethod");*/
2072 va_start(vaargs, methodID);
2073 ret = callObjectMethod(0, methodID, vaargs);
2080 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2082 STATS(jniinvokation();)
2083 /* log_text("JNI-Call: CallStaticObjectMethodV"); */
2085 return callObjectMethod(0,methodID,args);
2089 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2091 STATS(jniinvokation();)
2092 log_text("JNI-Call: CallStaticObjectMethodA");
2098 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2102 STATS(jniinvokation();)
2104 va_start(vaargs, methodID);
2105 ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
2112 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2114 STATS(jniinvokation();)
2115 return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
2119 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2121 STATS(jniinvokation();)
2122 log_text("JNI-Call: CallStaticBooleanMethodA");
2128 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2132 STATS(jniinvokation();)
2134 /* log_text("JNI-Call: CallStaticByteMethod");*/
2136 va_start(vaargs, methodID);
2137 ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
2144 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2146 STATS(jniinvokation();)
2147 return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
2151 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2153 STATS(jniinvokation();)
2154 log_text("JNI-Call: CallStaticByteMethodA");
2160 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2164 STATS(jniinvokation();)
2166 /* log_text("JNI-Call: CallStaticByteMethod");*/
2168 va_start(vaargs, methodID);
2169 ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
2176 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2178 STATS(jniinvokation();)
2179 return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
2183 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2185 STATS(jniinvokation();)
2186 log_text("JNI-Call: CallStaticCharMethodA");
2193 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2197 STATS(jniinvokation();)
2199 /* log_text("JNI-Call: CallStaticByteMethod");*/
2201 va_start(vaargs, methodID);
2202 ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
2209 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2211 STATS(jniinvokation();)
2212 /*log_text("JNI-Call: CallStaticShortMethodV");*/
2213 return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
2217 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2219 STATS(jniinvokation();)
2220 log_text("JNI-Call: CallStaticShortMethodA");
2227 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2231 STATS(jniinvokation();)
2233 /* log_text("JNI-Call: CallStaticIntMethod");*/
2235 va_start(vaargs, methodID);
2236 ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
2243 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2245 STATS(jniinvokation();)
2246 log_text("JNI-Call: CallStaticIntMethodV");
2248 return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
2252 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2254 STATS(jniinvokation();)
2255 log_text("JNI-Call: CallStaticIntMethodA");
2262 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2266 STATS(jniinvokation();)
2268 /* log_text("JNI-Call: CallStaticLongMethod");*/
2270 va_start(vaargs, methodID);
2271 ret = callLongMethod(0, methodID, vaargs);
2278 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2280 STATS(jniinvokation();)
2281 log_text("JNI-Call: CallStaticLongMethodV");
2283 return callLongMethod(0,methodID,args);
2287 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2289 STATS(jniinvokation();)
2290 log_text("JNI-Call: CallStaticLongMethodA");
2297 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2301 STATS(jniinvokation();)
2303 /* log_text("JNI-Call: CallStaticLongMethod");*/
2305 va_start(vaargs, methodID);
2306 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
2313 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2315 STATS(jniinvokation();)
2317 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
2322 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2324 STATS(jniinvokation();)
2325 log_text("JNI-Call: CallStaticFloatMethodA");
2332 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2336 STATS(jniinvokation();)
2338 /* log_text("JNI-Call: CallStaticDoubleMethod");*/
2340 va_start(vaargs,methodID);
2341 ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
2348 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2350 STATS(jniinvokation();)
2351 log_text("JNI-Call: CallStaticDoubleMethodV");
2353 return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
2357 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2359 STATS(jniinvokation();)
2360 log_text("JNI-Call: CallStaticDoubleMethodA");
2366 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2369 STATS(jniinvokation();)
2371 va_start(vaargs, methodID);
2372 (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
2377 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2379 log_text("JNI-Call: CallStaticVoidMethodV");
2380 STATS(jniinvokation();)
2381 (void)callIntegerMethod(0, methodID, TYPE_VOID, args);
2385 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2387 STATS(jniinvokation();)
2388 log_text("JNI-Call: CallStaticVoidMethodA");
2392 /* Accessing Static Fields ****************************************************/
2394 /* GetStaticFieldID ************************************************************
2396 Returns the field ID for a static field of a class. The field is
2397 specified by its name and signature. The GetStatic<type>Field and
2398 SetStatic<type>Field families of accessor functions use field IDs
2399 to retrieve static fields.
2401 *******************************************************************************/
2403 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2406 STATS(jniinvokation();)
2408 f = jclass_findfield(clazz,
2409 utf_new_char((char *) name),
2410 utf_new_char((char *) sig));
2413 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2419 /* GetStatic<type>Field ********************************************************
2421 This family of accessor routines returns the value of a static
2424 *******************************************************************************/
2426 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2428 STATS(jniinvokation();)
2429 JWCLINITDEBUG(printf("GetStaticObjectField: calling initialize_class %s\n",clazz->name->text);)
2430 if (!initialize_class(clazz))
2433 return fieldID->value.a;
2437 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2439 STATS(jniinvokation();)
2440 JWCLINITDEBUG(printf("GetStaticBooleanField: calling initialize_class %s\n",clazz->name->text);)
2442 if (!initialize_class(clazz))
2445 return fieldID->value.i;
2449 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2451 STATS(jniinvokation();)
2452 JWCLINITDEBUG(printf("GetStaticByteField: calling initialize_class %s\n",clazz->name->text);)
2454 if (!initialize_class(clazz))
2457 return fieldID->value.i;
2461 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2463 STATS(jniinvokation();)
2464 JWCLINITDEBUG(printf("GetStaticCharField: calling initialize_class %s\n",clazz->name->text);)
2466 if (!initialize_class(clazz))
2469 return fieldID->value.i;
2473 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2475 STATS(jniinvokation();)
2476 JWCLINITDEBUG(printf("GetStaticShorttField: calling initialize_class %s\n",clazz->name->text);)
2477 if (!initialize_class(clazz))
2480 return fieldID->value.i;
2484 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2486 STATS(jniinvokation();)
2487 JWCLINITDEBUG(printf("GetStaticIntField: calling initialize_class %s\n",clazz->name->text);)
2488 if (!initialize_class(clazz))
2491 return fieldID->value.i;
2495 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2497 STATS(jniinvokation();)
2498 JWCLINITDEBUG(printf("GetStaticLongField: calling initialize_class %s\n",clazz->name->text);)
2499 if (!initialize_class(clazz))
2502 return fieldID->value.l;
2506 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2508 STATS(jniinvokation();)
2509 JWCLINITDEBUG(printf("GetStaticFloatField: calling initialize_class %s\n",clazz->name->text);)
2510 if (!initialize_class(clazz))
2513 return fieldID->value.f;
2517 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2519 STATS(jniinvokation();)
2520 JWCLINITDEBUG(printf("GetStaticDoubleField: calling initialize_class %s\n",clazz->name->text);)
2521 if (!initialize_class(clazz))
2524 return fieldID->value.d;
2528 /* SetStatic<type>Field *******************************************************
2530 This family of accessor routines sets the value of a static field
2533 *******************************************************************************/
2535 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2537 STATS(jniinvokation();)
2538 JWCLINITDEBUG(printf("SetStaticObjectField: calling initialize_class %s\n",clazz->name->text);)
2539 if (!initialize_class(clazz))
2542 fieldID->value.a = value;
2546 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2548 STATS(jniinvokation();)
2549 JWCLINITDEBUG(printf("SetStaticBooleanField: calling initialize_class %s\n",clazz->name->text);)
2550 if (!initialize_class(clazz))
2553 fieldID->value.i = value;
2557 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2559 STATS(jniinvokation();)
2560 JWCLINITDEBUG(printf("SetStaticByteField: calling initialize_class %s\n",clazz->name->text);)
2561 if (!initialize_class(clazz))
2564 fieldID->value.i = value;
2568 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2570 STATS(jniinvokation();)
2571 JWCLINITDEBUG(printf("SetStaticCharField: calling initialize_class %s\n",clazz->name->text);)
2572 if (!initialize_class(clazz))
2575 fieldID->value.i = value;
2579 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2581 STATS(jniinvokation();)
2582 JWCLINITDEBUG(printf("SetStaticShortField: calling initialize_class %s\n",clazz->name->text);)
2583 if (!initialize_class(clazz))
2586 fieldID->value.i = value;
2590 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2592 STATS(jniinvokation();)
2593 JWCLINITDEBUG(printf("SetStaticIntField: calling initialize_class %s\n",clazz->name->text);)
2594 if (!initialize_class(clazz))
2597 fieldID->value.i = value;
2601 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2603 STATS(jniinvokation();)
2604 JWCLINITDEBUG(printf("SetStaticLongField: calling initialize_class %s\n",clazz->name->text);)
2605 if (!initialize_class(clazz))
2608 fieldID->value.l = value;
2612 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2614 STATS(jniinvokation();)
2615 JWCLINITDEBUG(printf("SetStaticFloatField: calling initialize_class %s\n",clazz->name->text);)
2616 if (!initialize_class(clazz))
2619 fieldID->value.f = value;
2623 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2625 STATS(jniinvokation();)
2626 JWCLINITDEBUG(printf("SetStaticDoubleField: calling initialize_class %s\n",clazz->name->text);)
2627 if (!initialize_class(clazz))
2630 fieldID->value.d = value;
2634 /* String Operations **********************************************************/
2636 /* NewString *******************************************************************
2638 Create new java.lang.String object from an array of Unicode
2641 *******************************************************************************/
2643 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
2645 java_lang_String *s;
2649 STATS(jniinvokation();)
2651 s = (java_lang_String *) builtin_new(class_java_lang_String);
2652 a = builtin_newarray_char(len);
2654 /* javastring or characterarray could not be created */
2659 for (i = 0; i < len; i++)
2660 a->data[i] = buf[i];
2670 static jchar emptyStringJ[]={0,0};
2672 /* GetStringLength *************************************************************
2674 Returns the length (the count of Unicode characters) of a Java
2677 *******************************************************************************/
2679 jsize GetStringLength(JNIEnv *env, jstring str)
2681 return ((java_lang_String *) str)->count;
2685 /******************** convertes javastring to u2-array ****************************/
2687 u2 *javastring_tou2(jstring so)
2689 java_lang_String *s;
2694 STATS(jniinvokation();)
2696 s = (java_lang_String *) so;
2706 /* allocate memory */
2708 stringbuffer = MNEW(u2, s->count + 1);
2712 for (i = 0; i < s->count; i++)
2713 stringbuffer[i] = a->data[s->offset + i];
2715 /* terminate string */
2717 stringbuffer[i] = '\0';
2719 return stringbuffer;
2723 /* GetStringChars **************************************************************
2725 Returns a pointer to the array of Unicode characters of the
2726 string. This pointer is valid until ReleaseStringchars() is called.
2728 *******************************************************************************/
2730 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2734 STATS(jniinvokation();)
2736 jc = javastring_tou2(str);
2748 return emptyStringJ;
2752 /* ReleaseStringChars **********************************************************
2754 Informs the VM that the native code no longer needs access to
2755 chars. The chars argument is a pointer obtained from string using
2758 *******************************************************************************/
2760 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2762 STATS(jniinvokation();)
2764 if (chars == emptyStringJ)
2767 MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
2771 /* NewStringUTF ****************************************************************
2773 Constructs a new java.lang.String object from an array of UTF-8 characters.
2775 *******************************************************************************/
2777 jstring NewStringUTF(JNIEnv *env, const char *bytes)
2779 STATS(jniinvokation();)
2780 return (jstring) javastring_new(utf_new_char(bytes));
2784 /****************** returns the utf8 length in bytes of a string *******************/
2786 jsize GetStringUTFLength (JNIEnv *env, jstring string)
2788 java_lang_String *s = (java_lang_String*) string;
2789 STATS(jniinvokation();)
2791 return (jsize) u2_utflength(s->value->data, s->count);
2795 /* GetStringUTFChars ***********************************************************
2797 Returns a pointer to an array of UTF-8 characters of the
2798 string. This array is valid until it is released by
2799 ReleaseStringUTFChars().
2801 *******************************************************************************/
2803 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
2806 STATS(jniinvokation();)
2814 u = javastring_toutf((java_lang_String *) string, false);
2823 /* ReleaseStringUTFChars *******************************************************
2825 Informs the VM that the native code no longer needs access to
2826 utf. The utf argument is a pointer derived from string using
2827 GetStringUTFChars().
2829 *******************************************************************************/
2831 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2833 STATS(jniinvokation();)
2835 /* XXX we don't release utf chars right now, perhaps that should be done
2836 later. Since there is always one reference the garbage collector will
2841 /* Array Operations ***********************************************************/
2843 /* GetArrayLength **************************************************************
2845 Returns the number of elements in the array.
2847 *******************************************************************************/
2849 jsize GetArrayLength(JNIEnv *env, jarray array)
2851 STATS(jniinvokation();)
2857 /* NewObjectArray **************************************************************
2859 Constructs a new array holding objects in class elementClass. All
2860 elements are initially set to initialElement.
2862 *******************************************************************************/
2864 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
2866 java_objectarray *oa;
2868 STATS(jniinvokation();)
2871 *exceptionptr = new_negativearraysizeexception();
2875 oa = builtin_anewarray(length, elementClass);
2880 /* set all elements to initialElement */
2882 for (i = 0; i < length; i++)
2883 oa->data[i] = initialElement;
2889 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
2892 STATS(jniinvokation();)
2894 if (index < array->header.size)
2895 j = array->data[index];
2897 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2903 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
2905 STATS(jniinvokation();)
2906 if (index >= array->header.size)
2907 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2910 /* check if the class of value is a subclass of the element class of the array */
2911 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
2912 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
2915 array->data[index] = val;
2921 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
2923 java_booleanarray *j;
2924 STATS(jniinvokation();)
2927 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2931 j = builtin_newarray_boolean(len);
2937 jbyteArray NewByteArray(JNIEnv *env, jsize len)
2940 STATS(jniinvokation();)
2943 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2947 j = builtin_newarray_byte(len);
2953 jcharArray NewCharArray(JNIEnv *env, jsize len)
2956 STATS(jniinvokation();)
2959 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2963 j = builtin_newarray_char(len);
2969 jshortArray NewShortArray(JNIEnv *env, jsize len)
2972 STATS(jniinvokation();)
2975 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2979 j = builtin_newarray_short(len);
2985 jintArray NewIntArray(JNIEnv *env, jsize len)
2988 STATS(jniinvokation();)
2991 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2995 j = builtin_newarray_int(len);
3001 jlongArray NewLongArray(JNIEnv *env, jsize len)
3004 STATS(jniinvokation();)
3007 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
3011 j = builtin_newarray_long(len);
3017 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3020 STATS(jniinvokation();)
3023 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
3027 j = builtin_newarray_float(len);
3033 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3035 java_doublearray *j;
3036 STATS(jniinvokation();)
3039 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
3043 j = builtin_newarray_double(len);
3049 /* Get<PrimitiveType>ArrayElements *********************************************
3051 A family of functions that returns the body of the primitive array.
3053 *******************************************************************************/
3055 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3058 STATS(jniinvokation();)
3061 *isCopy = JNI_FALSE;
3067 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3069 STATS(jniinvokation();)
3072 *isCopy = JNI_FALSE;
3078 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3080 STATS(jniinvokation();)
3083 *isCopy = JNI_FALSE;
3089 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3091 STATS(jniinvokation();)
3094 *isCopy = JNI_FALSE;
3100 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3102 STATS(jniinvokation();)
3105 *isCopy = JNI_FALSE;
3111 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3113 STATS(jniinvokation();)
3116 *isCopy = JNI_FALSE;
3122 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3124 STATS(jniinvokation();)
3127 *isCopy = JNI_FALSE;
3133 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3136 STATS(jniinvokation();)
3139 *isCopy = JNI_FALSE;
3145 /* Release<PrimitiveType>ArrayElements *****************************************
3147 A family of functions that informs the VM that the native code no
3148 longer needs access to elems. The elems argument is a pointer
3149 derived from array using the corresponding
3150 Get<PrimitiveType>ArrayElements() function. If necessary, this
3151 function copies back all changes made to elems to the original
3154 *******************************************************************************/
3156 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3157 jboolean *elems, jint mode)
3159 STATS(jniinvokation();)
3161 if (elems != array->data) {
3164 MCOPY(array->data, elems, jboolean, array->header.size);
3167 MCOPY(array->data, elems, jboolean, array->header.size);
3168 /* XXX TWISTI how should it be freed? */
3171 /* XXX TWISTI how should it be freed? */
3178 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
3181 STATS(jniinvokation();)
3183 if (elems != array->data) {
3186 MCOPY(array->data, elems, jboolean, array->header.size);
3189 MCOPY(array->data, elems, jboolean, array->header.size);
3190 /* XXX TWISTI how should it be freed? */
3193 /* XXX TWISTI how should it be freed? */
3200 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
3203 STATS(jniinvokation();)
3205 if (elems != array->data) {
3208 MCOPY(array->data, elems, jboolean, array->header.size);
3211 MCOPY(array->data, elems, jboolean, array->header.size);
3212 /* XXX TWISTI how should it be freed? */
3215 /* XXX TWISTI how should it be freed? */
3222 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
3225 STATS(jniinvokation();)
3227 if (elems != array->data) {
3230 MCOPY(array->data, elems, jboolean, array->header.size);
3233 MCOPY(array->data, elems, jboolean, array->header.size);
3234 /* XXX TWISTI how should it be freed? */
3237 /* XXX TWISTI how should it be freed? */
3244 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
3247 STATS(jniinvokation();)
3249 if (elems != array->data) {
3252 MCOPY(array->data, elems, jboolean, array->header.size);
3255 MCOPY(array->data, elems, jboolean, array->header.size);
3256 /* XXX TWISTI how should it be freed? */
3259 /* XXX TWISTI how should it be freed? */
3266 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
3269 STATS(jniinvokation();)
3271 if (elems != array->data) {
3274 MCOPY(array->data, elems, jboolean, array->header.size);
3277 MCOPY(array->data, elems, jboolean, array->header.size);
3278 /* XXX TWISTI how should it be freed? */
3281 /* XXX TWISTI how should it be freed? */
3288 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
3291 STATS(jniinvokation();)
3293 if (elems != array->data) {
3296 MCOPY(array->data, elems, jboolean, array->header.size);
3299 MCOPY(array->data, elems, jboolean, array->header.size);
3300 /* XXX TWISTI how should it be freed? */
3303 /* XXX TWISTI how should it be freed? */
3310 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3311 jdouble *elems, jint mode)
3313 STATS(jniinvokation();)
3315 if (elems != array->data) {
3318 MCOPY(array->data, elems, jboolean, array->header.size);
3321 MCOPY(array->data, elems, jboolean, array->header.size);
3322 /* XXX TWISTI how should it be freed? */
3325 /* XXX TWISTI how should it be freed? */
3332 /* Get<PrimitiveType>ArrayRegion **********************************************
3334 A family of functions that copies a region of a primitive array
3337 *******************************************************************************/
3339 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3340 jsize len, jboolean *buf)
3342 STATS(jniinvokation();)
3344 if (start < 0 || len < 0 || start + len > array->header.size)
3346 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3349 MCOPY(buf, &array->data[start], jboolean, len);
3353 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3356 STATS(jniinvokation();)
3358 if (start < 0 || len < 0 || start + len > array->header.size)
3360 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3363 MCOPY(buf, &array->data[start], jbyte, len);
3367 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3370 STATS(jniinvokation();)
3372 if (start < 0 || len < 0 || start + len > array->header.size)
3374 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3377 MCOPY(buf, &array->data[start], jchar, len);
3381 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3382 jsize len, jshort *buf)
3384 STATS(jniinvokation();)
3386 if (start < 0 || len < 0 || start + len > array->header.size)
3388 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3391 MCOPY(buf, &array->data[start], jshort, len);
3395 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3398 STATS(jniinvokation();)
3400 if (start < 0 || len < 0 || start + len > array->header.size)
3402 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3405 MCOPY(buf, &array->data[start], jint, len);
3409 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
3412 STATS(jniinvokation();)
3414 if (start < 0 || len < 0 || start + len > array->header.size)
3416 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3419 MCOPY(buf, &array->data[start], jlong, len);
3423 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3424 jsize len, jfloat *buf)
3426 STATS(jniinvokation();)
3428 if (start < 0 || len < 0 || start + len > array->header.size)
3430 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3433 MCOPY(buf, &array->data[start], jfloat, len);
3437 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3438 jsize len, jdouble *buf)
3440 STATS(jniinvokation();)
3442 if (start < 0 || len < 0 || start+len>array->header.size)
3444 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3447 MCOPY(buf, &array->data[start], jdouble, len);
3451 /* Set<PrimitiveType>ArrayRegion **********************************************
3453 A family of functions that copies back a region of a primitive
3454 array from a buffer.
3456 *******************************************************************************/
3458 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3459 jsize len, jboolean *buf)
3461 STATS(jniinvokation();)
3463 if (start < 0 || len < 0 || start + len > array->header.size)
3465 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3468 MCOPY(&array->data[start], buf, jboolean, len);
3472 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3475 STATS(jniinvokation();)
3477 if (start < 0 || len < 0 || start + len > array->header.size)
3479 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3482 MCOPY(&array->data[start], buf, jbyte, len);
3486 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3489 STATS(jniinvokation();)
3491 if (start < 0 || len < 0 || start + len > array->header.size)
3493 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3496 MCOPY(&array->data[start], buf, jchar, len);
3501 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3502 jsize len, jshort *buf)
3504 STATS(jniinvokation();)
3506 if (start < 0 || len < 0 || start + len > array->header.size)
3508 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3511 MCOPY(&array->data[start], buf, jshort, len);
3515 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3518 STATS(jniinvokation();)
3520 if (start < 0 || len < 0 || start + len > array->header.size)
3522 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3525 MCOPY(&array->data[start], buf, jint, len);
3530 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
3533 STATS(jniinvokation();)
3535 if (start < 0 || len < 0 || start + len > array->header.size)
3537 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3540 MCOPY(&array->data[start], buf, jlong, len);
3545 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3546 jsize len, jfloat *buf)
3548 STATS(jniinvokation();)
3550 if (start < 0 || len < 0 || start + len > array->header.size)
3552 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3555 MCOPY(&array->data[start], buf, jfloat, len);
3560 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3561 jsize len, jdouble *buf)
3563 STATS(jniinvokation();)
3565 if (start < 0 || len < 0 || start + len > array->header.size)
3567 new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3570 MCOPY(&array->data[start], buf, jdouble, len);
3574 /* Registering Native Methods *************************************************/
3576 /* RegisterNatives *************************************************************
3578 Registers native methods with the class specified by the clazz
3579 argument. The methods parameter specifies an array of
3580 JNINativeMethod structures that contain the names, signatures, and
3581 function pointers of the native methods. The nMethods parameter
3582 specifies the number of native methods in the array.
3584 *******************************************************************************/
3586 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
3589 STATS(jniinvokation();)
3591 log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
3597 /* UnregisterNatives ***********************************************************
3599 Unregisters native methods of a class. The class goes back to the
3600 state before it was linked or registered with its native method
3603 This function should not be used in normal native code. Instead, it
3604 provides special programs a way to reload and relink native
3607 *******************************************************************************/
3609 jint UnregisterNatives(JNIEnv *env, jclass clazz)
3611 STATS(jniinvokation();)
3613 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3615 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3621 /* Monitor Operations *********************************************************/
3623 /* MonitorEnter ****************************************************************
3625 Enters the monitor associated with the underlying Java object
3628 *******************************************************************************/
3630 jint MonitorEnter(JNIEnv *env, jobject obj)
3632 STATS(jniinvokation();)
3634 *exceptionptr = new_nullpointerexception();
3638 #if defined(USE_THREADS)
3639 builtin_monitorenter(obj);
3646 /* MonitorExit *****************************************************************
3648 The current thread must be the owner of the monitor associated with
3649 the underlying Java object referred to by obj. The thread
3650 decrements the counter indicating the number of times it has
3651 entered this monitor. If the value of the counter becomes zero, the
3652 current thread releases the monitor.
3654 *******************************************************************************/
3656 jint MonitorExit(JNIEnv *env, jobject obj)
3658 STATS(jniinvokation();)
3660 *exceptionptr = new_nullpointerexception();
3664 #if defined(USE_THREADS)
3665 builtin_monitorexit(obj);
3672 /* JavaVM Interface ***********************************************************/
3674 /* GetJavaVM *******************************************************************
3676 Returns the Java VM interface (used in the Invocation API)
3677 associated with the current thread. The result is placed at the
3678 location pointed to by the second argument, vm.
3680 *******************************************************************************/
3682 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
3684 STATS(jniinvokation();)
3691 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3693 STATS(jniinvokation();)
3694 log_text("JNI-Call: GetStringRegion");
3698 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3700 STATS(jniinvokation();)
3701 log_text("JNI-Call: GetStringUTFRegion");
3705 /* GetPrimitiveArrayCritical ***************************************************
3707 Obtain a direct pointer to array elements.
3709 *******************************************************************************/
3711 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3713 java_objectheader *s;
3714 arraydescriptor *desc;
3716 STATS(jniinvokation();)
3718 s = (java_objectheader *) array;
3719 desc = s->vftbl->arraydesc;
3725 *isCopy = JNI_FALSE;
3727 /* TODO add to global refs */
3729 return ((u1 *) s) + desc->dataoffset;
3733 /* ReleasePrimitiveArrayCritical ***********************************************
3735 No specific documentation.
3737 *******************************************************************************/
3739 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
3742 STATS(jniinvokation();)
3744 log_text("JNI-Call: ReleasePrimitiveArrayCritical: IMPLEMENT ME!!!");
3746 /* TODO remove from global refs */
3750 /* GetStringCritical ***********************************************************
3752 The semantics of these two functions are similar to the existing
3753 Get/ReleaseStringChars functions.
3755 *******************************************************************************/
3757 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
3759 STATS(jniinvokation();)
3761 return GetStringChars(env, string, isCopy);
3765 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
3767 STATS(jniinvokation();)
3769 ReleaseStringChars(env, string, cstring);
3773 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3775 STATS(jniinvokation();)
3776 log_text("JNI-Call: NewWeakGlobalRef");
3782 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
3784 STATS(jniinvokation();)
3785 log_text("JNI-Call: DeleteWeakGlobalRef");
3791 /** Creates a new global reference to the object referred to by the obj argument **/
3793 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
3798 STATS(jniinvokation();)
3800 MonitorEnter(env, *global_ref_table);
3802 refcount = CallObjectMethod(env, *global_ref_table, getmid, lobj);
3803 val = (refcount == NULL) ? 0 : CallIntMethod(env, refcount, intvalue);
3804 newval = NewObject(env, intclass, newint, val + 1);
3806 if (newval != NULL) {
3807 CallObjectMethod(env, *global_ref_table, putmid, lobj, newval);
3808 MonitorExit(env, *global_ref_table);
3812 log_text("JNI-NewGlobalRef: unable to create new java.lang.Integer");
3813 MonitorExit(env, *global_ref_table);
3818 /************* Deletes the global reference pointed to by globalRef **************/
3820 void DeleteGlobalRef(JNIEnv* env, jobject gref)
3824 STATS(jniinvokation();)
3826 MonitorEnter(env, *global_ref_table);
3827 refcount = CallObjectMethod(env, *global_ref_table, getmid, gref);
3829 if (refcount == NULL) {
3830 log_text("JNI-DeleteGlobalRef: unable to find global reference");
3834 val = CallIntMethod(env, refcount, intvalue);
3838 CallObjectMethod(env, *global_ref_table, removemid,refcount);
3841 jobject newval = NewObject(env, intclass, newint, val);
3843 if (newval != NULL) {
3844 CallObjectMethod(env,*global_ref_table, putmid, gref, newval);
3847 log_text("JNI-DeleteGlobalRef: unable to create new java.lang.Integer");
3851 MonitorExit(env,*global_ref_table);
3855 /* ExceptionCheck **************************************************************
3857 Returns JNI_TRUE when there is a pending exception; otherwise,
3860 *******************************************************************************/
3862 jboolean ExceptionCheck(JNIEnv *env)
3864 STATS(jniinvokation();)
3865 return *exceptionptr ? JNI_TRUE : JNI_FALSE;
3869 /* New JNI 1.4 functions ******************************************************/
3871 /* NewDirectByteBuffer *********************************************************
3873 Allocates and returns a direct java.nio.ByteBuffer referring to the
3874 block of memory starting at the memory address address and
3875 extending capacity bytes.
3877 *******************************************************************************/
3879 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3881 STATS(jniinvokation();)
3882 log_text("NewDirectByteBuffer: IMPLEMENT ME!");
3888 /* GetDirectBufferAddress ******************************************************
3890 Fetches and returns the starting address of the memory region
3891 referenced by the given direct java.nio.Buffer.
3893 *******************************************************************************/
3895 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
3897 STATS(jniinvokation();)
3898 log_text("GetDirectBufferAddress: IMPLEMENT ME!");
3904 /* GetDirectBufferCapacity *****************************************************
3906 Fetches and returns the capacity in bytes of the memory region
3907 referenced by the given direct java.nio.Buffer.
3909 *******************************************************************************/
3911 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3913 STATS(jniinvokation();)
3914 log_text("GetDirectBufferCapacity: IMPLEMENT ME!");
3920 jint DestroyJavaVM(JavaVM *vm)
3922 STATS(jniinvokation();)
3923 log_text("DestroyJavaVM called");
3929 /* AttachCurrentThread *********************************************************
3931 Attaches the current thread to a Java VM. Returns a JNI interface
3932 pointer in the JNIEnv argument.
3934 Trying to attach a thread that is already attached is a no-op.
3936 A native thread cannot be attached simultaneously to two Java VMs.
3938 When a thread is attached to the VM, the context class loader is
3939 the bootstrap loader.
3941 *******************************************************************************/
3943 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
3945 STATS(jniinvokation();)
3947 log_text("AttachCurrentThread called");
3949 #if !defined(HAVE___THREAD)
3950 /* cacao_thread_attach();*/
3952 #error "No idea how to implement that. Perhaps Stefan knows"
3961 jint DetachCurrentThread(JavaVM *vm)
3963 STATS(jniinvokation();)
3964 log_text("DetachCurrentThread called");
3970 /* GetEnv **********************************************************************
3972 If the current thread is not attached to the VM, sets *env to NULL,
3973 and returns JNI_EDETACHED. If the specified version is not
3974 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3975 sets *env to the appropriate interface, and returns JNI_OK.
3977 *******************************************************************************/
3979 jint GetEnv(JavaVM *vm, void **env, jint version)
3981 STATS(jniinvokation();)
3983 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3984 if (thread_getself() == NULL) {
3987 return JNI_EDETACHED;
3991 if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
3992 (version == JNI_VERSION_1_4)) {
3998 #if defined(ENABLE_JVMTI)
3999 if (version == JVMTI_VERSION_1_0) {
4000 *env = (void *) new_jvmtienv();
4009 return JNI_EVERSION;
4014 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4016 STATS(jniinvokation();)
4017 log_text("AttachCurrentThreadAsDaemon called");
4022 /************* JNI Initialization ****************************************************/
4024 jobject jni_init1(JNIEnv* env, jobject lobj) {
4025 #if defined(USE_THREADS)
4026 while (initrunning) {yieldThread();} /* wait until init is done */
4028 if (global_ref_table == NULL) {
4031 #if defined(USE_THREADS)
4033 /* wait until jni_init is done */
4034 MonitorEnter(env, *global_ref_table) ;
4035 MonitorExit(env, *global_ref_table);
4038 return NewGlobalRef(env, lobj);
4040 void jni_init2(JNIEnv* env, jobject gref) {
4041 log_text("DeleteGlobalref called before NewGlobalref");
4042 #if defined(USE_THREADS)
4043 while (initrunning) {yieldThread();} /* wait until init is done */
4045 if (global_ref_table == NULL) {
4048 #if defined(USE_THREADS)
4050 /* wait until jni_init is done */
4051 MonitorEnter(env, *global_ref_table) ;
4052 MonitorExit(env, *global_ref_table);
4055 DeleteGlobalRef(env, gref);
4065 /* initalize global reference table */
4066 ihmclass = FindClass(NULL, "java/util/IdentityHashMap");
4068 if (ihmclass == NULL) {
4069 log_text("JNI-Init: unable to find java.util.IdentityHashMap");
4072 mid = GetMethodID(NULL, ihmclass, "<init>","()V");
4074 log_text("JNI-Init: unable to find constructor in java.util.IdentityHashMap");
4077 global_ref_table = (jobject*)heap_allocate(sizeof(jobject),true,NULL);
4079 *global_ref_table = NewObject(NULL,ihmclass,mid);
4081 if (*global_ref_table == NULL) {
4082 log_text("JNI-Init: unable to create new global_ref_table");
4085 initrunning = false;
4087 getmid = GetMethodID(NULL, ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
4089 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
4092 getmid = GetMethodID(NULL ,ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
4093 if (getmid == NULL) {
4094 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
4097 putmid = GetMethodID(NULL, ihmclass, "put","(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
4098 if (putmid == NULL) {
4099 log_text("JNI-Init: unable to find method \"put\" in java.util.IdentityHashMap");
4102 intclass = FindClass(NULL, "java/lang/Integer");
4103 if (intclass == NULL) {
4104 log_text("JNI-Init: unable to find java.lang.Integer");
4107 newint = GetMethodID(NULL, intclass, "<init>","(I)V");
4108 if (newint == NULL) {
4109 log_text("JNI-Init: unable to find constructor in java.lang.Integer");
4112 intvalue = GetMethodID(NULL, intclass, "intValue","()I");
4113 if (intvalue == NULL) {
4114 log_text("JNI-Init: unable to find method \"intValue\" in java.lang.Integer");
4117 removemid = GetMethodID(NULL, ihmclass, "remove","(Ljava/lang/Object;)Ljava/lang/Object;");
4118 if (removemid == NULL) {
4119 log_text("JNI-DeleteGlobalRef: unable to find method \"remove\" in java.lang.Object");
4122 /* set NewGlobalRef, DeleteGlobalRef envTable entry to real implementation */
4124 JNI_JNIEnvTable.NewGlobalRef = &NewGlobalRef;
4125 JNI_JNIEnvTable.DeleteGlobalRef = &DeleteGlobalRef;
4129 /* JNI invocation table *******************************************************/
4131 const struct JNIInvokeInterface JNI_JavaVMTable = {
4137 AttachCurrentThread,
4138 DetachCurrentThread,
4140 AttachCurrentThreadAsDaemon
4144 /* JNI function table *********************************************************/
4146 struct JNINativeInterface JNI_JNIEnvTable = {
4155 &FromReflectedMethod,
4156 &FromReflectedField,
4171 &jni_init1, /* &NewGlobalRef, initialize Global_Ref_Table*/
4172 &jni_init2, /* &DeleteGlobalRef,*/
4176 &EnsureLocalCapacity,
4192 &CallBooleanMethodV,
4193 &CallBooleanMethodA,
4219 &CallNonvirtualObjectMethod,
4220 &CallNonvirtualObjectMethodV,
4221 &CallNonvirtualObjectMethodA,
4222 &CallNonvirtualBooleanMethod,
4223 &CallNonvirtualBooleanMethodV,
4224 &CallNonvirtualBooleanMethodA,
4225 &CallNonvirtualByteMethod,
4226 &CallNonvirtualByteMethodV,
4227 &CallNonvirtualByteMethodA,
4228 &CallNonvirtualCharMethod,
4229 &CallNonvirtualCharMethodV,
4230 &CallNonvirtualCharMethodA,
4231 &CallNonvirtualShortMethod,
4232 &CallNonvirtualShortMethodV,
4233 &CallNonvirtualShortMethodA,
4234 &CallNonvirtualIntMethod,
4235 &CallNonvirtualIntMethodV,
4236 &CallNonvirtualIntMethodA,
4237 &CallNonvirtualLongMethod,
4238 &CallNonvirtualLongMethodV,
4239 &CallNonvirtualLongMethodA,
4240 &CallNonvirtualFloatMethod,
4241 &CallNonvirtualFloatMethodV,
4242 &CallNonvirtualFloatMethodA,
4243 &CallNonvirtualDoubleMethod,
4244 &CallNonvirtualDoubleMethodV,
4245 &CallNonvirtualDoubleMethodA,
4246 &CallNonvirtualVoidMethod,
4247 &CallNonvirtualVoidMethodV,
4248 &CallNonvirtualVoidMethodA,
4273 &CallStaticObjectMethod,
4274 &CallStaticObjectMethodV,
4275 &CallStaticObjectMethodA,
4276 &CallStaticBooleanMethod,
4277 &CallStaticBooleanMethodV,
4278 &CallStaticBooleanMethodA,
4279 &CallStaticByteMethod,
4280 &CallStaticByteMethodV,
4281 &CallStaticByteMethodA,
4282 &CallStaticCharMethod,
4283 &CallStaticCharMethodV,
4284 &CallStaticCharMethodA,
4285 &CallStaticShortMethod,
4286 &CallStaticShortMethodV,
4287 &CallStaticShortMethodA,
4288 &CallStaticIntMethod,
4289 &CallStaticIntMethodV,
4290 &CallStaticIntMethodA,
4291 &CallStaticLongMethod,
4292 &CallStaticLongMethodV,
4293 &CallStaticLongMethodA,
4294 &CallStaticFloatMethod,
4295 &CallStaticFloatMethodV,
4296 &CallStaticFloatMethodA,
4297 &CallStaticDoubleMethod,
4298 &CallStaticDoubleMethodV,
4299 &CallStaticDoubleMethodA,
4300 &CallStaticVoidMethod,
4301 &CallStaticVoidMethodV,
4302 &CallStaticVoidMethodA,
4306 &GetStaticObjectField,
4307 &GetStaticBooleanField,
4308 &GetStaticByteField,
4309 &GetStaticCharField,
4310 &GetStaticShortField,
4312 &GetStaticLongField,
4313 &GetStaticFloatField,
4314 &GetStaticDoubleField,
4315 &SetStaticObjectField,
4316 &SetStaticBooleanField,
4317 &SetStaticByteField,
4318 &SetStaticCharField,
4319 &SetStaticShortField,
4321 &SetStaticLongField,
4322 &SetStaticFloatField,
4323 &SetStaticDoubleField,
4328 &ReleaseStringChars,
4331 &GetStringUTFLength,
4333 &ReleaseStringUTFChars,
4338 &GetObjectArrayElement,
4339 &SetObjectArrayElement,
4350 &GetBooleanArrayElements,
4351 &GetByteArrayElements,
4352 &GetCharArrayElements,
4353 &GetShortArrayElements,
4354 &GetIntArrayElements,
4355 &GetLongArrayElements,
4356 &GetFloatArrayElements,
4357 &GetDoubleArrayElements,
4359 &ReleaseBooleanArrayElements,
4360 &ReleaseByteArrayElements,
4361 &ReleaseCharArrayElements,
4362 &ReleaseShortArrayElements,
4363 &ReleaseIntArrayElements,
4364 &ReleaseLongArrayElements,
4365 &ReleaseFloatArrayElements,
4366 &ReleaseDoubleArrayElements,
4368 &GetBooleanArrayRegion,
4369 &GetByteArrayRegion,
4370 &GetCharArrayRegion,
4371 &GetShortArrayRegion,
4373 &GetLongArrayRegion,
4374 &GetFloatArrayRegion,
4375 &GetDoubleArrayRegion,
4376 &SetBooleanArrayRegion,
4377 &SetByteArrayRegion,
4378 &SetCharArrayRegion,
4379 &SetShortArrayRegion,
4381 &SetLongArrayRegion,
4382 &SetFloatArrayRegion,
4383 &SetDoubleArrayRegion,
4393 /* new JNI 1.2 functions */
4396 &GetStringUTFRegion,
4398 &GetPrimitiveArrayCritical,
4399 &ReleasePrimitiveArrayCritical,
4402 &ReleaseStringCritical,
4405 &DeleteWeakGlobalRef,
4409 /* new JNI 1.4 functions */
4411 &NewDirectByteBuffer,
4412 &GetDirectBufferAddress,
4413 &GetDirectBufferCapacity
4417 /* Invocation API Functions ***************************************************/
4419 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4421 Returns a default configuration for the Java VM.
4423 *******************************************************************************/
4425 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4427 JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4429 /* GNU classpath currently supports JNI 1.2 */
4431 _vm_args->version = JNI_VERSION_1_2;
4437 /* JNI_GetCreatedJavaVMs *******************************************************
4439 Returns all Java VMs that have been created. Pointers to VMs are written in
4440 the buffer vmBuf in the order they are created. At most bufLen number of
4441 entries will be written. The total number of created VMs is returned in
4444 *******************************************************************************/
4446 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4448 log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4454 /* JNI_CreateJavaVM ************************************************************
4456 Loads and initializes a Java VM. The current thread becomes the main thread.
4457 Sets the env argument to the JNI interface pointer of the main thread.
4459 *******************************************************************************/
4461 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4463 const struct JNIInvokeInterface *vm;
4464 struct JNINativeInterface *env;
4466 vm = &JNI_JavaVMTable;
4467 env = &JNI_JNIEnvTable;
4469 *p_vm = (JavaVM *) vm;
4470 *p_env = (JNIEnv *) env;
4476 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4477 jobject obj, java_objectarray *params)
4484 if (methodID == 0) {
4485 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
4489 argcount = methodID->parseddesc->paramcount;
4490 paramcount = argcount;
4492 /* if method is non-static, remove the `this' pointer */
4494 if (!(methodID->flags & ACC_STATIC))
4497 /* the method is an instance method the obj has to be an instance of the
4498 class the method belongs to. For static methods the obj parameter
4501 if (!(methodID->flags & ACC_STATIC) && obj &&
4502 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4504 new_exception_message(string_java_lang_IllegalArgumentException,
4505 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4509 if (((params == NULL) && (paramcount != 0)) ||
4510 (params && (params->header.size != paramcount))) {
4512 new_exception(string_java_lang_IllegalArgumentException);
4517 if (!(methodID->flags & ACC_STATIC) && !obj) {
4519 new_exception_message(string_java_lang_NullPointerException,
4520 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4524 if ((methodID->flags & ACC_STATIC) && (obj))
4528 if ((methodID->flags & ACC_ABSTRACT) ||
4529 (methodID->class->flags & ACC_INTERFACE)) {
4530 methodID = get_virtual(obj, methodID);
4534 blk = MNEW(jni_callblock, argcount);
4536 if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4540 switch (methodID->parseddesc->returntype.decltype) {
4542 (void) asm_calljavafunction2(methodID, argcount,
4543 argcount * sizeof(jni_callblock),
4545 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4548 case PRIMITIVETYPE_INT: {
4550 i = asm_calljavafunction2int(methodID, argcount,
4551 argcount * sizeof(jni_callblock),
4554 o = native_new_and_init_int(class_java_lang_Integer, i);
4558 case PRIMITIVETYPE_BYTE: {
4560 i = asm_calljavafunction2int(methodID, argcount,
4561 argcount * sizeof(jni_callblock),
4564 /* o = native_new_and_init_int(class_java_lang_Byte, i); */
4565 o = builtin_new(class_java_lang_Byte);
4568 class_resolvemethod(o->vftbl->class,
4575 case PRIMITIVETYPE_CHAR: {
4577 intVal = asm_calljavafunction2int(methodID,
4579 argcount * sizeof(jni_callblock),
4581 o = builtin_new(class_java_lang_Character);
4584 class_resolvemethod(o->vftbl->class,
4591 case PRIMITIVETYPE_SHORT: {
4593 intVal = asm_calljavafunction2int(methodID,
4595 argcount * sizeof(jni_callblock),
4597 o = builtin_new(class_java_lang_Short);
4600 class_resolvemethod(o->vftbl->class,
4607 case PRIMITIVETYPE_BOOLEAN: {
4609 intVal = asm_calljavafunction2int(methodID,
4611 argcount * sizeof(jni_callblock),
4613 o = builtin_new(class_java_lang_Boolean);
4616 class_resolvemethod(o->vftbl->class,
4625 longVal = asm_calljavafunction2long(methodID,
4627 argcount * sizeof(jni_callblock),
4629 o = builtin_new(class_java_lang_Long);
4632 class_resolvemethod(o->vftbl->class,
4639 case PRIMITIVETYPE_FLOAT: {
4641 floatVal = asm_calljavafunction2float(methodID,
4643 argcount * sizeof(jni_callblock),
4645 o = builtin_new(class_java_lang_Float);
4648 class_resolvemethod(o->vftbl->class,
4655 case PRIMITIVETYPE_DOUBLE: {
4657 doubleVal = asm_calljavafunction2double(methodID,
4659 argcount * sizeof(jni_callblock),
4661 o = builtin_new(class_java_lang_Double);
4664 class_resolvemethod(o->vftbl->class,
4672 o = asm_calljavafunction2(methodID, argcount,
4673 argcount * sizeof(jni_callblock), blk);
4677 /* if this happens the exception has already been set by */
4678 /* fill_callblock_from_objectarray */
4680 MFREE(blk, jni_callblock, argcount);
4681 return (jobject *) 0;
4684 MFREE(blk, jni_callblock, argcount);
4686 if (*exceptionptr) {
4687 java_objectheader *cause;
4689 cause = *exceptionptr;
4691 /* clear exception pointer, we are calling JIT code again */
4693 *exceptionptr = NULL;
4696 new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
4697 (java_lang_Throwable *) cause);
4700 return (jobject *) o;
4705 * These are local overrides for various environment variables in Emacs.
4706 * Please do not remove this and leave it at the end of the file, where
4707 * Emacs will automagically detect them.
4708 * ---------------------------------------------------------------------
4711 * indent-tabs-mode: t