-/* native/jni.c - implementation of the Java Native Interface functions
+/* src/native/jni.c - implementation of the Java Native Interface functions
Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
Contact: cacao@complang.tuwien.ac.at
- Authors: ?
+ Authors: Rainhard Grafl
+ Roman Obermaisser
- Changes: Joseph Wenninger, Martin Platter
+ Changes: Joseph Wenninger
+ Martin Platter
+ Christian Thalinger
- $Id: jni.c 1801 2004-12-21 20:19:19Z jowenn $
+ $Id: jni.c 3668 2005-11-14 19:48:30Z twisti $
*/
+#include <assert.h>
#include <string.h>
+#include "config.h"
+
#include "mm/boehm.h"
#include "mm/memory.h"
#include "native/jni.h"
#include "native/native.h"
+
+#include "native/include/gnu_classpath_Pointer.h"
+
+#if SIZEOF_VOID_P == 8
+# include "native/include/gnu_classpath_Pointer64.h"
+#else
+# include "native/include/gnu_classpath_Pointer32.h"
+#endif
+
+#include "native/include/java_lang_Object.h"
#include "native/include/java_lang_Byte.h"
#include "native/include/java_lang_Character.h"
#include "native/include/java_lang_Short.h"
#include "native/include/java_lang_Float.h"
#include "native/include/java_lang_Double.h"
#include "native/include/java_lang_Throwable.h"
+#include "native/include/java_lang_reflect_Method.h"
+#include "native/include/java_lang_reflect_Constructor.h"
+#include "native/include/java_lang_reflect_Field.h"
+
+#include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
+#include "native/include/java_lang_VMClass.h"
+#include "native/include/java_lang_VMClassLoader.h"
+#include "native/include/java_nio_Buffer.h"
+#include "native/include/java_nio_DirectByteBufferImpl.h"
+
+#if defined(ENABLE_JVMTI)
+# include "native/jvmti/jvmti.h"
+#endif
#if defined(USE_THREADS)
# if defined(NATIVE_THREADS)
#include "vm/builtin.h"
#include "vm/exceptions.h"
#include "vm/global.h"
+#include "vm/initialize.h"
#include "vm/loader.h"
#include "vm/options.h"
+#include "vm/resolve.h"
#include "vm/statistics.h"
+#include "vm/stringlocal.h"
#include "vm/tables.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/jit.h"
+#include "vm/statistics.h"
-#define JNI_VERSION 0x00010002
+/* XXX TWISTI hack: define it extern so they can be found in this file */
+
+extern const struct JNIInvokeInterface JNI_JavaVMTable;
+extern struct JNINativeInterface JNI_JNIEnvTable;
+
+/* pointers to VM and the environment needed by GetJavaVM and GetEnv */
+
+static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
+void *ptr_env = (void*) &JNI_JNIEnvTable;
#define PTR_TO_ITEM(ptr) ((u8)(size_t)(ptr))
-static utf* utf_char = 0;
-static utf* utf_bool = 0;
-static utf* utf_byte =0;
-static utf* utf_short = 0;
-static utf* utf_int = 0;
-static utf* utf_long = 0;
-static utf* utf_float = 0;
-static utf* utf_double = 0;
+/* global variables ***********************************************************/
+
+/* global reference table *****************************************************/
-/* global reference table */
-static jobject *global_ref_table;
-static bool initrunning=false;
+static java_objectheader **global_ref_table;
/* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
-static jmethodID getmid = NULL;
-static jmethodID putmid = NULL;
-static jclass intclass = NULL;
-static jmethodID intvalue = NULL;
-static jmethodID newint = NULL;
-static jclass ihmclass = NULL;
-static jmethodID removemid = NULL;
+static classinfo *ihmclass = NULL;
+static methodinfo *putmid = NULL;
+static methodinfo *getmid = NULL;
+static methodinfo *removemid = NULL;
+
+
+/* direct buffer stuff ********************************************************/
+
+static utf *utf_java_nio_DirectByteBufferImpl;
+#if SIZEOF_VOID_P == 8
+static utf *utf_gnu_classpath_Pointer64;
+#else
+static utf *utf_gnu_classpath_Pointer32;
+#endif
+
+static classinfo *class_java_nio_DirectByteBufferImpl;
+#if SIZEOF_VOID_P == 8
+static classinfo *class_gnu_classpath_Pointer64;
+#else
+static classinfo *class_gnu_classpath_Pointer32;
+#endif
-/********************* accessing instance-fields **********************************/
+/* local reference table ******************************************************/
-#define setField(obj,typ,var,val) *((typ*) ((long int) obj + (long int) var->offset))=val;
-#define getField(obj,typ,var) *((typ*) ((long int) obj + (long int) var->offset))
-#define setfield_critical(clazz,obj,name,sig,jdatatype,val) setField(obj,jdatatype,getFieldID_critical(env,clazz,name,sig),val);
+#if !defined(USE_THREADS)
+localref_table *_no_threads_localref_table;
+#endif
+/* accessing instance fields macros *******************************************/
-u4 get_parametercount(methodinfo *m)
-{
- utf *descr = m->descriptor; /* method-descriptor */
- char *utf_ptr = descr->text; /* current position in utf-text */
- char *desc_end = utf_end(descr); /* points behind utf string */
- u4 parametercount = 0;
+#define SET_FIELD(obj,type,var,value) \
+ *((type *) ((ptrint) (obj) + (ptrint) (var)->offset)) = (type) (value)
- /* skip '(' */
- utf_nextu2(&utf_ptr);
+#define GET_FIELD(obj,type,var) \
+ *((type *) ((ptrint) (obj) + (ptrint) (var)->offset))
- /* determine number of parameters */
- while (*utf_ptr != ')') {
- get_type(&utf_ptr, desc_end, true);
- parametercount++;
- }
- return parametercount;
-}
+/* some forward declarations **************************************************/
+jobject NewLocalRef(JNIEnv *env, jobject ref);
-void fill_callblock(void *obj, utf *descr, jni_callblock blk[], va_list data, char ret)
+/* jni_init ********************************************************************
+
+ Initialize the JNI subsystem.
+
+*******************************************************************************/
+
+bool jni_init(void)
{
- char *utf__ptr = descr->text; /* current position in utf-text */
- char **utf_ptr = &utf__ptr;
- char *desc_end = utf_end(descr); /* points behind utf string */
- int cnt;
- u4 dummy;
- char c;
+ /* initalize global reference table */
- /*
- log_text("fill_callblock");
- utf_display(descr);
- log_text("====");
- */
- /* skip '(' */
- utf_nextu2(utf_ptr);
+ if (!(ihmclass =
+ load_class_bootstrap(utf_new_char("java/util/IdentityHashMap"))))
+ return false;
- /* determine number of parameters */
- if (obj) {
- blk[0].itemtype = TYPE_ADR;
- blk[0].item = PTR_TO_ITEM(obj);
- cnt = 1;
- } else cnt = 0;
-
- while (**utf_ptr != ')') {
- if (*utf_ptr >= desc_end)
- panic("illegal method descriptor");
-
- switch (utf_nextu2(utf_ptr)) {
- /* primitive types */
- case 'B':
- case 'C':
- case 'S':
- case 'Z':
- blk[cnt].itemtype = TYPE_INT;
- blk[cnt].item = (u8) va_arg(data, int);
- break;
+ global_ref_table = GCNEW(jobject, 1);
- case 'I':
- blk[cnt].itemtype = TYPE_INT;
- dummy = va_arg(data, u4);
- /*printf("fill_callblock: pos:%d, value:%d\n",cnt,dummy);*/
- blk[cnt].item = (u8) dummy;
- break;
+ if (!(*global_ref_table = native_new_and_init(ihmclass)))
+ return false;
- case 'J':
- blk[cnt].itemtype = TYPE_LNG;
- blk[cnt].item = (u8) va_arg(data, jlong);
- break;
+ if (!(getmid = class_resolvemethod(ihmclass, utf_get,
+ utf_java_lang_Object__java_lang_Object)))
+ return false;
- case 'F':
- blk[cnt].itemtype = TYPE_FLT;
- *((jfloat *) (&blk[cnt].item)) = (jfloat) va_arg(data, jdouble);
- break;
+ if (!(putmid = class_resolvemethod(ihmclass, utf_put,
+ utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))))
+ return false;
- case 'D':
- blk[cnt].itemtype = TYPE_DBL;
- *((jdouble *) (&blk[cnt].item)) = (jdouble) va_arg(data, jdouble);
- break;
+ if (!(removemid =
+ class_resolvemethod(ihmclass, utf_remove,
+ utf_java_lang_Object__java_lang_Object)))
+ return false;
- case 'V':
- panic ("V not allowed as function parameter");
- break;
-
- case 'L':
- while (utf_nextu2(utf_ptr) != ';')
- blk[cnt].itemtype = TYPE_ADR;
- blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
- break;
-
- case '[':
- {
- /* XXX */
- /* arrayclass */
-/* char *start = *utf_ptr; */
- char ch;
- while ((ch = utf_nextu2(utf_ptr)) == '[')
- if (ch == 'L') {
- while (utf_nextu2(utf_ptr) != ';') {}
- }
-
- ch = utf_nextu2(utf_ptr);
- blk[cnt].itemtype = TYPE_ADR;
- blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
- break;
- }
- }
- cnt++;
- }
- /*the standard doesn't say anything about return value checking, but it appears to be usefull*/
- c = utf_nextu2(utf_ptr);
- c = utf_nextu2(utf_ptr);
- /*printf("%c %c\n",ret,c);*/
- if (ret == 'O') {
- if (!((c == 'L') || (c == '[')))
- log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
- } else if (ret != c)
- log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
+ /* direct buffer stuff */
+
+ utf_java_nio_DirectByteBufferImpl =
+ utf_new_char("java/nio/DirectByteBufferImpl");
+
+ if (!(class_java_nio_DirectByteBufferImpl =
+ load_class_bootstrap(utf_java_nio_DirectByteBufferImpl)))
+ return false;
+
+ if (!link_class(class_java_nio_DirectByteBufferImpl))
+ return false;
+
+#if SIZEOF_VOID_P == 8
+ utf_gnu_classpath_Pointer64 = utf_new_char("gnu/classpath/Pointer64");
+
+ if (!(class_gnu_classpath_Pointer64 =
+ load_class_bootstrap(utf_gnu_classpath_Pointer64)))
+ return false;
+
+ if (!link_class(class_gnu_classpath_Pointer64))
+ return false;
+#else
+ utf_gnu_classpath_Pointer32 = utf_new_char("gnu/classpath/Pointer32");
+
+ if (!(class_gnu_classpath_Pointer32 =
+ load_class_bootstrap(utf_gnu_classpath_Pointer32)))
+ return false;
+
+ if (!link_class(class_gnu_classpath_Pointer32))
+ return false;
+#endif
+
+ return true;
}
-/* XXX it could be considered if we should do typechecking here in the future */
-char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_objectarray* params)
+static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
+ jni_callblock blk[], va_list data,
+ s4 rettype)
{
- char *utf__ptr = descr->text; /* current position in utf-text */
- char **utf_ptr = &utf__ptr;
- char *desc_end = utf_end(descr); /* points behind utf string */
+ typedesc *paramtypes;
+ s4 i;
- jobject param;
- int cnt;
- int cnts;
- char c;
+ paramtypes = descr->paramtypes;
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
- intsDisable();
-#endif
- if (utf_char==0) {
- utf_char=utf_new_char("java/lang/Character");
- utf_bool=utf_new_char("java/lang/Boolean");
- utf_byte=utf_new_char("java/lang/Byte");
- utf_short=utf_new_char("java/lang/Short");
- utf_int=utf_new_char("java/lang/Integer");
- utf_long=utf_new_char("java/lang/Long");
- utf_float=utf_new_char("java/lang/Float");
- utf_double=utf_new_char("java/lang/Double");
- }
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
- intsRestore();
-#endif
+ /* if method is non-static fill first block and skip `this' pointer */
- /*
- log_text("fill_callblock");
- utf_display(descr);
- log_text("====");
- */
- /* skip '(' */
- utf_nextu2(utf_ptr);
+ i = 0;
- /* determine number of parameters */
if (obj) {
+ /* the `this' pointer */
blk[0].itemtype = TYPE_ADR;
blk[0].item = PTR_TO_ITEM(obj);
- cnt=1;
-
- } else {
- cnt = 0;
- }
- cnts = 0;
- while (**utf_ptr != ')') {
- if (*utf_ptr >= desc_end)
- panic("illegal method descriptor");
+ paramtypes++;
+ i++;
+ }
+ for (; i < descr->paramcount; i++, paramtypes++) {
+ switch (paramtypes->decltype) {
/* primitive types */
- switch (utf_nextu2(utf_ptr)) {
- case 'B':
- param = params->data[cnts];
- if (param == 0) {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
- if (param->vftbl->class->name == utf_byte) {
- blk[cnt].itemtype = TYPE_INT;
- blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
-
- } else {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
+ case PRIMITIVETYPE_BYTE:
+ case PRIMITIVETYPE_CHAR:
+ case PRIMITIVETYPE_SHORT:
+ case PRIMITIVETYPE_BOOLEAN:
+ blk[i].itemtype = TYPE_INT;
+ blk[i].item = (s8) va_arg(data, s4);
break;
- case 'C':
- param = params->data[cnts];
- if (param == 0) {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
- if (param->vftbl->class->name == utf_char) {
- blk[cnt].itemtype = TYPE_INT;
- blk[cnt].item = (u8) ((java_lang_Character *) param)->value;
-
- } else {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
+ case PRIMITIVETYPE_INT:
+ blk[i].itemtype = TYPE_INT;
+ blk[i].item = (s8) va_arg(data, s4);
break;
- case 'S':
- param = params->data[cnts];
- if (param == 0) {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
- if (param->vftbl->class->name == utf_short) {
- blk[cnt].itemtype = TYPE_INT;
- blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
-
- } else {
- if (param->vftbl->class->name == utf_byte) {
- blk[cnt].itemtype = TYPE_INT;
- blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
-
- } else {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
- }
+ case PRIMITIVETYPE_LONG:
+ blk[i].itemtype = TYPE_LNG;
+ blk[i].item = (s8) va_arg(data, s8);
break;
- case 'Z':
- param = params->data[cnts];
- if (param == 0) {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
- if (param->vftbl->class->name == utf_bool) {
- blk[cnt].itemtype = TYPE_INT;
- blk[cnt].item = (u8) ((java_lang_Boolean *) param)->value;
-
- } else {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
- break;
+ case PRIMITIVETYPE_FLOAT:
+ blk[i].itemtype = TYPE_FLT;
+#if defined(__ALPHA__)
+ /* this keeps the assembler function much simpler */
- case 'I':
- /*log_text("fill_callblock_objA: param 'I'");*/
- param = params->data[cnts];
- if (param == 0) {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
- if (param->vftbl->class->name == utf_int) {
- blk[cnt].itemtype = TYPE_INT;
- blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
- /*printf("INT VALUE :%d\n",((struct java_lang_Integer * )param)->value);*/
- } else {
- if (param->vftbl->class->name == utf_short) {
- blk[cnt].itemtype = TYPE_INT;
- blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
-
- } else {
- if (param->vftbl->class->name == utf_byte) {
- blk[cnt].itemtype = TYPE_INT;
- blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
-
- } else {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
- }
- }
+ *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
+#else
+ *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
+#endif
break;
- case 'J':
- param = params->data[cnts];
- if (param == 0) {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
- if (param->vftbl->class->name == utf_long) {
- blk[cnt].itemtype = TYPE_LNG;
- blk[cnt].item = (u8) ((java_lang_Long *) param)->value;
-
- } else {
- if (param->vftbl->class->name == utf_int) {
- blk[cnt].itemtype = TYPE_LNG;
- blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
-
- } else {
- if (param->vftbl->class->name == utf_short) {
- blk[cnt].itemtype = TYPE_LNG;
- blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
-
- } else {
- if (param->vftbl->class->name == utf_byte) {
- blk[cnt].itemtype = TYPE_LNG;
- blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
- } else {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
- }
- }
-
- }
+ case PRIMITIVETYPE_DOUBLE:
+ blk[i].itemtype = TYPE_DBL;
+ *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
break;
- case 'F':
- param = params->data[cnts];
- if (param == 0) {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
-
- if (param->vftbl->class->name == utf_float) {
- blk[cnt].itemtype = TYPE_FLT;
- *((jfloat *) (&blk[cnt].item)) = (jfloat) ((java_lang_Float *) param)->value;
-
- } else {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
+ case TYPE_ADR:
+ blk[i].itemtype = TYPE_ADR;
+ blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
break;
+ }
+ }
- case 'D':
- param = params->data[cnts];
- if (param == 0) {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
-
- if (param->vftbl->class->name == utf_double) {
- blk[cnt].itemtype = TYPE_DBL;
- *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
-
- } else {
- if (param->vftbl->class->name == utf_float) {
- blk[cnt].itemtype = TYPE_DBL;
- *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
-
- } else {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
- }
- break;
+ /* The standard doesn't say anything about return value checking, but it */
+ /* appears to be useful. */
- case 'V':
- panic("V not allowed as function parameter");
- break;
+ if (rettype != descr->returntype.decltype)
+ log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
+}
- case 'L':
- {
- char *start = (*utf_ptr) - 1;
- /*char *end = NULL;
- while (utf_nextu2(utf_ptr) != ';')
- end = (*utf_ptr) + 1;*/
+/* XXX it could be considered if we should do typechecking here in the future */
- if (!builtin_instanceof(params->data[cnts], class_from_descriptor(start, desc_end, utf_ptr, CLASSLOAD_LOAD))) {
- if (params->data[cnts] != 0) {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
- }
- blk[cnt].itemtype = TYPE_ADR;
- blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
- break;
- }
-
- case '[':
- {
- char *start = (*utf_ptr) - 1;
- /*char *end;
-
- char ch;
- while ((ch = utf_nextu2(utf_ptr)) == '[')
- if (ch == 'L') {
- while (utf_nextu2(utf_ptr) != ';') {}
- }
+static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
+ jni_callblock blk[],
+ java_objectarray *params)
+{
+ jobject param;
+ s4 paramcount;
+ typedesc *paramtypes;
+ classinfo *c;
+ s4 i;
+ s4 j;
- end = (*utf_ptr) - 1;
- ch = utf_nextu2(utf_ptr); */
+ paramcount = descr->paramcount;
+ paramtypes = descr->paramtypes;
- if (!builtin_arrayinstanceof(params->data[cnts], class_from_descriptor(start, desc_end, utf_ptr, CLASSLOAD_LOAD)->vftbl)) {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
+ /* if method is non-static fill first block and skip `this' pointer */
- blk[cnt].itemtype = TYPE_ADR;
- blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
- break;
- }
- }
- cnt++;
- cnts++;
- }
+ i = 0;
- c = utf_nextu2(utf_ptr);
- c = utf_nextu2(utf_ptr);
- return c; /*return type needed usage of the right lowlevel methods*/
-}
+ if (obj) {
+ /* this pointer */
+ blk[0].itemtype = TYPE_ADR;
+ blk[0].item = PTR_TO_ITEM(obj);
+ paramtypes++;
+ paramcount--;
+ i++;
+ }
+ for (j = 0; j < paramcount; i++, j++, paramtypes++) {
+ switch (paramtypes->type) {
+ /* primitive types */
+ case TYPE_INT:
+ case TYPE_LONG:
+ case TYPE_FLOAT:
+ case TYPE_DOUBLE:
+ param = params->data[j];
+ if (!param)
+ goto illegal_arg;
+
+ /* internally used data type */
+ blk[i].itemtype = paramtypes->type;
+
+ /* convert the value according to its declared type */
+
+ c = param->vftbl->class;
+
+ switch (paramtypes->decltype) {
+ case PRIMITIVETYPE_BOOLEAN:
+ if (c == primitivetype_table[paramtypes->decltype].class_wrap)
+ blk[i].item = (s8) ((java_lang_Boolean *) param)->value;
+ else
+ goto illegal_arg;
+ break;
+ case PRIMITIVETYPE_BYTE:
+ if (c == primitivetype_table[paramtypes->decltype].class_wrap)
+ blk[i].item = (s8) ((java_lang_Byte *) param)->value;
+ else
+ goto illegal_arg;
+ break;
+ case PRIMITIVETYPE_CHAR:
+ if (c == primitivetype_table[paramtypes->decltype].class_wrap)
+ blk[i].item = (s8) ((java_lang_Character *) param)->value;
+ else
+ goto illegal_arg;
+ break;
+ case PRIMITIVETYPE_SHORT:
+ if (c == primitivetype_table[paramtypes->decltype].class_wrap)
+ blk[i].item = (s8) ((java_lang_Short *) param)->value;
+ else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
+ blk[i].item = (s8) ((java_lang_Byte *) param)->value;
+ else
+ goto illegal_arg;
+ break;
+ case PRIMITIVETYPE_INT:
+ if (c == primitivetype_table[paramtypes->decltype].class_wrap)
+ blk[i].item = (s8) ((java_lang_Integer *) param)->value;
+ else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
+ blk[i].item = (s8) ((java_lang_Short *) param)->value;
+ else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
+ blk[i].item = (s8) ((java_lang_Byte *) param)->value;
+ else
+ goto illegal_arg;
+ break;
+ case PRIMITIVETYPE_LONG:
+ if (c == primitivetype_table[paramtypes->decltype].class_wrap)
+ blk[i].item = (s8) ((java_lang_Long *) param)->value;
+ else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
+ blk[i].item = (s8) ((java_lang_Integer *) param)->value;
+ else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
+ blk[i].item = (s8) ((java_lang_Short *) param)->value;
+ else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
+ blk[i].item = (s8) ((java_lang_Byte *) param)->value;
+ else
+ goto illegal_arg;
+ break;
+ case PRIMITIVETYPE_FLOAT:
+ if (c == primitivetype_table[paramtypes->decltype].class_wrap)
+ *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
+ else
+ goto illegal_arg;
+ break;
+ case PRIMITIVETYPE_DOUBLE:
+ if (c == primitivetype_table[paramtypes->decltype].class_wrap)
+ *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Float *) param)->value;
+ else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
+ *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
+ else
+ goto illegal_arg;
+ break;
+ default:
+ goto illegal_arg;
+ } /* end declared type switch */
+ break;
+
+ case TYPE_ADDRESS:
+ if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
+ return false;
+
+ if (params->data[j] != 0) {
+ if (paramtypes->arraydim > 0) {
+ if (!builtin_arrayinstanceof(params->data[j], c))
+ goto illegal_arg;
+
+ } else {
+ if (!builtin_instanceof(params->data[j], c))
+ goto illegal_arg;
+ }
+ }
+ blk[i].itemtype = TYPE_ADR;
+ blk[i].item = PTR_TO_ITEM(params->data[j]);
+ break;
+ default:
+ goto illegal_arg;
+ } /* end param type switch */
+ } /* end param loop */
+/* if (rettype) */
+/* *rettype = descr->returntype.decltype; */
+ return true;
-jmethodID get_virtual(jobject obj,jmethodID methodID) {
- if (obj->vftbl->class==methodID->class) return methodID;
- return class_resolvemethod (obj->vftbl->class, methodID->name, methodID->descriptor);
+illegal_arg:
+ *exceptionptr = new_illegalargumentexception();
+ return false;
}
-jmethodID get_nonvirtual(jclass clazz,jmethodID methodID) {
- if (clazz==methodID->class) return methodID;
-/*class_resolvemethod -> classfindmethod? (JOWENN)*/
- return class_resolvemethod (clazz, methodID->name, methodID->descriptor);
+
+static jmethodID get_virtual(jobject obj, jmethodID methodID)
+{
+ if (obj->vftbl->class == methodID->class)
+ return methodID;
+
+ return class_resolvemethod(obj->vftbl->class, methodID->name,
+ methodID->descriptor);
}
+static jmethodID get_nonvirtual(jclass clazz, jmethodID methodID)
+{
+ if (clazz == methodID->class)
+ return methodID;
+
+ /* class_resolvemethod -> classfindmethod? (JOWENN) */
+ return class_resolvemethod(clazz, methodID->name, methodID->descriptor);
+}
+
-jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
+static jobject callObjectMethod(jobject obj, jmethodID methodID, va_list args)
{
int argcount;
jni_callblock *blk;
jobject ret;
-
-
if (methodID == 0) {
*exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return 0;
}
- argcount = get_parametercount(methodID);
-
if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
*exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return 0;
}
-#ifdef arglimit
+ argcount = methodID->parseddesc->paramcount;
- if (argcount > 3) {
- *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
- log_text("Too many arguments. CallObjectMethod does not support that");
- return 0;
- }
-#endif
+ blk = MNEW(jni_callblock, argcount);
- blk = MNEW(jni_callblock, /*4 */argcount+2);
+ fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_ADR);
+
+ STATS(jnicallXmethodnvokation();)
- fill_callblock(obj, methodID->descriptor, blk, args, 'O');
- /* printf("parameter: obj: %p",blk[0].item); */
ret = asm_calljavafunction2(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
+ argcount,
+ argcount * sizeof(jni_callblock),
blk);
- MFREE(blk, jni_callblock, argcount + 1);
- /* printf("(CallObjectMethodV)-->%p\n",ret); */
+
+ MFREE(blk, jni_callblock, argcount);
return ret;
}
core function for integer class methods (bool, byte, short, integer)
This is basically needed for i386
*/
-jint callIntegerMethod(jobject obj, jmethodID methodID, char retType, va_list args)
+static jint callIntegerMethod(jobject obj, jmethodID methodID, int retType, va_list args)
{
int argcount;
jni_callblock *blk;
jint ret;
-/* printf("%p, %c\n",retType,methodID,retType);*/
+ STATS(jniinvokation();)
/*
log_text("JNI-Call: CallObjectMethodV");
return 0;
}
- argcount = get_parametercount(methodID);
-
if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
*exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return 0;
}
-#ifdef arglimit
- if (argcount > 3) {
- *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
- log_text("Too many arguments. CallIntegerMethod does not support that");
- return 0;
- }
-#endif
+ argcount = methodID->parseddesc->paramcount;
- blk = MNEW(jni_callblock, /*4 */ argcount+2);
+ blk = MNEW(jni_callblock, argcount);
- fill_callblock(obj, methodID->descriptor, blk, args, retType);
+ fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
- /* printf("parameter: obj: %p",blk[0].item); */
- ret = (jint) asm_calljavafunction2(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
- blk);
+ STATS(jnicallXmethodnvokation();)
- MFREE(blk, jni_callblock, argcount + 1);
- /* printf("(CallObjectMethodV)-->%p\n",ret); */
+ ret = asm_calljavafunction2int(methodID,
+ argcount,
+ argcount * sizeof(jni_callblock),
+ blk);
+
+ MFREE(blk, jni_callblock, argcount);
return ret;
}
-/*core function for long class functions*/
-jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
+/* callLongMethod **************************************************************
+
+ Core function for long class functions.
+
+*******************************************************************************/
+
+static jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
{
- int argcount;
+ s4 argcount;
jni_callblock *blk;
- jlong ret;
+ jlong ret;
+
+ STATS(jniinvokation();)
-/*
- log_text("JNI-Call: CallObjectMethodV");
- utf_display(methodID->name);
- utf_display(methodID->descriptor);
- printf("\nParmaeter count: %d\n",argcount);
- utf_display(obj->vftbl->class->name);
- printf("\n");
-*/
if (methodID == 0) {
*exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return 0;
}
- argcount = get_parametercount(methodID);
-
if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
- ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
+ ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
*exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return 0;
}
- if (obj && !builtin_instanceof(obj,methodID->class)) {
+ if (obj && !builtin_instanceof(obj, methodID->class)) {
*exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return 0;
}
-#ifdef arglimit
- if (argcount > 3) {
- *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
- log_text("Too many arguments. CallObjectMethod does not support that");
- return 0;
- }
-#endif
+ argcount = methodID->parseddesc->paramcount;
- blk = MNEW(jni_callblock,/* 4 */argcount+2);
+ blk = MNEW(jni_callblock, argcount);
- fill_callblock(obj, methodID->descriptor, blk, args, 'J');
+ fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_LNG);
+
+ STATS(jnicallXmethodnvokation();)
- /* printf("parameter: obj: %p",blk[0].item); */
ret = asm_calljavafunction2long(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
+ argcount,
+ argcount * sizeof(jni_callblock),
blk);
- MFREE(blk, jni_callblock, argcount + 1);
- /* printf("(CallObjectMethodV)-->%p\n",ret); */
+ MFREE(blk, jni_callblock, argcount);
return ret;
}
/*core function for float class methods (float,double)*/
-jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,char retType)
+static jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,int retType)
{
- int argcount = get_parametercount(methodID);
+ int argcount = methodID->parseddesc->paramcount;
jni_callblock *blk;
jdouble ret;
- /*
- log_text("JNI-Call: CallObjectMethodV");
- utf_display(methodID->name);
- utf_display(methodID->descriptor);
- printf("\nParmaeter count: %d\n",argcount);
- utf_display(obj->vftbl->class->name);
- printf("\n");
- */
+ STATS(jniinvokation();)
+
+ assert(0);
-#ifdef arglimit
if (argcount > 3) {
*exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
log_text("Too many arguments. CallObjectMethod does not support that");
return 0;
}
-#endif
blk = MNEW(jni_callblock, /*4 */ argcount+2);
- fill_callblock(obj, methodID->descriptor, blk, args, retType);
+ fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
/* printf("parameter: obj: %p",blk[0].item); */
+ STATS(jnicallXmethodnvokation();)
ret = asm_calljavafunction2double(methodID,
argcount + 1,
(argcount + 1) * sizeof(jni_callblock),
}
-/*************************** function: jclass_findfield ****************************
-
- searches for field with specified name and type in a 'classinfo'-structur
- if no such field is found NULL is returned
+static void cacao_jni_CallVoidMethod(jobject obj, jmethodID m, va_list ap)
+{
+ s4 paramcount;
+ jni_callblock *blk;
-************************************************************************************/
+ if (m == 0) {
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+ return;
+ }
-fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
-{
- s4 i;
-/* printf(" FieldCount: %d\n",c->fieldscount);
- utf_display(c->name); */
- for (i = 0; i < c->fieldscount; i++) {
-/* utf_display(c->fields[i].name);
- printf("\n");
- utf_display(c->fields[i].descriptor);
- printf("\n");*/
- if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
- return &(c->fields[i]);
- }
+ if (!( ((m->flags & ACC_STATIC) && (obj == 0)) ||
+ ((!(m->flags & ACC_STATIC)) && (obj != 0)) )) {
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+ return;
+ }
+
+ if (obj && !builtin_instanceof(obj, m->class)) {
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+ return;
+ }
- if (c->super) return jclass_findfield(c->super,name,desc);
+ paramcount = m->parseddesc->paramcount;
- return NULL;
+/* #error XXX does not work on intrp, but on JIT */
+ if (!(m->flags & ACC_STATIC))
+ paramcount++;
+
+ blk = MNEW(jni_callblock, paramcount);
+
+ fill_callblock_from_vargs(obj, m->parseddesc, blk, ap, TYPE_VOID);
+
+ STATS(jnicallXmethodnvokation();)
+
+ (void) asm_calljavafunction2(m,
+ paramcount,
+ paramcount * sizeof(jni_callblock),
+ blk);
+
+ MFREE(blk, jni_callblock, paramcount);
+
+ return;
}
-/********************* returns version of native method interface *****************/
-jint GetVersion (JNIEnv* env)
+/* GetVersion ******************************************************************
+
+ Returns the major version number in the higher 16 bits and the
+ minor version number in the lower 16 bits.
+
+*******************************************************************************/
+
+jint GetVersion(JNIEnv *env)
{
- return JNI_VERSION;
+ STATS(jniinvokation();)
+
+ /* we support JNI 1.4 */
+
+ return JNI_VERSION_1_4;
}
-/************** loads a class from a buffer of raw class data *****************/
+/* Class Operations ***********************************************************/
-jclass DefineClass(JNIEnv* env, const char *name, jobject loader, const jbyte *buf, jsize len)
-{
- jclass c;
- jclass r;
- classbuffer *cb;
+/* DefineClass *****************************************************************
- c = class_new(utf_new_char_classname((char *) name));
+ Loads a class from a buffer of raw class data. The buffer
+ containing the raw class data is not referenced by the VM after the
+ DefineClass call returns, and it may be discarded if desired.
- /* enter a monitor on the class */
+*******************************************************************************/
- builtin_monitorenter((java_objectheader *) c);
+jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
+ const jbyte *buf, jsize bufLen)
+{
+ java_lang_ClassLoader *cl;
+ java_lang_String *s;
+ java_bytearray *ba;
+ jclass c;
- /* measure time */
- if (getloadingtime)
- loadingtime_start();
+ STATS(jniinvokation();)
- /* build a classbuffer with the given data */
- cb = NEW(classbuffer);
- cb->class = c;
- cb->size = len;
- cb->data = (u1 *) buf;
- cb->pos = cb->data - 1;
+ cl = (java_lang_ClassLoader *) loader;
+ s = javastring_new_char(name);
+ ba = (java_bytearray *) buf;
- r = class_load_intern(cb);
+ c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
+ 0, bufLen, NULL);
- /* if return value is NULL, we had a problem and the class is not loaded */
- if (!r) {
- c->loaded = false;
+ return (jclass) NewLocalRef(env, (jobject) c);
+}
- /* now free the allocated memory, otherwise we could ran into a DOS */
- class_remove(c);
- }
- /* free memory */
- FREE(cb, classbuffer);
+/* FindClass *******************************************************************
- /* measure time */
- if (getloadingtime)
- loadingtime_stop();
+ This function loads a locally-defined class. It searches the
+ directories and zip files specified by the CLASSPATH environment
+ variable for the class with the specified name.
- /* leave the monitor */
+*******************************************************************************/
- builtin_monitorexit((java_objectheader *) c);
+jclass FindClass(JNIEnv *env, const char *name)
+{
+ utf *u;
+ classinfo *c;
+ java_objectheader *cl;
- /* XXX link the class here? */
-/* if (class_link(c)) */
-/* return NULL; */
+ STATS(jniinvokation();)
- if (r) {
- c->classloader = loader;
- use_class_as_object(r);
- }
+ u = utf_new_char_classname((char *) name);
- return r;
-}
+ /* check stacktrace for classloader, if one found use it, otherwise use */
+ /* the system classloader */
+#if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__)
+ /* these JITs support stacktraces, and so does the interpreter */
-/*********** loads locally defined class with the specified name **************/
+ cl = cacao_currentClassLoader();
+#else
+# if defined(ENABLE_INTRP)
+ /* the interpreter supports stacktraces, even if the JIT does not */
-jclass FindClass(JNIEnv* env, const char *name)
-{
- classinfo *c;
-
- c = class_new(utf_new_char_classname((char *) name));
+ if (opt_intrp)
+ cl = cacao_currentClassLoader();
+ else
+# endif
+ cl = NULL;
+#endif
- if (!class_load(c))
+ if (!(c = load_class_from_classloader(u, cl)))
return NULL;
- if (!class_link(c))
+ if (!link_class(c))
return NULL;
- use_class_as_object(c);
+ if (!use_class_as_object(c))
+ return NULL;
- return c;
+ return (jclass) NewLocalRef(env, (jobject) c);
}
-/*******************************************************************************
+/* FromReflectedMethod *********************************************************
- converts java.lang.reflect.Method or
- java.lang.reflect.Constructor object to a method ID
+ Converts java.lang.reflect.Method or java.lang.reflect.Constructor
+ object to a method ID.
*******************************************************************************/
-jmethodID FromReflectedMethod(JNIEnv* env, jobject method)
+jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
{
- /* log_text("JNI-Call: FromReflectedMethod"); */
+ methodinfo *mi;
+ classinfo *c;
+ s4 slot;
- return 0;
+ STATS(jniinvokation();)
+
+ if (method == NULL)
+ return NULL;
+
+ if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
+ java_lang_reflect_Method *rm;
+
+ rm = (java_lang_reflect_Method *) method;
+ c = (classinfo *) (rm->declaringClass);
+ slot = rm->slot;
+
+ } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
+ java_lang_reflect_Constructor *rc;
+
+ rc = (java_lang_reflect_Constructor *) method;
+ c = (classinfo *) (rc->clazz);
+ slot = rc->slot;
+
+ } else
+ return NULL;
+
+ if ((slot < 0) || (slot >= c->methodscount)) {
+ /* this usually means a severe internal cacao error or somebody
+ tempered around with the reflected method */
+ log_text("error illegal slot for method in class(FromReflectedMethod)");
+ assert(0);
+ }
+
+ mi = &(c->methods[slot]);
+
+ return mi;
}
-/*************** return superclass of the class represented by sub ****************/
+/* GetSuperclass ***************************************************************
+
+ If clazz represents any class other than the class Object, then
+ this function returns the object that represents the superclass of
+ the class specified by clazz.
+
+*******************************************************************************/
-jclass GetSuperclass(JNIEnv* env, jclass sub)
+jclass GetSuperclass(JNIEnv *env, jclass sub)
{
classinfo *c;
- c = ((classinfo*) sub)->super;
+ STATS(jniinvokation();)
- if (!c) return NULL;
+ c = ((classinfo *) sub)->super.cls;
+
+ if (!c)
+ return NULL;
- use_class_as_object(c);
+ if (!use_class_as_object(c))
+ return NULL;
- return c;
+ return (jclass) NewLocalRef(env, (jobject) c);
}
-/*********************** check whether sub can be cast to sup ********************/
-
-jboolean IsAssignableForm(JNIEnv* env, jclass sub, jclass sup)
+/* IsAssignableFrom ************************************************************
+
+ Determines whether an object of sub can be safely cast to sup.
+
+*******************************************************************************/
+
+jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
{
- return builtin_isanysubclass(sub, sup);
+ STATS(jniinvokation();)
+ return Java_java_lang_VMClass_isAssignableFrom(env,
+ NULL,
+ (java_lang_Class *) sup,
+ (java_lang_Class *) sub);
}
jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
{
- /* log_text("JNI-Call: ToReflectedField"); */
+ STATS(jniinvokation();)
+
+ log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!!!");
return NULL;
}
-/***************** throw java.lang.Throwable object ******************************/
+/* Throw ***********************************************************************
+
+ Causes a java.lang.Throwable object to be thrown.
-jint Throw(JNIEnv* env, jthrowable obj)
+*******************************************************************************/
+
+jint Throw(JNIEnv *env, jthrowable obj)
{
- *exceptionptr = (java_objectheader*) obj;
+ STATS(jniinvokation();)
- return 0;
+ *exceptionptr = (java_objectheader *) obj;
+
+ return JNI_OK;
}
-/*******************************************************************************
+/* ThrowNew ********************************************************************
- create exception object from the class clazz with the
- specified message and cause it to be thrown
+ Constructs an exception object from the specified class with the
+ message specified by message and causes that exception to be
+ thrown.
*******************************************************************************/
jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
{
java_lang_Throwable *o;
+ java_lang_String *s;
+
+ STATS(jniinvokation();)
+
+ s = (java_lang_String *) javastring_new_char(msg);
/* instantiate exception object */
- o = (java_lang_Throwable *) native_new_and_init((classinfo*) clazz);
- if (!o) return (-1);
+ o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
+ s);
- o->detailMessage = (java_lang_String *) javastring_new_char((char *) msg);
+ if (!o)
+ return -1;
*exceptionptr = (java_objectheader *) o;
}
-/************************* check if exception occured *****************************/
+/* ExceptionOccurred ***********************************************************
-jthrowable ExceptionOccurred (JNIEnv* env)
-{
- return (jthrowable) *exceptionptr;
-}
+ Determines if an exception is being thrown. The exception stays
+ being thrown until either the native code calls ExceptionClear(),
+ or the Java code handles the exception.
-/********** print exception and a backtrace of the stack (for debugging) **********/
+*******************************************************************************/
-void ExceptionDescribe (JNIEnv* env)
+jthrowable ExceptionOccurred(JNIEnv *env)
{
- utf_display((*exceptionptr)->vftbl->class->name);
- printf ("\n");
- fflush (stdout);
-}
+ java_objectheader *e;
+ STATS(jniinvokation();)
-/******************* clear any exception currently being thrown *******************/
+ e = *exceptionptr;
-void ExceptionClear (JNIEnv* env)
-{
- *exceptionptr = NULL;
+ return NewLocalRef(env, (jthrowable) e);
}
-/********** raises a fatal error and does not expect the VM to recover ************/
+/* ExceptionDescribe ***********************************************************
-void FatalError (JNIEnv* env, const char *msg)
-{
- panic((char *) msg);
+ Prints an exception and a backtrace of the stack to a system
+ error-reporting channel, such as stderr. This is a convenience
+ routine provided for debugging.
+
+*******************************************************************************/
+
+void ExceptionDescribe(JNIEnv *env)
+{
+ java_objectheader *e;
+ methodinfo *m;
+ STATS(jniinvokation();)
+
+ e = *exceptionptr;
+
+ if (e) {
+ /* clear exception, because we are calling jit code again */
+
+ *exceptionptr = NULL;
+
+ /* get printStackTrace method from exception class */
+
+ m = class_resolveclassmethod(e->vftbl->class,
+ utf_printStackTrace,
+ utf_void__void,
+ NULL,
+ true);
+
+ if (!m)
+ /* XXX what should we do? */
+ return;
+
+ /* print the stacktrace */
+
+ asm_calljavafunction(m, e, NULL, NULL, NULL);
+ }
+}
+
+
+/* ExceptionClear **************************************************************
+
+ Clears any exception that is currently being thrown. If no
+ exception is currently being thrown, this routine has no effect.
+
+*******************************************************************************/
+
+void ExceptionClear(JNIEnv *env)
+{
+ STATS(jniinvokation();)
+
+ *exceptionptr = NULL;
+}
+
+
+/* FatalError ******************************************************************
+
+ Raises a fatal error and does not expect the VM to recover. This
+ function does not return.
+
+*******************************************************************************/
+
+void FatalError(JNIEnv *env, const char *msg)
+{
+ STATS(jniinvokation();)
+
+ throw_cacao_exception_exit(string_java_lang_InternalError, msg);
}
-/******************* creates a new local reference frame **************************/
+
+/* PushLocalFrame **************************************************************
+
+ Creates a new local reference frame, in which at least a given
+ number of local references can be created.
+
+*******************************************************************************/
jint PushLocalFrame(JNIEnv* env, jint capacity)
{
- /* empty */
+ STATS(jniinvokation();)
+
+ log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
+
+ assert(0);
return 0;
}
-/**************** Pops off the current local reference frame **********************/
+/* PopLocalFrame ***************************************************************
+
+ Pops off the current local reference frame, frees all the local
+ references, and returns a local reference in the previous local
+ reference frame for the given result object.
+
+*******************************************************************************/
jobject PopLocalFrame(JNIEnv* env, jobject result)
{
- log_text("JNI-Call: PopLocalFrame");
- /* empty */
+ STATS(jniinvokation();)
- return NULL;
+ log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
+
+ assert(0);
+
+ /* add local reference and return the value */
+
+ return NewLocalRef(env, NULL);
}
-/*************** Deletes the local reference pointed to by localRef ***************/
+/* DeleteLocalRef **************************************************************
+
+ Deletes the local reference pointed to by localRef.
-void DeleteLocalRef (JNIEnv* env, jobject localRef)
+*******************************************************************************/
+
+void DeleteLocalRef(JNIEnv *env, jobject localRef)
{
-/* log_text("JNI-Call: DeleteLocalRef");*/
- /* empty */
+ java_objectheader *o;
+ localref_table *lrt;
+ s4 i;
+
+ STATS(jniinvokation();)
+
+ o = (java_objectheader *) localRef;
+
+ /* get local reference table (thread specific) */
+
+ lrt = LOCALREFTABLE;
+
+ /* remove the reference */
+
+ for (i = 0; i < lrt->capacity; i++) {
+ if (lrt->refs[i] == o) {
+ lrt->refs[i] = NULL;
+ lrt->used--;
+
+ return;
+ }
+ }
+
+ /* this should not happen */
+
+/* if (opt_checkjni) */
+/* FatalError(env, "Bad global or local ref passed to JNI"); */
+ log_text("JNI-DeleteLocalRef: Bad global or local ref passed to JNI");
}
-/********** Tests whether two references refer to the same Java object ************/
-jboolean IsSameObject (JNIEnv* env, jobject obj1, jobject obj2)
+/* IsSameObject ****************************************************************
+
+ Tests whether two references refer to the same Java object.
+
+*******************************************************************************/
+
+jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
{
- return (obj1==obj2);
+ STATS(jniinvokation();)
+
+ if (ref1 == ref2)
+ return JNI_TRUE;
+ else
+ return JNI_FALSE;
}
-/***** Creates a new local reference that refers to the same object as ref *******/
-jobject NewLocalRef (JNIEnv* env, jobject ref)
+/* NewLocalRef *****************************************************************
+
+ Creates a new local reference that refers to the same object as ref.
+
+*******************************************************************************/
+
+jobject NewLocalRef(JNIEnv *env, jobject ref)
{
- return ref;
+ localref_table *lrt;
+ s4 i;
+
+ STATS(jniinvokation();)
+
+ if (ref == NULL)
+ return NULL;
+
+ /* get local reference table (thread specific) */
+
+ lrt = LOCALREFTABLE;
+
+ /* check if we have space for the requested reference */
+
+ if (lrt->used == lrt->capacity)
+ throw_cacao_exception_exit(string_java_lang_InternalError,
+ "Too many local references");
+
+ /* insert the reference */
+
+ for (i = 0; i < lrt->capacity; i++) {
+ if (lrt->refs[i] == NULL) {
+ lrt->refs[i] = (java_objectheader *) ref;
+ lrt->used++;
+
+ return ref;
+ }
+ }
+
+ /* should not happen, just to be sure */
+
+ assert(0);
+
+ /* keep compiler happy */
+
+ return NULL;
}
-/***********************************************************************************
- Ensures that at least a given number of local references can
- be created in the current thread
+/* EnsureLocalCapacity *********************************************************
- **********************************************************************************/
+ Ensures that at least a given number of local references can be
+ created in the current thread
+
+*******************************************************************************/
-jint EnsureLocalCapacity (JNIEnv* env, jint capacity)
+jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
{
- return 0; /* return 0 on success */
+ localref_table *lrt;
+
+ STATS(jniinvokation();)
+
+ /* get local reference table (thread specific) */
+
+ lrt = LOCALREFTABLE;
+
+ /* check if capacity elements are available in the local references table */
+
+ if ((lrt->used + capacity) > lrt->capacity) {
+ *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
+ return -1;
+ }
+
+ return 0;
}
-/********* Allocates a new Java object without invoking a constructor *************/
+/* AllocObject *****************************************************************
-jobject AllocObject (JNIEnv* env, jclass clazz)
+ Allocates a new Java object without invoking any of the
+ constructors for the object. Returns a reference to the object.
+
+*******************************************************************************/
+
+jobject AllocObject(JNIEnv *env, jclass clazz)
{
- java_objectheader *o = builtin_new(clazz);
- return o;
+ java_objectheader *o;
+
+ STATS(jniinvokation();)
+
+ if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
+ *exceptionptr =
+ new_exception_utfmessage(string_java_lang_InstantiationException,
+ clazz->name);
+ return NULL;
+ }
+
+ o = builtin_new(clazz);
+
+ return NewLocalRef(env, o);
}
-/***********************************************************************************
+/* NewObject *******************************************************************
- Constructs a new Java object
- arguments that are to be passed to the constructor are placed after methodID
+ Programmers place all arguments that are to be passed to the
+ constructor immediately following the methodID
+ argument. NewObject() accepts these arguments and passes them to
+ the Java method that the programmer wishes to invoke.
-***********************************************************************************/
+*******************************************************************************/
-jobject NewObject (JNIEnv* env, jclass clazz, jmethodID methodID, ...)
+jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
{
java_objectheader *o;
- void* args[3];
- int argcount=get_parametercount(methodID);
- int i;
- va_list vaargs;
+ va_list ap;
- /* log_text("JNI-Call: NewObject"); */
+ STATS(jniinvokation();)
-#ifdef arglimit
- if (argcount > 3) {
- *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
- log_text("Too many arguments. NewObject does not support that");
- return 0;
- }
-#endif
-
- o = builtin_new (clazz); /* create object */
+ /* create object */
+
+ o = builtin_new(clazz);
- if (!o) return NULL;
+ if (!o)
+ return NULL;
- va_start(vaargs,methodID);
- for (i=0;i<argcount;i++) {
- args[i]=va_arg(vaargs,void*);
- }
- va_end(vaargs);
- asm_calljavafunction(methodID,o,args[0],args[1],args[2]);
+ /* call constructor */
- return o;
+ va_start(ap, methodID);
+ cacao_jni_CallVoidMethod(o, methodID, ap);
+ va_end(ap);
+
+ return NewLocalRef(env, o);
}
jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
{
- /* log_text("JNI-Call: NewObjectV"); */
+ STATS(jniinvokation();)
- return NULL;
+ log_text("JNI-Call: NewObjectV: IMPLEMENT ME!");
+
+ return NewLocalRef(env, NULL);
}
jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
{
- /* log_text("JNI-Call: NewObjectA"); */
+ STATS(jniinvokation();)
- return NULL;
+ log_text("JNI-Call: NewObjectA: IMPLEMENT ME!");
+
+ return NewLocalRef(env, NULL);
}
-/************************ returns the class of an object **************************/
+/* GetObjectClass **************************************************************
+
+ Returns the class of an object.
-jclass GetObjectClass(JNIEnv* env, jobject obj)
+*******************************************************************************/
+
+jclass GetObjectClass(JNIEnv *env, jobject obj)
{
- classinfo *c = obj->vftbl->class;
+ classinfo *c;
+
+ STATS(jniinvokation();)
+
+ if (!obj || !obj->vftbl)
+ return NULL;
- use_class_as_object(c);
+ c = obj->vftbl->class;
+
+ if (!use_class_as_object(c))
+ return NULL;
- return c;
+ return (jclass) NewLocalRef(env, (jobject) c);
}
-/************* tests whether an object is an instance of a class ******************/
+/* IsInstanceOf ****************************************************************
-jboolean IsInstanceOf(JNIEnv* env, jobject obj, jclass clazz)
+ Tests whether an object is an instance of a class.
+
+*******************************************************************************/
+
+jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
{
- return builtin_instanceof(obj,clazz);
+ STATS(jniinvokation();)
+
+ return Java_java_lang_VMClass_isInstance(env,
+ NULL,
+ (java_lang_Class *) clazz,
+ (java_lang_Object *) obj);
}
jfieldID FromReflectedField(JNIEnv* env, jobject field)
{
- log_text("JNI-Call: FromReflectedField");
-
- return 0;
+ java_lang_reflect_Field *f;
+ classinfo *c;
+ jfieldID fid; /* the JNI-fieldid of the wrapping object */
+ STATS(jniinvokation();)
+ /*log_text("JNI-Call: FromReflectedField");*/
+
+ f=(java_lang_reflect_Field *)field;
+ if (f==0) return 0;
+ c=(classinfo*)(f->declaringClass);
+ if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
+ /*this usually means a severe internal cacao error or somebody
+ tempered around with the reflected method*/
+ log_text("error illegal slot for field in class(FromReflectedField)");
+ assert(0);
+ }
+ fid=&(c->fields[f->slot]);
+ return fid;
}
jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
{
log_text("JNI-Call: ToReflectedMethod");
+ STATS(jniinvokation();)
return NULL;
}
+/* Calling Instance Methods ***************************************************/
+
/* GetMethodID *****************************************************************
- returns the method ID for an instance method
+ Returns the method ID for an instance (nonstatic) method of a class
+ or interface. The method may be defined in one of the clazz's
+ superclasses and inherited by clazz. The method is determined by
+ its name and signature.
+
+ GetMethodID() causes an uninitialized class to be initialized.
*******************************************************************************/
-jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
+jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name,
+ const char *sig)
{
- jmethodID m;
+ classinfo *c;
+ utf *uname;
+ utf *udesc;
+ methodinfo *m;
+
+ STATS(jniinvokation();)
+
+ c = (classinfo *) clazz;
- m = class_resolvemethod(clazz,
- utf_new_char((char *) name),
- utf_new_char((char *) sig));
+ if (!c)
+ return NULL;
+
+ if (!c->initialized)
+ if (!initialize_class(c))
+ return NULL;
+
+ /* try to get the method of the class or one of it's superclasses */
+
+ uname = utf_new_char((char *) name);
+ udesc = utf_new_char((char *) sig);
+
+ m = class_resolvemethod(clazz, uname, udesc);
if (!m || (m->flags & ACC_STATIC)) {
- *exceptionptr =
- new_exception_message(string_java_lang_NoSuchMethodError, name);
+ *exceptionptr = exceptions_new_nosuchmethoderror(c, uname, udesc);
return NULL;
}
jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
{
- jobject ret;
- va_list vaargs;
+ java_objectheader* ret;
+ va_list vaargs;
-/* log_text("JNI-Call: CallObjectMethod");*/
+ STATS(jniinvokation();)
va_start(vaargs, methodID);
ret = callObjectMethod(obj, methodID, vaargs);
va_end(vaargs);
- return ret;
+ return NewLocalRef(env, ret);
}
jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
{
- return callObjectMethod(obj,methodID,args);
+ java_objectheader* ret;
+
+ STATS(jniinvokation();)
+
+ ret = callObjectMethod(obj, methodID, args);
+
+ return NewLocalRef(env, ret);
}
jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
{
- log_text("JNI-Call: CallObjectMethodA");
+ STATS(jniinvokation();)
- return NULL;
+ log_text("JNI-Call: CallObjectMethodA: IMPLEMENT ME!");
+
+ return NewLocalRef(env, NULL);
}
{
jboolean ret;
va_list vaargs;
+ STATS(jniinvokation();)
/* log_text("JNI-Call: CallBooleanMethod");*/
va_start(vaargs,methodID);
- ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',vaargs);
+ ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
va_end(vaargs);
return ret;
jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
{
- return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',args);
+ STATS(jniinvokation();)
+
+ return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
}
jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallBooleanMethodA");
return 0;
{
jbyte ret;
va_list vaargs;
+ STATS(jniinvokation();)
/* log_text("JNI-Call: CallVyteMethod");*/
va_start(vaargs,methodID);
- ret = callIntegerMethod(obj,get_virtual(obj,methodID),'B',vaargs);
+ ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
va_end(vaargs);
return ret;
jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
{
/* log_text("JNI-Call: CallByteMethodV");*/
- return callIntegerMethod(obj,methodID,'B',args);
+ STATS(jniinvokation();)
+
+ return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
}
jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
{
log_text("JNI-Call: CallByteMethodA");
+ STATS(jniinvokation();)
return 0;
}
{
jchar ret;
va_list vaargs;
+ STATS(jniinvokation();)
/* log_text("JNI-Call: CallCharMethod");*/
va_start(vaargs,methodID);
- ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'C', vaargs);
+ ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
va_end(vaargs);
return ret;
jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
{
+ STATS(jniinvokation();)
+
/* log_text("JNI-Call: CallCharMethodV");*/
- return callIntegerMethod(obj,get_virtual(obj,methodID),'C',args);
+ return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
}
jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
{
+ STATS(jniinvokation();)
+
log_text("JNI-Call: CallCharMethodA");
return 0;
{
jshort ret;
va_list vaargs;
+ STATS(jniinvokation();)
/* log_text("JNI-Call: CallShortMethod");*/
va_start(vaargs, methodID);
- ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'S', vaargs);
+ ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
va_end(vaargs);
return ret;
jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
{
- return callIntegerMethod(obj, get_virtual(obj, methodID), 'S', args);
+ STATS(jniinvokation();)
+ return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
}
jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallShortMethodA");
return 0;
{
jint ret;
va_list vaargs;
+ STATS(jniinvokation();)
va_start(vaargs,methodID);
- ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'I', vaargs);
+ ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
va_end(vaargs);
return ret;
jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
{
- return callIntegerMethod(obj, get_virtual(obj, methodID), 'I', args);
+ STATS(jniinvokation();)
+ return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
}
jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallIntMethodA");
return 0;
{
jlong ret;
va_list vaargs;
+ STATS(jniinvokation();)
va_start(vaargs,methodID);
ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
{
+ STATS(jniinvokation();)
return callLongMethod(obj,get_virtual(obj, methodID),args);
}
jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallLongMethodA");
return 0;
jfloat ret;
va_list vaargs;
+ STATS(jniinvokation();)
/* log_text("JNI-Call: CallFloatMethod");*/
va_start(vaargs,methodID);
- ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'F');
+ ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
va_end(vaargs);
return ret;
jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallFloatMethodV");
- return callFloatMethod(obj, get_virtual(obj, methodID), args, 'F');
+ return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
}
jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallFloatMethodA");
return 0;
{
jdouble ret;
va_list vaargs;
+ STATS(jniinvokation();)
/* log_text("JNI-Call: CallDoubleMethod");*/
va_start(vaargs,methodID);
- ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'D');
+ ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
va_end(vaargs);
return ret;
jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallDoubleMethodV");
- return callFloatMethod(obj, get_virtual(obj, methodID), args, 'D');
+ return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
}
jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallDoubleMethodA");
return 0;
}
void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
{
va_list vaargs;
+ STATS(jniinvokation();)
va_start(vaargs,methodID);
- (void) callIntegerMethod(obj, get_virtual(obj, methodID), 'V', vaargs);
+ (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
va_end(vaargs);
}
void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
{
log_text("JNI-Call: CallVoidMethodV");
- (void)callIntegerMethod(obj,get_virtual(obj,methodID),'V',args);
+ STATS(jniinvokation();)
+ (void)callIntegerMethod(obj,get_virtual(obj,methodID),TYPE_VOID,args);
}
void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallVoidMethodA");
}
-jobject CallNonvirtualObjectMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
+jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
{
- log_text("JNI-Call: CallNonvirtualObjectMethod");
+ STATS(jniinvokation();)
- return NULL;
+ log_text("JNI-Call: CallNonvirtualObjectMethod: IMPLEMENT ME!");
+
+ return NewLocalRef(env, NULL);
}
-jobject CallNonvirtualObjectMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
+jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
{
- log_text("JNI-Call: CallNonvirtualObjectMethodV");
+ STATS(jniinvokation();)
- return NULL;
+ log_text("JNI-Call: CallNonvirtualObjectMethodV: IMPLEMENT ME!");
+
+ return NewLocalRef(env, NULL);
}
-jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
+jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
{
- log_text("JNI-Call: CallNonvirtualObjectMethodA");
+ STATS(jniinvokation();)
- return NULL;
+ log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
+
+ return NewLocalRef(env, NULL);
}
{
jboolean ret;
va_list vaargs;
+ STATS(jniinvokation();)
/* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
va_start(vaargs,methodID);
- ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',vaargs);
+ ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
va_end(vaargs);
return ret;
jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
{
+ STATS(jniinvokation();)
/* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
- return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',args);
+ return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
}
jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallNonvirtualBooleanMethodA");
return 0;
jbyte ret;
va_list vaargs;
+ STATS(jniinvokation();)
/* log_text("JNI-Call: CallNonvirutalByteMethod");*/
va_start(vaargs,methodID);
- ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',vaargs);
+ ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
va_end(vaargs);
return ret;
}
jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
{
+ STATS(jniinvokation();)
/*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
- return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',args);
+ return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
}
jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallNonvirtualByteMethodA");
return 0;
jchar ret;
va_list vaargs;
+ STATS(jniinvokation();)
/* log_text("JNI-Call: CallNonVirtualCharMethod");*/
va_start(vaargs,methodID);
- ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',vaargs);
+ ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
va_end(vaargs);
return ret;
}
jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
{
+ STATS(jniinvokation();)
/*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
- return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',args);
+ return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
}
jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallNonvirtualCharMethodA");
return 0;
{
jshort ret;
va_list vaargs;
+ STATS(jniinvokation();)
/*log_text("JNI-Call: CallNonvirtualShortMethod");*/
va_start(vaargs,methodID);
- ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',vaargs);
+ ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
va_end(vaargs);
return ret;
}
jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
{
+ STATS(jniinvokation();)
/*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
- return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',args);
+ return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
}
jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallNonvirtualShortMethodA");
return 0;
jint ret;
va_list vaargs;
+ STATS(jniinvokation();)
/*log_text("JNI-Call: CallNonvirtualIntMethod");*/
va_start(vaargs,methodID);
- ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',vaargs);
+ ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
va_end(vaargs);
return ret;
}
jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
{
+ STATS(jniinvokation();)
/*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
- return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',args);
+ return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
}
jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallNonvirtualIntMethodA");
return 0;
jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallNonvirtualLongMethod");
return 0;
jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallNonvirtualLongMethodV");
return 0;
jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallNonvirtualLongMethodA");
return 0;
{
jfloat ret;
va_list vaargs;
+ STATS(jniinvokation();)
/*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
va_start(vaargs,methodID);
- ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'F');
+ ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
va_end(vaargs);
return ret;
jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallNonvirtualFloatMethodV");
- return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'F');
+ return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
}
jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallNonvirtualFloatMethodA");
return 0;
{
jdouble ret;
va_list vaargs;
+ STATS(jniinvokation();)
log_text("JNI-Call: CallNonvirtualDoubleMethod");
va_start(vaargs,methodID);
- ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'D');
+ ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
va_end(vaargs);
return ret;
jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
{
+ STATS(jniinvokation();)
/* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
- return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'D');
+ return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
}
jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallNonvirtualDoubleMethodA");
return 0;
void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
{
va_list vaargs;
+ STATS(jniinvokation();)
/* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
va_start(vaargs,methodID);
- (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',vaargs);
+ (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
va_end(vaargs);
}
void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
{
/* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
+ STATS(jniinvokation();)
- (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',args);
+ (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
}
void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: CallNonvirtualVoidMethodA");
}
-/************************* JNI-functions for accessing fields ************************/
-jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
+/* Accessing Fields of Objects ************************************************/
+
+/* GetFieldID ******************************************************************
+
+ Returns the field ID for an instance (nonstatic) field of a
+ class. The field is specified by its name and signature. The
+ Get<type>Field and Set<type>Field families of accessor functions
+ use field IDs to retrieve object fields.
+
+*******************************************************************************/
+
+jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name,
+ const char *sig)
{
- jfieldID f;
+ fieldinfo *f;
+ utf *uname;
+ utf *udesc;
+
+ STATS(jniinvokation();)
+
+ uname = utf_new_char((char *) name);
+ udesc = utf_new_char((char *) sig);
-/* log_text("========================= searching for:");
- log_text(name);
- log_text(sig);*/
- f = jclass_findfield(clazz,
- utf_new_char ((char*) name),
- utf_new_char ((char*) sig)
- );
+ f = class_findfield(clazz, uname, udesc);
- if (!f) {
- /*utf_display(clazz->name);
- log_text(name);
- log_text(sig);*/
+ if (!f)
*exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
- }
+
return f;
}
-/*************************** retrieve fieldid, abort on error ************************/
-jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
-{
- jfieldID id = GetFieldID(env, clazz, name, sig);
+/* Get<type>Field Routines *****************************************************
- if (!id) {
- log_text("class:");
- utf_display(clazz->name);
- log_text("\nfield:");
- log_text(name);
- log_text("sig:");
- log_text(sig);
+ This family of accessor routines returns the value of an instance
+ (nonstatic) field of an object. The field to access is specified by
+ a field ID obtained by calling GetFieldID().
- panic("setfield_critical failed");
- }
- return id;
-}
+*******************************************************************************/
-jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
+jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
{
- jobject dbg,dretval,*dpretval;
- long int dli1, dli2, dli3;
+ java_objectheader *o;
+
+ STATS(jniinvokation();)
-/* printf("GetObjectField(1): thread: %s obj: %p name: %s desc: %s \n",GetStringUTFChars(env,
- ((threadobject *) THREADOBJECT)->o
- .thread->name,NULL)
- ,obj,((fieldinfo*)fieldID)->name->text,(fieldID->descriptor)->text);*/
+ o = GET_FIELD(obj, java_objectheader*, fieldID);
- dbg = getField(obj,jobject,fieldID);
- dli1 = (long int) obj;
- dli2 = (long int) fieldID->offset;
- dli3 = dli1+dli2;
- dpretval = (jobject*) dli3;
- dretval = *dpretval;
-/* jclass tmp;
- jmethodID mid;
- jstring jstr;
+ return NewLocalRef(env, o);
+}
- tmp = FindClass(env, "java/lang/Object");
- mid = GetMethodID(env,tmp,"toString","()Ljava/lang/String;");
- jstr = CallObjectMethod(env,dbg,mid);*/
-/* printf("GetObjectField(2): retval %p (obj: %#lx + offset: %#lx = %#lx (jobject*) %p (jobject) %p\n"
- ,dbg, dli1, dli2, dli3,dpretval, dretval);*/
+jboolean GetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID)
+{
+ s4 i;
+ STATS(jniinvokation();)
- return dbg;
-}
+ i = GET_FIELD(obj, s4, fieldID);
-jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
-{
- return getField(obj,jboolean,fieldID);
+ return (jboolean) i;
}
-jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
+jbyte GetByteField(JNIEnv *env, jobject obj, jfieldID fieldID)
{
- return getField(obj,jbyte,fieldID);
+ s4 i;
+
+ STATS(jniinvokation();)
+
+ i = GET_FIELD(obj, s4, fieldID);
+
+ return (jbyte) i;
}
-jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
+jchar GetCharField(JNIEnv *env, jobject obj, jfieldID fieldID)
{
- return getField(obj,jchar,fieldID);
+ s4 i;
+
+ STATS(jniinvokation();)
+
+ i = GET_FIELD(obj, s4, fieldID);
+
+ return (jchar) i;
}
-jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
+jshort GetShortField(JNIEnv *env, jobject obj, jfieldID fieldID)
{
- return getField(obj,jshort,fieldID);
+ s4 i;
+
+ STATS(jniinvokation();)
+
+ i = GET_FIELD(obj, s4, fieldID);
+
+ return (jshort) i;
}
-jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
+jint GetIntField(JNIEnv *env, jobject obj, jfieldID fieldID)
{
- return getField(obj,jint,fieldID);
+ s4 i;
+
+ STATS(jniinvokation();)
+
+ i = GET_FIELD(obj, s4, fieldID);
+
+ return i;
}
-jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
+jlong GetLongField(JNIEnv *env, jobject obj, jfieldID fieldID)
{
- return getField(obj,jlong,fieldID);
+ s8 l;
+
+ STATS(jniinvokation();)
+
+ l = GET_FIELD(obj, s8, fieldID);
+
+ return l;
}
-jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
+jfloat GetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID)
{
- return getField(obj,jfloat,fieldID);
+ float f;
+
+ STATS(jniinvokation();)
+
+ f = GET_FIELD(obj, float, fieldID);
+
+ return f;
}
-jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
+jdouble GetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID)
{
- return getField(obj,jdouble,fieldID);
+ double d;
+
+ STATS(jniinvokation();)
+
+ d = GET_FIELD(obj, double, fieldID);
+
+ return d;
}
-void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
+
+/* Set<type>Field Routines *****************************************************
+
+ This family of accessor routines sets the value of an instance
+ (nonstatic) field of an object. The field to access is specified by
+ a field ID obtained by calling GetFieldID().
+
+*******************************************************************************/
+
+void SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value)
{
- setField(obj,jobject,fieldID,val);
+ STATS(jniinvokation();)
+
+ SET_FIELD(obj, java_objectheader*, fieldID, value);
}
-void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
+void SetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID, jboolean value)
{
- setField(obj,jboolean,fieldID,val);
+ STATS(jniinvokation();)
+
+ SET_FIELD(obj, s4, fieldID, value);
}
-void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
+void SetByteField(JNIEnv *env, jobject obj, jfieldID fieldID, jbyte value)
{
- setField(obj,jbyte,fieldID,val);
+ STATS(jniinvokation();)
+
+ SET_FIELD(obj, s4, fieldID, value);
}
-void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
+void SetCharField(JNIEnv *env, jobject obj, jfieldID fieldID, jchar value)
{
- setField(obj,jchar,fieldID,val);
+ STATS(jniinvokation();)
+
+ SET_FIELD(obj, s4, fieldID, value);
}
-void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
+void SetShortField(JNIEnv *env, jobject obj, jfieldID fieldID, jshort value)
{
- setField(obj,jshort,fieldID,val);
+ STATS(jniinvokation();)
+
+ SET_FIELD(obj, s4, fieldID, value);
}
-void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
+void SetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint value)
{
- setField(obj,jint,fieldID,val);
+ STATS(jniinvokation();)
+
+ SET_FIELD(obj, s4, fieldID, value);
}
-void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
+void SetLongField(JNIEnv *env, jobject obj, jfieldID fieldID, jlong value)
{
- setField(obj,jlong,fieldID,val);
+ STATS(jniinvokation();)
+
+ SET_FIELD(obj, s8, fieldID, value);
}
-void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
+void SetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID, jfloat value)
{
- setField(obj,jfloat,fieldID,val);
+ STATS(jniinvokation();)
+
+ SET_FIELD(obj, float, fieldID, value);
}
-void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
+void SetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID, jdouble value)
{
- setField(obj,jdouble,fieldID,val);
+ STATS(jniinvokation();)
+
+ SET_FIELD(obj, double, fieldID, value);
}
-/**************** JNI-functions for calling static methods **********************/
+/* Calling Static Methods *****************************************************/
+
+/* GetStaticMethodID ***********************************************************
+
+ Returns the method ID for a static method of a class. The method is
+ specified by its name and signature.
+
+ GetStaticMethodID() causes an uninitialized class to be
+ initialized.
-jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
+*******************************************************************************/
+
+jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
+ const char *sig)
{
- jmethodID m;
+ classinfo *c;
+ utf *uname;
+ utf *udesc;
+ methodinfo *m;
+
+ STATS(jniinvokation();)
+
+ c = (classinfo *) clazz;
+
+ if (!c)
+ return NULL;
+
+ if (!c->initialized)
+ if (!initialize_class(c))
+ return NULL;
+
+ /* try to get the static method of the class */
- m = class_resolvemethod(clazz,
- utf_new_char((char *) name),
- utf_new_char((char *) sig));
+ uname = utf_new_char((char *) name);
+ udesc = utf_new_char((char *) sig);
+
+ m = class_resolvemethod(c, uname, udesc);
if (!m || !(m->flags & ACC_STATIC)) {
- *exceptionptr =
- new_exception_message(string_java_lang_NoSuchMethodError, name);
+ *exceptionptr = exceptions_new_nosuchmethoderror(c, uname, udesc);
return NULL;
}
jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
{
- jobject ret;
- va_list vaargs;
+ java_objectheader *ret;
+ va_list vaargs;
- /* log_text("JNI-Call: CallStaticObjectMethod");*/
+ STATS(jniinvokation();)
va_start(vaargs, methodID);
ret = callObjectMethod(0, methodID, vaargs);
va_end(vaargs);
- return ret;
+ return NewLocalRef(env, ret);
}
jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
{
- /* log_text("JNI-Call: CallStaticObjectMethodV"); */
+ java_objectheader *ret;
+
+ STATS(jniinvokation();)
- return callObjectMethod(0,methodID,args);
+ ret = callObjectMethod(0, methodID, args);
+
+ return NewLocalRef(env, ret);
}
jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
{
- log_text("JNI-Call: CallStaticObjectMethodA");
+ STATS(jniinvokation();)
- return NULL;
+ log_text("JNI-Call: CallStaticObjectMethodA: IMPLEMENT ME!");
+
+ return NewLocalRef(env, NULL);
}
jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
{
+ va_list vaargs;
jboolean ret;
- va_list vaargs;
+
+ STATS(jniinvokation();)
va_start(vaargs, methodID);
- ret = (jboolean) callIntegerMethod(0, methodID, 'Z', vaargs);
+ ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
va_end(vaargs);
return ret;
jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
{
- return (jboolean) callIntegerMethod(0, methodID, 'Z', args);
+ STATS(jniinvokation();)
+
+ return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
}
jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
{
- log_text("JNI-Call: CallStaticBooleanMethodA");
+ STATS(jniinvokation();)
+
+ log_text("JNI-Call: CallStaticBooleanMethodA: IMPLEMENT ME!");
return 0;
}
jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
{
- jbyte ret;
va_list vaargs;
+ jbyte ret;
- /* log_text("JNI-Call: CallStaticByteMethod");*/
+ STATS(jniinvokation();)
va_start(vaargs, methodID);
- ret = (jbyte) callIntegerMethod(0, methodID, 'B', vaargs);
+ ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
va_end(vaargs);
return ret;
jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
{
- return (jbyte) callIntegerMethod(0, methodID, 'B', args);
+ STATS(jniinvokation();)
+ return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
}
jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
{
- log_text("JNI-Call: CallStaticByteMethodA");
+ STATS(jniinvokation();)
+
+ log_text("JNI-Call: CallStaticByteMethodA: IMPLEMENT ME!");
return 0;
}
jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
{
- jchar ret;
va_list vaargs;
+ jchar ret;
- /* log_text("JNI-Call: CallStaticByteMethod");*/
+ STATS(jniinvokation();)
va_start(vaargs, methodID);
- ret = (jchar) callIntegerMethod(0, methodID, 'C', vaargs);
+ ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
va_end(vaargs);
return ret;
jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
{
- return (jchar) callIntegerMethod(0, methodID, 'C', args);
+ STATS(jniinvokation();)
+
+ return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
}
jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
{
- log_text("JNI-Call: CallStaticCharMethodA");
+ STATS(jniinvokation();)
+
+ log_text("JNI-Call: CallStaticCharMethodA: IMPLEMENT ME!");
return 0;
}
-
jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
{
- jshort ret;
va_list vaargs;
+ jshort ret;
- /* log_text("JNI-Call: CallStaticByteMethod");*/
+ STATS(jniinvokation();)
va_start(vaargs, methodID);
- ret = (jshort) callIntegerMethod(0, methodID, 'S', vaargs);
+ ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
va_end(vaargs);
return ret;
jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
{
- /*log_text("JNI-Call: CallStaticShortMethodV");*/
- return (jshort) callIntegerMethod(0, methodID, 'S', args);
+ STATS(jniinvokation();)
+
+ return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
}
jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
{
- log_text("JNI-Call: CallStaticShortMethodA");
+ STATS(jniinvokation();)
+
+ log_text("JNI-Call: CallStaticShortMethodA: IMPLEMENT ME!");
return 0;
}
-
jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
{
- jint ret;
va_list vaargs;
+ jint ret;
- /* log_text("JNI-Call: CallStaticIntMethod");*/
+ STATS(jniinvokation();)
va_start(vaargs, methodID);
- ret = callIntegerMethod(0, methodID, 'I', vaargs);
+ ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
va_end(vaargs);
return ret;
jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
{
- log_text("JNI-Call: CallStaticIntMethodV");
+ STATS(jniinvokation();)
- return callIntegerMethod(0, methodID, 'I', args);
+ return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
}
jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
{
- log_text("JNI-Call: CallStaticIntMethodA");
+ STATS(jniinvokation();)
+
+ log_text("JNI-Call: CallStaticIntMethodA: IMPLEMENT ME!");
return 0;
}
-
jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
{
- jlong ret;
va_list vaargs;
+ jlong ret;
- /* log_text("JNI-Call: CallStaticLongMethod");*/
+ STATS(jniinvokation();)
va_start(vaargs, methodID);
ret = callLongMethod(0, methodID, vaargs);
}
-jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
+jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
+ va_list args)
{
- log_text("JNI-Call: CallStaticLongMethodV");
+ STATS(jniinvokation();)
- return callLongMethod(0,methodID,args);
+ return callLongMethod(0, methodID, args);
}
jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
{
- log_text("JNI-Call: CallStaticLongMethodA");
+ STATS(jniinvokation();)
+
+ log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!");
return 0;
}
jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
{
- jfloat ret;
va_list vaargs;
+ jfloat ret;
- /* log_text("JNI-Call: CallStaticLongMethod");*/
+ STATS(jniinvokation();)
va_start(vaargs, methodID);
- ret = callFloatMethod(0, methodID, vaargs, 'F');
+ ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
va_end(vaargs);
return ret;
jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
{
+ STATS(jniinvokation();)
- return callFloatMethod(0, methodID, args, 'F');
+ return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
}
jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
{
- log_text("JNI-Call: CallStaticFloatMethodA");
+ STATS(jniinvokation();)
+
+ log_text("JNI-Call: CallStaticFloatMethodA: IMPLEMENT ME!");
return 0;
}
-
jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
{
- jdouble ret;
va_list vaargs;
+ jdouble ret;
- /* log_text("JNI-Call: CallStaticDoubleMethod");*/
+ STATS(jniinvokation();)
va_start(vaargs,methodID);
- ret = callFloatMethod(0, methodID, vaargs, 'D');
+ ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
va_end(vaargs);
return ret;
jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
{
- log_text("JNI-Call: CallStaticDoubleMethodV");
+ STATS(jniinvokation();)
- return callFloatMethod(0, methodID, args, 'D');
+ return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
}
jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
{
- log_text("JNI-Call: CallStaticDoubleMethodA");
+ STATS(jniinvokation();)
+
+ log_text("JNI-Call: CallStaticDoubleMethodA: IMPLEMENT ME!");
return 0;
}
{
va_list vaargs;
+ STATS(jniinvokation();)
+
va_start(vaargs, methodID);
- (void) callIntegerMethod(0, methodID, 'V', vaargs);
+ (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
va_end(vaargs);
}
void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
{
- log_text("JNI-Call: CallStaticVoidMethodV");
- (void)callIntegerMethod(0, methodID, 'V', args);
+ STATS(jniinvokation();)
+
+ (void) callIntegerMethod(0, methodID, TYPE_VOID, args);
}
void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
{
- log_text("JNI-Call: CallStaticVoidMethodA");
+ STATS(jniinvokation();)
+
+ log_text("JNI-Call: CallStaticVoidMethodA: IMPLEMENT ME!");
}
-/****************** JNI-functions for accessing static fields ********************/
+/* Accessing Static Fields ****************************************************/
+
+/* GetStaticFieldID ************************************************************
+
+ Returns the field ID for a static field of a class. The field is
+ specified by its name and signature. The GetStatic<type>Field and
+ SetStatic<type>Field families of accessor functions use field IDs
+ to retrieve static fields.
+
+*******************************************************************************/
-jfieldID GetStaticFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
+jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
{
jfieldID f;
+ STATS(jniinvokation();)
- f = jclass_findfield(clazz,
- utf_new_char ((char*) name),
- utf_new_char ((char*) sig)
- );
+ f = class_findfield(clazz,
+ utf_new_char((char *) name),
+ utf_new_char((char *) sig));
- if (!f) *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
+ if (!f)
+ *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
return f;
}
-jobject GetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID)
+/* GetStatic<type>Field ********************************************************
+
+ This family of accessor routines returns the value of a static
+ field of an object.
+
+*******************************************************************************/
+
+jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
{
- class_init(clazz);
- return fieldID->value.a;
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return NULL;
+
+ return NewLocalRef(env, fieldID->value.a);
}
-jboolean GetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID)
+jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return false;
+
return fieldID->value.i;
}
-jbyte GetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID)
+jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return 0;
+
return fieldID->value.i;
}
-jchar GetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID)
+jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return 0;
+
return fieldID->value.i;
}
-jshort GetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID)
+jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return 0;
+
return fieldID->value.i;
}
-jint GetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID)
+jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return 0;
+
return fieldID->value.i;
}
-jlong GetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID)
+jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return 0;
+
return fieldID->value.l;
}
-jfloat GetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID)
+jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return 0.0;
+
return fieldID->value.f;
}
-jdouble GetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID)
+jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return 0.0;
+
return fieldID->value.d;
}
+/* SetStatic<type>Field *******************************************************
+
+ This family of accessor routines sets the value of a static field
+ of an object.
-void SetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
+*******************************************************************************/
+
+void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return;
+
fieldID->value.a = value;
}
-void SetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
+void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return;
+
fieldID->value.i = value;
}
-void SetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
+void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return;
+
fieldID->value.i = value;
}
-void SetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
+void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return;
+
fieldID->value.i = value;
}
-void SetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
+void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return;
+
fieldID->value.i = value;
}
-void SetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
+void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return;
+
fieldID->value.i = value;
}
-void SetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
+void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return;
+
fieldID->value.l = value;
}
-void SetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
+void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return;
+
fieldID->value.f = value;
}
-void SetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
+void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
{
- class_init(clazz);
+ STATS(jniinvokation();)
+
+ if (!clazz->initialized)
+ if (!initialize_class(clazz))
+ return;
+
fieldID->value.d = value;
}
-/***** create new java.lang.String object from an array of Unicode characters ****/
+/* String Operations **********************************************************/
+
+/* NewString *******************************************************************
+
+ Create new java.lang.String object from an array of Unicode
+ characters.
+
+*******************************************************************************/
-jstring NewString (JNIEnv *env, const jchar *buf, jsize len)
+jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
{
- u4 i;
java_lang_String *s;
- java_chararray *a;
+ java_chararray *a;
+ u4 i;
+
+ STATS(jniinvokation();)
- s = (java_lang_String*) builtin_new (class_java_lang_String);
- a = builtin_newarray_char (len);
+ s = (java_lang_String *) builtin_new(class_java_lang_String);
+ a = builtin_newarray_char(len);
/* javastring or characterarray could not be created */
- if ( (!a) || (!s) ) return NULL;
+ if (!a || !s)
+ return NULL;
/* copy text */
- for (i=0; i<len; i++) a->data[i] = buf[i];
- s -> value = a;
- s -> offset = 0;
- s -> count = len;
+ for (i = 0; i < len; i++)
+ a->data[i] = buf[i];
- return (jstring) s;
+ s->value = a;
+ s->offset = 0;
+ s->count = len;
+
+ return (jstring) NewLocalRef(env, (jobject) s);
}
-static char emptyString[]="";
static jchar emptyStringJ[]={0,0};
-/******************* returns the length of a Java string ***************************/
+/* GetStringLength *************************************************************
+
+ Returns the length (the count of Unicode characters) of a Java
+ string.
-jsize GetStringLength (JNIEnv *env, jstring str)
+*******************************************************************************/
+
+jsize GetStringLength(JNIEnv *env, jstring str)
{
- return ((java_lang_String*) str)->count;
+ return ((java_lang_String *) str)->count;
}
/******************** convertes javastring to u2-array ****************************/
-u2 *javastring_tou2 (jstring so)
+u2 *javastring_tou2(jstring so)
{
- java_lang_String *s = (java_lang_String*) so;
- java_chararray *a;
- u4 i;
- u2 *stringbuffer;
+ java_lang_String *s;
+ java_chararray *a;
+ u2 *stringbuffer;
+ u4 i;
+
+ STATS(jniinvokation();)
- if (!s) return NULL;
+ s = (java_lang_String *) so;
+
+ if (!s)
+ return NULL;
a = s->value;
- if (!a) return NULL;
+
+ if (!a)
+ return NULL;
/* allocate memory */
- stringbuffer = MNEW( u2 , s->count + 1 );
+
+ stringbuffer = MNEW(u2, s->count + 1);
/* copy text */
- for (i=0; i<s->count; i++) stringbuffer[i] = a->data[s->offset+i];
+
+ for (i = 0; i < s->count; i++)
+ stringbuffer[i] = a->data[s->offset + i];
/* terminate string */
+
stringbuffer[i] = '\0';
return stringbuffer;
}
-/********* returns a pointer to an array of Unicode characters of the string *******/
-const jchar *GetStringChars (JNIEnv *env, jstring str, jboolean *isCopy)
+/* GetStringChars **************************************************************
+
+ Returns a pointer to the array of Unicode characters of the
+ string. This pointer is valid until ReleaseStringchars() is called.
+
+*******************************************************************************/
+
+const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
{
- jchar *jc=javastring_tou2(str);
+ jchar *jc;
+
+ STATS(jniinvokation();)
+
+ jc = javastring_tou2(str);
if (jc) {
- if (isCopy) *isCopy=JNI_TRUE;
+ if (isCopy)
+ *isCopy = JNI_TRUE;
+
return jc;
}
- if (isCopy) *isCopy=JNI_TRUE;
+
+ if (isCopy)
+ *isCopy = JNI_TRUE;
+
return emptyStringJ;
}
-/**************** native code no longer needs access to chars **********************/
-void ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars)
+/* ReleaseStringChars **********************************************************
+
+ Informs the VM that the native code no longer needs access to
+ chars. The chars argument is a pointer obtained from string using
+ GetStringChars().
+
+*******************************************************************************/
+
+void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
{
- if (chars==emptyStringJ) return;
- MFREE(((jchar*) chars),jchar,((java_lang_String*) str)->count+1);
+ STATS(jniinvokation();)
+
+ if (chars == emptyStringJ)
+ return;
+
+ MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
}
-/************ create new java.lang.String object from utf8-characterarray **********/
-jstring NewStringUTF (JNIEnv *env, const char *utf)
+/* NewStringUTF ****************************************************************
+
+ Constructs a new java.lang.String object from an array of UTF-8 characters.
+
+*******************************************************************************/
+
+jstring NewStringUTF(JNIEnv *env, const char *bytes)
{
-/* log_text("NewStringUTF called");*/
- return (jstring) javastring_new(utf_new_char((char *) utf));
+ java_lang_String *s;
+
+ STATS(jniinvokation();)
+
+ s = javastring_new(utf_new_char(bytes));
+
+ return (jstring) NewLocalRef(env, (jobject) s);
}
+
/****************** returns the utf8 length in bytes of a string *******************/
jsize GetStringUTFLength (JNIEnv *env, jstring string)
{
java_lang_String *s = (java_lang_String*) string;
+ STATS(jniinvokation();)
return (jsize) u2_utflength(s->value->data, s->count);
}
-/************ converts a Javastring to an array of UTF-8 characters ****************/
+/* GetStringUTFChars ***********************************************************
-const char* GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
+ Returns a pointer to an array of UTF-8 characters of the
+ string. This array is valid until it is released by
+ ReleaseStringUTFChars().
+
+*******************************************************************************/
+
+const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
{
- utf *u;
+ utf *u;
+ STATS(jniinvokation();)
- u = javastring_toutf((java_lang_String *) string, false);
+ if (!string)
+ return "";
- if (isCopy)
- *isCopy = JNI_FALSE;
+ if (isCopy)
+ *isCopy = JNI_TRUE;
- if (u)
+ u = javastring_toutf((java_lang_String *) string, false);
+
+ if (u)
return u->text;
- return emptyString;
-
+ return "";
}
-/***************** native code no longer needs access to utf ***********************/
+/* ReleaseStringUTFChars *******************************************************
+
+ Informs the VM that the native code no longer needs access to
+ utf. The utf argument is a pointer derived from string using
+ GetStringUTFChars().
-void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
+*******************************************************************************/
+
+void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
{
- /*we don't release utf chars right now, perhaps that should be done later. Since there is always one reference
- the garbage collector will never get them*/
- /*
- log_text("JNI-Call: ReleaseStringUTFChars");
- utf_display(utf_new_char(chars));
- */
+ STATS(jniinvokation();)
+
+ /* XXX we don't release utf chars right now, perhaps that should be done
+ later. Since there is always one reference the garbage collector will
+ never get them */
}
-/************************** array operations ***************************************/
+
+/* Array Operations ***********************************************************/
+
+/* GetArrayLength **************************************************************
+
+ Returns the number of elements in the array.
+
+*******************************************************************************/
jsize GetArrayLength(JNIEnv *env, jarray array)
{
- return array->size;
+ STATS(jniinvokation();)
+
+ return array->size;
}
-jobjectArray NewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init)
+/* NewObjectArray **************************************************************
+
+ Constructs a new array holding objects in class elementClass. All
+ elements are initially set to initialElement.
+
+*******************************************************************************/
+
+jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
{
- java_objectarray *j;
+ java_objectarray *oa;
+ s4 i;
+
+ STATS(jniinvokation();)
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
+ if (length < 0) {
+ *exceptionptr = new_negativearraysizeexception();
return NULL;
- }
+ }
- j = builtin_anewarray(len, clazz);
+ oa = builtin_anewarray(length, elementClass);
- return j;
+ if (!oa)
+ return NULL;
+
+ /* set all elements to initialElement */
+
+ for (i = 0; i < length; i++)
+ oa->data[i] = initialElement;
+
+ return (jobjectArray) NewLocalRef(env, (jobject) oa);
}
jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
{
- jobject j = NULL;
+ jobject o;
- if (index < array->header.size)
- j = array->data[index];
- else
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ STATS(jniinvokation();)
+
+ if (index >= array->header.size) {
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ return NULL;
+ }
+
+ o = array->data[index];
- return j;
+ return NewLocalRef(env, o);
}
void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
{
+ STATS(jniinvokation();)
if (index >= array->header.size)
*exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
}
-
jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
{
- java_booleanarray *j;
+ java_booleanarray *ba;
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
+ STATS(jniinvokation();)
+
+ if (len < 0) {
+ *exceptionptr = new_negativearraysizeexception();
return NULL;
- }
+ }
- j = builtin_newarray_boolean(len);
+ ba = builtin_newarray_boolean(len);
- return j;
+ return (jbooleanArray) NewLocalRef(env, (jobject) ba);
}
jbyteArray NewByteArray(JNIEnv *env, jsize len)
{
- java_bytearray *j;
+ java_bytearray *ba;
+
+ STATS(jniinvokation();)
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
+ if (len < 0) {
+ *exceptionptr = new_negativearraysizeexception();
return NULL;
- }
+ }
- j = builtin_newarray_byte(len);
+ ba = builtin_newarray_byte(len);
- return j;
+ return (jbyteArray) NewLocalRef(env, (jobject) ba);
}
jcharArray NewCharArray(JNIEnv *env, jsize len)
{
- java_chararray *j;
+ java_chararray *ca;
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
+ STATS(jniinvokation();)
+
+ if (len < 0) {
+ *exceptionptr = new_negativearraysizeexception();
return NULL;
- }
+ }
- j = builtin_newarray_char(len);
+ ca = builtin_newarray_char(len);
- return j;
+ return (jcharArray) NewLocalRef(env, (jobject) ca);
}
jshortArray NewShortArray(JNIEnv *env, jsize len)
{
- java_shortarray *j;
+ java_shortarray *sa;
+
+ STATS(jniinvokation();)
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
+ if (len < 0) {
+ *exceptionptr = new_negativearraysizeexception();
return NULL;
- }
+ }
- j = builtin_newarray_short(len);
+ sa = builtin_newarray_short(len);
- return j;
+ return (jshortArray) NewLocalRef(env, (jobject) sa);
}
jintArray NewIntArray(JNIEnv *env, jsize len)
{
- java_intarray *j;
+ java_intarray *ia;
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
+ STATS(jniinvokation();)
+
+ if (len < 0) {
+ *exceptionptr = new_negativearraysizeexception();
return NULL;
- }
+ }
- j = builtin_newarray_int(len);
+ ia = builtin_newarray_int(len);
- return j;
+ return (jintArray) NewLocalRef(env, (jobject) ia);
}
jlongArray NewLongArray(JNIEnv *env, jsize len)
{
- java_longarray *j;
+ java_longarray *la;
+
+ STATS(jniinvokation();)
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
+ if (len < 0) {
+ *exceptionptr = new_negativearraysizeexception();
return NULL;
- }
+ }
- j = builtin_newarray_long(len);
+ la = builtin_newarray_long(len);
- return j;
+ return (jlongArray) NewLocalRef(env, (jobject) la);
}
jfloatArray NewFloatArray(JNIEnv *env, jsize len)
{
- java_floatarray *j;
+ java_floatarray *fa;
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
+ STATS(jniinvokation();)
+
+ if (len < 0) {
+ *exceptionptr = new_negativearraysizeexception();
return NULL;
- }
+ }
- j = builtin_newarray_float(len);
+ fa = builtin_newarray_float(len);
- return j;
+ return (jfloatArray) NewLocalRef(env, (jobject) fa);
}
jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
{
- java_doublearray *j;
+ java_doublearray *da;
+
+ STATS(jniinvokation();)
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
+ if (len < 0) {
+ *exceptionptr = new_negativearraysizeexception();
return NULL;
- }
+ }
- j = builtin_newarray_double(len);
+ da = builtin_newarray_double(len);
- return j;
+ return (jdoubleArray) NewLocalRef(env, (jobject) da);
}
-jboolean * GetBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *isCopy)
-{
- if (isCopy) *isCopy = JNI_FALSE;
- return array->data;
-}
+/* Get<PrimitiveType>ArrayElements *********************************************
+
+ A family of functions that returns the body of the primitive array.
+*******************************************************************************/
-jbyte * GetByteArrayElements (JNIEnv *env, jbyteArray array, jboolean *isCopy)
+jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
+ jboolean *isCopy)
{
- if (isCopy) *isCopy = JNI_FALSE;
- return array->data;
-}
+ STATS(jniinvokation();)
+ if (isCopy)
+ *isCopy = JNI_FALSE;
-jchar * GetCharArrayElements (JNIEnv *env, jcharArray array, jboolean *isCopy)
-{
- if (isCopy) *isCopy = JNI_FALSE;
return array->data;
}
-jshort * GetShortArrayElements (JNIEnv *env, jshortArray array, jboolean *isCopy)
+jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
{
- if (isCopy) *isCopy = JNI_FALSE;
- return array->data;
-}
+ STATS(jniinvokation();)
+ if (isCopy)
+ *isCopy = JNI_FALSE;
-jint * GetIntArrayElements (JNIEnv *env, jintArray array, jboolean *isCopy)
-{
- if (isCopy) *isCopy = JNI_FALSE;
return array->data;
}
-jlong * GetLongArrayElements (JNIEnv *env, jlongArray array, jboolean *isCopy)
+jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
{
- if (isCopy) *isCopy = JNI_FALSE;
- return array->data;
-}
+ STATS(jniinvokation();)
+ if (isCopy)
+ *isCopy = JNI_FALSE;
-jfloat * GetFloatArrayElements (JNIEnv *env, jfloatArray array, jboolean *isCopy)
-{
- if (isCopy) *isCopy = JNI_FALSE;
return array->data;
}
-jdouble * GetDoubleArrayElements (JNIEnv *env, jdoubleArray array, jboolean *isCopy)
+jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
{
- if (isCopy) *isCopy = JNI_FALSE;
+ STATS(jniinvokation();)
+
+ if (isCopy)
+ *isCopy = JNI_FALSE;
+
return array->data;
}
-
-void ReleaseBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode)
+jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
{
- /* empty */
-}
+ STATS(jniinvokation();)
+ if (isCopy)
+ *isCopy = JNI_FALSE;
-void ReleaseByteArrayElements (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode)
-{
- /* empty */
+ return array->data;
}
-void ReleaseCharArrayElements (JNIEnv *env, jcharArray array, jchar *elems, jint mode)
+jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
{
- /* empty */
-}
+ STATS(jniinvokation();)
+ if (isCopy)
+ *isCopy = JNI_FALSE;
-void ReleaseShortArrayElements (JNIEnv *env, jshortArray array, jshort *elems, jint mode)
-{
- /* empty */
+ return array->data;
}
-void ReleaseIntArrayElements (JNIEnv *env, jintArray array, jint *elems, jint mode)
+jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
{
- /* empty */
-}
+ STATS(jniinvokation();)
+ if (isCopy)
+ *isCopy = JNI_FALSE;
-void ReleaseLongArrayElements (JNIEnv *env, jlongArray array, jlong *elems, jint mode)
-{
- /* empty */
+ return array->data;
}
-void ReleaseFloatArrayElements (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode)
+jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
+ jboolean *isCopy)
{
- /* empty */
-}
+ STATS(jniinvokation();)
+ if (isCopy)
+ *isCopy = JNI_FALSE;
-void ReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode)
-{
- /* empty */
+ return array->data;
}
-void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
-{
- if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+/* Release<PrimitiveType>ArrayElements *****************************************
- else
- memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
-}
+ A family of functions that informs the VM that the native code no
+ longer needs access to elems. The elems argument is a pointer
+ derived from array using the corresponding
+ Get<PrimitiveType>ArrayElements() function. If necessary, this
+ function copies back all changes made to elems to the original
+ array.
+*******************************************************************************/
-void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
+void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
+ jboolean *elems, jint mode)
{
- if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ STATS(jniinvokation();)
- else
- memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
+ if (elems != array->data) {
+ switch (mode) {
+ case JNI_COMMIT:
+ MCOPY(array->data, elems, jboolean, array->header.size);
+ break;
+ case 0:
+ MCOPY(array->data, elems, jboolean, array->header.size);
+ /* XXX TWISTI how should it be freed? */
+ break;
+ case JNI_ABORT:
+ /* XXX TWISTI how should it be freed? */
+ break;
+ }
+ }
}
-void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
+void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
+ jint mode)
{
- if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ STATS(jniinvokation();)
- else
- memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
+ if (elems != array->data) {
+ switch (mode) {
+ case JNI_COMMIT:
+ MCOPY(array->data, elems, jboolean, array->header.size);
+ break;
+ case 0:
+ MCOPY(array->data, elems, jboolean, array->header.size);
+ /* XXX TWISTI how should it be freed? */
+ break;
+ case JNI_ABORT:
+ /* XXX TWISTI how should it be freed? */
+ break;
+ }
+ }
}
-void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
+void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
+ jint mode)
{
- if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ STATS(jniinvokation();)
- else
- memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
+ if (elems != array->data) {
+ switch (mode) {
+ case JNI_COMMIT:
+ MCOPY(array->data, elems, jboolean, array->header.size);
+ break;
+ case 0:
+ MCOPY(array->data, elems, jboolean, array->header.size);
+ /* XXX TWISTI how should it be freed? */
+ break;
+ case JNI_ABORT:
+ /* XXX TWISTI how should it be freed? */
+ break;
+ }
+ }
}
-void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
+void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
+ jint mode)
{
- if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ STATS(jniinvokation();)
+
+ if (elems != array->data) {
+ switch (mode) {
+ case JNI_COMMIT:
+ MCOPY(array->data, elems, jboolean, array->header.size);
+ break;
+ case 0:
+ MCOPY(array->data, elems, jboolean, array->header.size);
+ /* XXX TWISTI how should it be freed? */
+ break;
+ case JNI_ABORT:
+ /* XXX TWISTI how should it be freed? */
+ break;
+ }
+ }
+}
+
+
+void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
+ jint mode)
+{
+ STATS(jniinvokation();)
+
+ if (elems != array->data) {
+ switch (mode) {
+ case JNI_COMMIT:
+ MCOPY(array->data, elems, jboolean, array->header.size);
+ break;
+ case 0:
+ MCOPY(array->data, elems, jboolean, array->header.size);
+ /* XXX TWISTI how should it be freed? */
+ break;
+ case JNI_ABORT:
+ /* XXX TWISTI how should it be freed? */
+ break;
+ }
+ }
+}
+
+
+void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
+ jint mode)
+{
+ STATS(jniinvokation();)
+
+ if (elems != array->data) {
+ switch (mode) {
+ case JNI_COMMIT:
+ MCOPY(array->data, elems, jboolean, array->header.size);
+ break;
+ case 0:
+ MCOPY(array->data, elems, jboolean, array->header.size);
+ /* XXX TWISTI how should it be freed? */
+ break;
+ case JNI_ABORT:
+ /* XXX TWISTI how should it be freed? */
+ break;
+ }
+ }
+}
+
+
+void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
+ jint mode)
+{
+ STATS(jniinvokation();)
+
+ if (elems != array->data) {
+ switch (mode) {
+ case JNI_COMMIT:
+ MCOPY(array->data, elems, jboolean, array->header.size);
+ break;
+ case 0:
+ MCOPY(array->data, elems, jboolean, array->header.size);
+ /* XXX TWISTI how should it be freed? */
+ break;
+ case JNI_ABORT:
+ /* XXX TWISTI how should it be freed? */
+ break;
+ }
+ }
+}
+
+
+void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
+ jdouble *elems, jint mode)
+{
+ STATS(jniinvokation();)
+
+ if (elems != array->data) {
+ switch (mode) {
+ case JNI_COMMIT:
+ MCOPY(array->data, elems, jboolean, array->header.size);
+ break;
+ case 0:
+ MCOPY(array->data, elems, jboolean, array->header.size);
+ /* XXX TWISTI how should it be freed? */
+ break;
+ case JNI_ABORT:
+ /* XXX TWISTI how should it be freed? */
+ break;
+ }
+ }
+}
+
+
+/* Get<PrimitiveType>ArrayRegion **********************************************
+
+ A family of functions that copies a region of a primitive array
+ into a buffer.
+
+*******************************************************************************/
+
+void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
+ jsize len, jboolean *buf)
+{
+ STATS(jniinvokation();)
+
+ if (start < 0 || len < 0 || start + len > array->header.size)
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
+ else
+ MCOPY(buf, &array->data[start], jboolean, len);
+}
+
+
+void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
+ jbyte *buf)
+{
+ STATS(jniinvokation();)
+
+ if (start < 0 || len < 0 || start + len > array->header.size)
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
else
- memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
+ MCOPY(buf, &array->data[start], jbyte, len);
}
-void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
+void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
+ jchar *buf)
{
+ STATS(jniinvokation();)
+
if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
else
- memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
+ MCOPY(buf, &array->data[start], jchar, len);
}
-void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
+void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
+ jsize len, jshort *buf)
{
+ STATS(jniinvokation();)
+
if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
+ else
+ MCOPY(buf, &array->data[start], jshort, len);
+}
+
+
+void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
+ jint *buf)
+{
+ STATS(jniinvokation();)
+
+ if (start < 0 || len < 0 || start + len > array->header.size)
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
+ else
+ MCOPY(buf, &array->data[start], jint, len);
+}
+
+
+void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
+ jlong *buf)
+{
+ STATS(jniinvokation();)
+
+ if (start < 0 || len < 0 || start + len > array->header.size)
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
else
- memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
+ MCOPY(buf, &array->data[start], jlong, len);
}
-void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
+void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
+ jsize len, jfloat *buf)
{
+ STATS(jniinvokation();)
+
+ if (start < 0 || len < 0 || start + len > array->header.size)
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
+ else
+ MCOPY(buf, &array->data[start], jfloat, len);
+}
+
+
+void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
+ jsize len, jdouble *buf)
+{
+ STATS(jniinvokation();)
+
if (start < 0 || len < 0 || start+len>array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
else
- memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
+ MCOPY(buf, &array->data[start], jdouble, len);
}
-void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
+/* Set<PrimitiveType>ArrayRegion **********************************************
+
+ A family of functions that copies back a region of a primitive
+ array from a buffer.
+
+*******************************************************************************/
+
+void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
+ jsize len, jboolean *buf)
{
+ STATS(jniinvokation();)
+
if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
else
- memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
+ MCOPY(&array->data[start], buf, jboolean, len);
}
-void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
+void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
+ jbyte *buf)
{
+ STATS(jniinvokation();)
+
if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
else
- memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
+ MCOPY(&array->data[start], buf, jbyte, len);
}
-void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
+void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
+ jchar *buf)
{
+ STATS(jniinvokation();)
+
if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
else
- memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
+ MCOPY(&array->data[start], buf, jchar, len);
}
-void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
+void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
+ jsize len, jshort *buf)
{
+ STATS(jniinvokation();)
+
if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
else
- memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
+ MCOPY(&array->data[start], buf, jshort, len);
}
-void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
+void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
+ jint *buf)
{
+ STATS(jniinvokation();)
+
if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
else
- memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
+ MCOPY(&array->data[start], buf, jint, len);
}
-void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
+void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
+ jlong *buf)
{
+ STATS(jniinvokation();)
+
if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
else
- memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
+ MCOPY(&array->data[start], buf, jlong, len);
}
-void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
+void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
+ jsize len, jfloat *buf)
{
+ STATS(jniinvokation();)
+
if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
else
- memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
+ MCOPY(&array->data[start], buf, jfloat, len);
}
-void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
+void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
+ jsize len, jdouble *buf)
{
+ STATS(jniinvokation();)
+
if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ *exceptionptr =
+ new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
else
- memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
+ MCOPY(&array->data[start], buf, jdouble, len);
}
-jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
+/* Registering Native Methods *************************************************/
+
+/* RegisterNatives *************************************************************
+
+ Registers native methods with the class specified by the clazz
+ argument. The methods parameter specifies an array of
+ JNINativeMethod structures that contain the names, signatures, and
+ function pointers of the native methods. The nMethods parameter
+ specifies the number of native methods in the array.
+
+*******************************************************************************/
+
+jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
+ jint nMethods)
{
- log_text("JNI-Call: RegisterNatives");
+ STATS(jniinvokation();)
+
+ log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
+
return 0;
}
-jint UnregisterNatives (JNIEnv* env, jclass clazz)
+/* UnregisterNatives ***********************************************************
+
+ Unregisters native methods of a class. The class goes back to the
+ state before it was linked or registered with its native method
+ functions.
+
+ This function should not be used in normal native code. Instead, it
+ provides special programs a way to reload and relink native
+ libraries.
+
+*******************************************************************************/
+
+jint UnregisterNatives(JNIEnv *env, jclass clazz)
{
- log_text("JNI-Call: UnregisterNatives");
+ STATS(jniinvokation();)
+
+ /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
+
+ log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
+
return 0;
}
-/******************************* monitor operations ********************************/
-jint MonitorEnter (JNIEnv* env, jobject obj)
+/* Monitor Operations *********************************************************/
+
+/* MonitorEnter ****************************************************************
+
+ Enters the monitor associated with the underlying Java object
+ referred to by obj.
+
+*******************************************************************************/
+
+jint MonitorEnter(JNIEnv *env, jobject obj)
{
- builtin_monitorenter(obj);
- return 0;
+ STATS(jniinvokation();)
+
+ if (!obj) {
+ *exceptionptr = new_nullpointerexception();
+ return JNI_ERR;
+ }
+
+#if defined(USE_THREADS)
+ builtin_monitorenter(obj);
+#endif
+
+ return JNI_OK;
}
-jint MonitorExit (JNIEnv* env, jobject obj)
+/* MonitorExit *****************************************************************
+
+ The current thread must be the owner of the monitor associated with
+ the underlying Java object referred to by obj. The thread
+ decrements the counter indicating the number of times it has
+ entered this monitor. If the value of the counter becomes zero, the
+ current thread releases the monitor.
+
+*******************************************************************************/
+
+jint MonitorExit(JNIEnv *env, jobject obj)
{
- builtin_monitorexit(obj);
- return 0;
+ STATS(jniinvokation();)
+ if (!obj) {
+ *exceptionptr = new_nullpointerexception();
+ return JNI_ERR;
+ }
+
+#if defined(USE_THREADS)
+ builtin_monitorexit(obj);
+#endif
+
+ return JNI_OK;
}
-/************************************* JavaVM interface ****************************/
-#ifdef __cplusplus
-#error CPP mode not supported yet
-#else
-jint GetJavaVM (JNIEnv* env, JavaVM **vm)
+/* JavaVM Interface ***********************************************************/
+
+/* GetJavaVM *******************************************************************
+
+ Returns the Java VM interface (used in the Invocation API)
+ associated with the current thread. The result is placed at the
+ location pointed to by the second argument, vm.
+
+*******************************************************************************/
+
+jint GetJavaVM(JNIEnv *env, JavaVM **vm)
{
- log_text("JNI-Call: GetJavaVM");
- *vm=&javaVM;
- return 0;
+ STATS(jniinvokation();)
+ *vm = &ptr_jvm;
+
+ return 0;
}
-#endif /*__cplusplus*/
+
void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
{
- log_text("JNI-Call: GetStringRegion");
-
+ STATS(jniinvokation();)
+ log_text("JNI-Call: GetStringRegion");
}
+
void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
{
- log_text("JNI-Call: GetStringUTFRegion");
+ STATS(jniinvokation();)
+ log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
}
-/************** obtain direct pointer to array elements ***********************/
-void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
+/* GetPrimitiveArrayCritical ***************************************************
+
+ Obtain a direct pointer to array elements.
+
+*******************************************************************************/
+
+void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
{
- java_objectheader *s = (java_objectheader*) array;
- arraydescriptor *desc = s->vftbl->arraydesc;
+ java_bytearray *ba;
+ jbyte *bp;
- if (!desc) return NULL;
+ ba = (java_bytearray *) array;
- return ((u1*)s) + desc->dataoffset;
+ /* do the same as Kaffe does */
+
+ bp = GetByteArrayElements(env, ba, isCopy);
+
+ return (void *) bp;
}
-void ReleasePrimitiveArrayCritical (JNIEnv* env, jarray array, void *carray, jint mode)
+/* ReleasePrimitiveArrayCritical ***********************************************
+
+ No specific documentation.
+
+*******************************************************************************/
+
+void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
+ jint mode)
{
- log_text("JNI-Call: ReleasePrimitiveArrayCritical");
+ STATS(jniinvokation();)
- /* empty */
+ /* do the same as Kaffe does */
+
+ ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
}
-/**** returns a pointer to an array of Unicode characters of the string *******/
-const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
+/* GetStringCritical ***********************************************************
+
+ The semantics of these two functions are similar to the existing
+ Get/ReleaseStringChars functions.
+
+*******************************************************************************/
+
+const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
{
- log_text("JNI-Call: GetStringCritical");
+ STATS(jniinvokation();)
- return GetStringChars(env,string,isCopy);
+ return GetStringChars(env, string, isCopy);
}
-/*********** native code no longer needs access to chars **********************/
-void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
+void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
{
- log_text("JNI-Call: ReleaseStringCritical");
+ STATS(jniinvokation();)
- ReleaseStringChars(env,string,cstring);
+ ReleaseStringChars(env, string, cstring);
}
jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: NewWeakGlobalRef");
return obj;
void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
{
+ STATS(jniinvokation();)
log_text("JNI-Call: DeleteWeakGlobalRef");
/* empty */
}
-/** Creates a new global reference to the object referred to by the obj argument **/
+/* NewGlobalRef ****************************************************************
+
+ Creates a new global reference to the object referred to by the obj
+ argument.
+
+*******************************************************************************/
jobject NewGlobalRef(JNIEnv* env, jobject lobj)
{
- jobject refcount;
- jint val;
- jobject newval;
+ java_lang_Integer *refcount;
+ java_objectheader *newval;
- MonitorEnter(env, *global_ref_table);
+ STATS(jniinvokation();)
+
+#if defined(USE_THREADS)
+ builtin_monitorenter(*global_ref_table);
+#endif
- refcount = CallObjectMethod(env, *global_ref_table, getmid, lobj);
- val = (refcount == NULL) ? 0 : CallIntMethod(env, refcount, intvalue);
- newval = NewObject(env, intclass, newint, val + 1);
+ refcount = (java_lang_Integer *)
+ asm_calljavafunction(getmid, *global_ref_table, lobj, NULL, NULL);
+
+ if (refcount == NULL) {
+ newval = native_new_and_init_int(class_java_lang_Integer, 1);
+
+ if (newval == NULL) {
+#if defined(USE_THREADS)
+ builtin_monitorexit(*global_ref_table);
+#endif
+ return NULL;
+ }
- if (newval != NULL) {
- CallObjectMethod(env, *global_ref_table, putmid, lobj, newval);
- MonitorExit(env, *global_ref_table);
- return lobj;
+ asm_calljavafunction(putmid, *global_ref_table, lobj, newval, NULL);
} else {
- log_text("JNI-NewGlobalRef: unable to create new java.lang.Integer");
- MonitorExit(env, *global_ref_table);
- return NULL;
+ /* we can access the object itself, as we are in a
+ synchronized section */
+
+ refcount->value++;
}
+
+#if defined(USE_THREADS)
+ builtin_monitorexit(*global_ref_table);
+#endif
+
+ return lobj;
}
-/************* Deletes the global reference pointed to by globalRef **************/
-void DeleteGlobalRef(JNIEnv* env, jobject gref)
+/* DeleteGlobalRef *************************************************************
+
+ Deletes the global reference pointed to by globalRef.
+
+*******************************************************************************/
+
+void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
{
- jobject refcount;
- jint val;
+ java_lang_Integer *refcount;
+ s4 val;
- MonitorEnter(env, *global_ref_table);
- refcount = CallObjectMethod(env, *global_ref_table, getmid, gref);
+ STATS(jniinvokation();)
+
+#if defined(USE_THREADS)
+ builtin_monitorenter(*global_ref_table);
+#endif
+
+ refcount = (java_lang_Integer *)
+ asm_calljavafunction(getmid, *global_ref_table, globalRef, NULL, NULL);
if (refcount == NULL) {
log_text("JNI-DeleteGlobalRef: unable to find global reference");
return;
}
- val = CallIntMethod(env, refcount, intvalue);
- val--;
+ /* we can access the object itself, as we are in a synchronized
+ section */
+
+ val = refcount->value - 1;
if (val == 0) {
- CallObjectMethod(env, *global_ref_table, removemid,refcount);
+ asm_calljavafunction(removemid, *global_ref_table, refcount, NULL,
+ NULL);
} else {
- jobject newval = NewObject(env, intclass, newint, val);
-
- if (newval != NULL) {
- CallObjectMethod(env,*global_ref_table, putmid,newval);
+ /* we do not create a new object, but set the new value into
+ the old one */
- } else {
- log_text("JNI-DeleteGlobalRef: unable to create new java.lang.Integer");
- }
+ refcount->value = val;
}
- MonitorExit(env,*global_ref_table);
+#if defined(USE_THREADS)
+ builtin_monitorexit(*global_ref_table);
+#endif
}
-/******************************* check for pending exception ***********************/
+/* ExceptionCheck **************************************************************
-jboolean ExceptionCheck(JNIEnv* env)
-{
- log_text("JNI-Call: ExceptionCheck");
+ Returns JNI_TRUE when there is a pending exception; otherwise,
+ returns JNI_FALSE.
+*******************************************************************************/
+
+jboolean ExceptionCheck(JNIEnv *env)
+{
+ STATS(jniinvokation();)
return *exceptionptr ? JNI_TRUE : JNI_FALSE;
}
+/* New JNI 1.4 functions ******************************************************/
+/* NewDirectByteBuffer *********************************************************
+ Allocates and returns a direct java.nio.ByteBuffer referring to the
+ block of memory starting at the memory address address and
+ extending capacity bytes.
+
+*******************************************************************************/
+
+jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
+{
+ java_nio_DirectByteBufferImpl *nbuf;
+#if SIZEOF_VOID_P == 8
+ gnu_classpath_Pointer64 *paddress;
+#else
+ gnu_classpath_Pointer32 *paddress;
+#endif
+
+ STATS(jniinvokation();)
+
+ log_text("JNI-NewDirectByteBuffer: called");
+
+ /* allocate a java.nio.DirectByteBufferImpl object */
+
+ if (!(nbuf = (java_nio_DirectByteBufferImpl *) builtin_new(class_java_nio_DirectByteBufferImpl)))
+ return NULL;
+
+ /* alocate a gnu.classpath.Pointer{32,64} object */
+
+#if SIZEOF_VOID_P == 8
+ if (!(paddress = (gnu_classpath_Pointer64 *) builtin_new(class_gnu_classpath_Pointer64)))
+#else
+ if (!(paddress = (gnu_classpath_Pointer32 *) builtin_new(class_gnu_classpath_Pointer32)))
+#endif
+ return NULL;
+
+ /* fill gnu.classpath.Pointer{32,64} with address */
+
+ paddress->data = (ptrint) address;
+
+ /* fill java.nio.Buffer object */
+
+ nbuf->cap = (s4) capacity;
+ nbuf->limit = (s4) capacity;
+ nbuf->pos = 0;
+ nbuf->address = (gnu_classpath_Pointer *) paddress;
+
+ /* add local reference and return the value */
+
+ return NewLocalRef(env, (jobject) nbuf);
+}
+
+
+/* GetDirectBufferAddress ******************************************************
+
+ Fetches and returns the starting address of the memory region
+ referenced by the given direct java.nio.Buffer.
+
+*******************************************************************************/
+
+void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
+{
+ java_nio_DirectByteBufferImpl *nbuf;
+#if SIZEOF_VOID_P == 8
+ gnu_classpath_Pointer64 *address;
+#else
+ gnu_classpath_Pointer32 *address;
+#endif
+
+ STATS(jniinvokation();)
+
+#if 0
+ if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
+ return NULL;
+#endif
+
+ nbuf = (java_nio_DirectByteBufferImpl *) buf;
+
+#if SIZEOF_VOID_P == 8
+ address = (gnu_classpath_Pointer64 *) nbuf->address;
+#else
+ address = (gnu_classpath_Pointer32 *) nbuf->address;
+#endif
+
+ return (void *) address->data;
+}
+
+
+/* GetDirectBufferCapacity *****************************************************
+
+ Fetches and returns the capacity in bytes of the memory region
+ referenced by the given direct java.nio.Buffer.
+
+*******************************************************************************/
+
+jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
+{
+ java_nio_Buffer *nbuf;
+
+ STATS(jniinvokation();)
+
+ if (buf == NULL)
+ return -1;
+
+ nbuf = (java_nio_Buffer *) buf;
+
+ return (jlong) nbuf->cap;
+}
jint DestroyJavaVM(JavaVM *vm)
{
+ STATS(jniinvokation();)
log_text("DestroyJavaVM called");
return 0;
}
-jint AttachCurrentThread(JavaVM *vm, void **par1, void *par2)
+/* AttachCurrentThread *********************************************************
+
+ Attaches the current thread to a Java VM. Returns a JNI interface
+ pointer in the JNIEnv argument.
+
+ Trying to attach a thread that is already attached is a no-op.
+
+ A native thread cannot be attached simultaneously to two Java VMs.
+
+ When a thread is attached to the VM, the context class loader is
+ the bootstrap loader.
+
+*******************************************************************************/
+
+jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
{
+ STATS(jniinvokation();)
+
log_text("AttachCurrentThread called");
+#if !defined(HAVE___THREAD)
+/* cacao_thread_attach();*/
+#else
+ #error "No idea how to implement that. Perhaps Stefan knows"
+#endif
+
+ *env = &ptr_env;
+
return 0;
}
jint DetachCurrentThread(JavaVM *vm)
{
+ STATS(jniinvokation();)
log_text("DetachCurrentThread called");
return 0;
}
-jint GetEnv(JavaVM *vm, void **environment, jint jniversion)
+/* GetEnv **********************************************************************
+
+ If the current thread is not attached to the VM, sets *env to NULL,
+ and returns JNI_EDETACHED. If the specified version is not
+ supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
+ sets *env to the appropriate interface, and returns JNI_OK.
+
+*******************************************************************************/
+
+jint GetEnv(JavaVM *vm, void **env, jint version)
{
- *environment = &env;
+ STATS(jniinvokation();)
- return 0;
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+ if (thread_getself() == NULL) {
+ *env = NULL;
+
+ return JNI_EDETACHED;
+ }
+#endif
+
+ if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
+ (version == JNI_VERSION_1_4)) {
+ *env = &ptr_env;
+
+ return JNI_OK;
+ }
+
+#if defined(ENABLE_JVMTI)
+ if (version == JVMTI_VERSION_1_0) {
+ *env = (void *) new_jvmtienv();
+
+ if (env != NULL)
+ return JNI_OK;
+ }
+#endif
+
+ *env = NULL;
+
+ return JNI_EVERSION;
}
+
jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
{
+ STATS(jniinvokation();)
log_text("AttachCurrentThreadAsDaemon called");
return 0;
}
-/************* JNI Initialization ****************************************************/
-jobject jni_init1(JNIEnv* env, jobject lobj) {
-#if defined(USE_THREADS)
- while (initrunning) {yieldThread();} /* wait until init is done */
-#endif
- if (global_ref_table == NULL) {
- jni_init();
- }
-#if defined(USE_THREADS)
- else {
- /* wait until jni_init is done */
- MonitorEnter(env, *global_ref_table) ;
- MonitorExit(env, *global_ref_table);
- }
-#endif
- return NewGlobalRef(env, lobj);
-}
-void jni_init2(JNIEnv* env, jobject gref) {
- log_text("DeleteGlobalref called before NewGlobalref");
-#if defined(USE_THREADS)
- while (initrunning) {yieldThread();} /* wait until init is done */
-#endif
- if (global_ref_table == NULL) {
- jni_init();
- }
-#if defined(USE_THREADS)
- else {
- /* wait until jni_init is done */
- MonitorEnter(env, *global_ref_table) ;
- MonitorExit(env, *global_ref_table);
- }
-#endif
- DeleteGlobalRef(env, gref);
-}
+/* JNI invocation table *******************************************************/
-void jni_init(){
- jmethodID mid;
+const struct JNIInvokeInterface JNI_JavaVMTable = {
+ NULL,
+ NULL,
+ NULL,
- initrunning = true;
- log_text("JNI-Init: initialize global_ref_table");
- /* initalize global reference table */
- ihmclass = FindClass(NULL, "java/util/IdentityHashMap");
-
- if (ihmclass == NULL) {
- log_text("JNI-Init: unable to find java.util.IdentityHashMap");
- }
+ DestroyJavaVM,
+ AttachCurrentThread,
+ DetachCurrentThread,
+ GetEnv,
+ AttachCurrentThreadAsDaemon
+};
- mid = GetMethodID(NULL, ihmclass, "<init>","()V");
- if (mid == NULL) {
- log_text("JNI-Init: unable to find constructor in java.util.IdentityHashMap");
- }
-
- global_ref_table = (jobject*)heap_allocate(sizeof(jobject),true,NULL);
- *global_ref_table = NewObject(NULL,ihmclass,mid);
+/* JNI function table *********************************************************/
+
+struct JNINativeInterface JNI_JNIEnvTable = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &GetVersion,
+
+ &DefineClass,
+ &FindClass,
+ &FromReflectedMethod,
+ &FromReflectedField,
+ &ToReflectedMethod,
+ &GetSuperclass,
+ &IsAssignableFrom,
+ &ToReflectedField,
+
+ &Throw,
+ &ThrowNew,
+ &ExceptionOccurred,
+ &ExceptionDescribe,
+ &ExceptionClear,
+ &FatalError,
+ &PushLocalFrame,
+ &PopLocalFrame,
+
+ &NewGlobalRef,
+ &DeleteGlobalRef,
+ &DeleteLocalRef,
+ &IsSameObject,
+ &NewLocalRef,
+ &EnsureLocalCapacity,
+
+ &AllocObject,
+ &NewObject,
+ &NewObjectV,
+ &NewObjectA,
+
+ &GetObjectClass,
+ &IsInstanceOf,
+
+ &GetMethodID,
+
+ &CallObjectMethod,
+ &CallObjectMethodV,
+ &CallObjectMethodA,
+ &CallBooleanMethod,
+ &CallBooleanMethodV,
+ &CallBooleanMethodA,
+ &CallByteMethod,
+ &CallByteMethodV,
+ &CallByteMethodA,
+ &CallCharMethod,
+ &CallCharMethodV,
+ &CallCharMethodA,
+ &CallShortMethod,
+ &CallShortMethodV,
+ &CallShortMethodA,
+ &CallIntMethod,
+ &CallIntMethodV,
+ &CallIntMethodA,
+ &CallLongMethod,
+ &CallLongMethodV,
+ &CallLongMethodA,
+ &CallFloatMethod,
+ &CallFloatMethodV,
+ &CallFloatMethodA,
+ &CallDoubleMethod,
+ &CallDoubleMethodV,
+ &CallDoubleMethodA,
+ &CallVoidMethod,
+ &CallVoidMethodV,
+ &CallVoidMethodA,
+
+ &CallNonvirtualObjectMethod,
+ &CallNonvirtualObjectMethodV,
+ &CallNonvirtualObjectMethodA,
+ &CallNonvirtualBooleanMethod,
+ &CallNonvirtualBooleanMethodV,
+ &CallNonvirtualBooleanMethodA,
+ &CallNonvirtualByteMethod,
+ &CallNonvirtualByteMethodV,
+ &CallNonvirtualByteMethodA,
+ &CallNonvirtualCharMethod,
+ &CallNonvirtualCharMethodV,
+ &CallNonvirtualCharMethodA,
+ &CallNonvirtualShortMethod,
+ &CallNonvirtualShortMethodV,
+ &CallNonvirtualShortMethodA,
+ &CallNonvirtualIntMethod,
+ &CallNonvirtualIntMethodV,
+ &CallNonvirtualIntMethodA,
+ &CallNonvirtualLongMethod,
+ &CallNonvirtualLongMethodV,
+ &CallNonvirtualLongMethodA,
+ &CallNonvirtualFloatMethod,
+ &CallNonvirtualFloatMethodV,
+ &CallNonvirtualFloatMethodA,
+ &CallNonvirtualDoubleMethod,
+ &CallNonvirtualDoubleMethodV,
+ &CallNonvirtualDoubleMethodA,
+ &CallNonvirtualVoidMethod,
+ &CallNonvirtualVoidMethodV,
+ &CallNonvirtualVoidMethodA,
+
+ &GetFieldID,
+
+ &GetObjectField,
+ &GetBooleanField,
+ &GetByteField,
+ &GetCharField,
+ &GetShortField,
+ &GetIntField,
+ &GetLongField,
+ &GetFloatField,
+ &GetDoubleField,
+ &SetObjectField,
+ &SetBooleanField,
+ &SetByteField,
+ &SetCharField,
+ &SetShortField,
+ &SetIntField,
+ &SetLongField,
+ &SetFloatField,
+ &SetDoubleField,
+
+ &GetStaticMethodID,
+
+ &CallStaticObjectMethod,
+ &CallStaticObjectMethodV,
+ &CallStaticObjectMethodA,
+ &CallStaticBooleanMethod,
+ &CallStaticBooleanMethodV,
+ &CallStaticBooleanMethodA,
+ &CallStaticByteMethod,
+ &CallStaticByteMethodV,
+ &CallStaticByteMethodA,
+ &CallStaticCharMethod,
+ &CallStaticCharMethodV,
+ &CallStaticCharMethodA,
+ &CallStaticShortMethod,
+ &CallStaticShortMethodV,
+ &CallStaticShortMethodA,
+ &CallStaticIntMethod,
+ &CallStaticIntMethodV,
+ &CallStaticIntMethodA,
+ &CallStaticLongMethod,
+ &CallStaticLongMethodV,
+ &CallStaticLongMethodA,
+ &CallStaticFloatMethod,
+ &CallStaticFloatMethodV,
+ &CallStaticFloatMethodA,
+ &CallStaticDoubleMethod,
+ &CallStaticDoubleMethodV,
+ &CallStaticDoubleMethodA,
+ &CallStaticVoidMethod,
+ &CallStaticVoidMethodV,
+ &CallStaticVoidMethodA,
+
+ &GetStaticFieldID,
+
+ &GetStaticObjectField,
+ &GetStaticBooleanField,
+ &GetStaticByteField,
+ &GetStaticCharField,
+ &GetStaticShortField,
+ &GetStaticIntField,
+ &GetStaticLongField,
+ &GetStaticFloatField,
+ &GetStaticDoubleField,
+ &SetStaticObjectField,
+ &SetStaticBooleanField,
+ &SetStaticByteField,
+ &SetStaticCharField,
+ &SetStaticShortField,
+ &SetStaticIntField,
+ &SetStaticLongField,
+ &SetStaticFloatField,
+ &SetStaticDoubleField,
+
+ &NewString,
+ &GetStringLength,
+ &GetStringChars,
+ &ReleaseStringChars,
+
+ &NewStringUTF,
+ &GetStringUTFLength,
+ &GetStringUTFChars,
+ &ReleaseStringUTFChars,
+
+ &GetArrayLength,
+
+ &NewObjectArray,
+ &GetObjectArrayElement,
+ &SetObjectArrayElement,
+
+ &NewBooleanArray,
+ &NewByteArray,
+ &NewCharArray,
+ &NewShortArray,
+ &NewIntArray,
+ &NewLongArray,
+ &NewFloatArray,
+ &NewDoubleArray,
+
+ &GetBooleanArrayElements,
+ &GetByteArrayElements,
+ &GetCharArrayElements,
+ &GetShortArrayElements,
+ &GetIntArrayElements,
+ &GetLongArrayElements,
+ &GetFloatArrayElements,
+ &GetDoubleArrayElements,
+
+ &ReleaseBooleanArrayElements,
+ &ReleaseByteArrayElements,
+ &ReleaseCharArrayElements,
+ &ReleaseShortArrayElements,
+ &ReleaseIntArrayElements,
+ &ReleaseLongArrayElements,
+ &ReleaseFloatArrayElements,
+ &ReleaseDoubleArrayElements,
+
+ &GetBooleanArrayRegion,
+ &GetByteArrayRegion,
+ &GetCharArrayRegion,
+ &GetShortArrayRegion,
+ &GetIntArrayRegion,
+ &GetLongArrayRegion,
+ &GetFloatArrayRegion,
+ &GetDoubleArrayRegion,
+ &SetBooleanArrayRegion,
+ &SetByteArrayRegion,
+ &SetCharArrayRegion,
+ &SetShortArrayRegion,
+ &SetIntArrayRegion,
+ &SetLongArrayRegion,
+ &SetFloatArrayRegion,
+ &SetDoubleArrayRegion,
+
+ &RegisterNatives,
+ &UnregisterNatives,
+
+ &MonitorEnter,
+ &MonitorExit,
+
+ &GetJavaVM,
+
+ /* new JNI 1.2 functions */
+
+ &GetStringRegion,
+ &GetStringUTFRegion,
+
+ &GetPrimitiveArrayCritical,
+ &ReleasePrimitiveArrayCritical,
+
+ &GetStringCritical,
+ &ReleaseStringCritical,
+
+ &NewWeakGlobalRef,
+ &DeleteWeakGlobalRef,
+
+ &ExceptionCheck,
+
+ /* new JNI 1.4 functions */
+
+ &NewDirectByteBuffer,
+ &GetDirectBufferAddress,
+ &GetDirectBufferCapacity
+};
- if (*global_ref_table == NULL) {
- log_text("JNI-Init: unable to create new global_ref_table");
- }
- initrunning = false;
+/* Invocation API Functions ***************************************************/
- getmid = GetMethodID(NULL, ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
- if (mid == NULL) {
- log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
- }
+/* JNI_GetDefaultJavaVMInitArgs ************************************************
- getmid = GetMethodID(NULL ,ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
- if (getmid == NULL) {
- log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
- }
+ Returns a default configuration for the Java VM.
- putmid = GetMethodID(NULL, ihmclass, "put","(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
- if (putmid == NULL) {
- log_text("JNI-Init: unable to find method \"put\" in java.util.IdentityHashMap");
- }
+*******************************************************************************/
- intclass = FindClass(NULL, "java/lang/Integer");
- if (intclass == NULL) {
- log_text("JNI-Init: unable to find java.lang.Integer");
- }
+jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
+{
+ JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
- newint = GetMethodID(NULL, intclass, "<init>","(I)V");
- if (newint == NULL) {
- log_text("JNI-Init: unable to find constructor in java.lang.Integer");
- }
+ /* GNU classpath currently supports JNI 1.2 */
- intvalue = GetMethodID(NULL, intclass, "intValue","()I");
- if (intvalue == NULL) {
- log_text("JNI-Init: unable to find method \"intValue\" in java.lang.Integer");
- }
+ _vm_args->version = JNI_VERSION_1_2;
- removemid = GetMethodID(NULL, ihmclass, "remove","(Ljava/lang/Object;)Ljava/lang/Object;");
- if (removemid == NULL) {
- log_text("JNI-DeleteGlobalRef: unable to find method \"remove\" in java.lang.Object");
- }
-
- /* set NewGlobalRef, DeleteGlobalRef envTable entry to real implementation */
- envTable.NewGlobalRef = &NewGlobalRef;
- envTable.DeleteGlobalRef = &DeleteGlobalRef;
+ return 0;
}
-/********************************* JNI invocation table ******************************/
+/* JNI_GetCreatedJavaVMs *******************************************************
-struct _JavaVM javaVMTable={
- NULL,
- NULL,
- NULL,
- &DestroyJavaVM,
- &AttachCurrentThread,
- &DetachCurrentThread,
- &GetEnv,
- &AttachCurrentThreadAsDaemon
-};
+ Returns all Java VMs that have been created. Pointers to VMs are written in
+ the buffer vmBuf in the order they are created. At most bufLen number of
+ entries will be written. The total number of created VMs is returned in
+ *nVMs.
-JavaVM javaVM = &javaVMTable;
-
-
-/********************************* JNI function table ******************************/
-
-struct JNI_Table envTable = {
- NULL,
- NULL,
- NULL,
- NULL,
- &GetVersion,
- &DefineClass,
- &FindClass,
- &FromReflectedMethod,
- &FromReflectedField,
- &ToReflectedMethod,
- &GetSuperclass,
- &IsAssignableForm,
- &ToReflectedField,
- &Throw,
- &ThrowNew,
- &ExceptionOccurred,
- &ExceptionDescribe,
- &ExceptionClear,
- &FatalError,
- &PushLocalFrame,
- &PopLocalFrame,
- &jni_init1, /* &NewGlobalRef, initialize Global_Ref_Table*/
- &jni_init2, /* &DeleteGlobalRef,*/
- &DeleteLocalRef,
- &IsSameObject,
- &NewLocalRef,
- &EnsureLocalCapacity,
- &AllocObject,
- &NewObject,
- &NewObjectV,
- &NewObjectA,
- &GetObjectClass,
- &IsInstanceOf,
- &GetMethodID,
- &CallObjectMethod,
- &CallObjectMethodV,
- &CallObjectMethodA,
- &CallBooleanMethod,
- &CallBooleanMethodV,
- &CallBooleanMethodA,
- &CallByteMethod,
- &CallByteMethodV,
- &CallByteMethodA,
- &CallCharMethod,
- &CallCharMethodV,
- &CallCharMethodA,
- &CallShortMethod,
- &CallShortMethodV,
- &CallShortMethodA,
- &CallIntMethod,
- &CallIntMethodV,
- &CallIntMethodA,
- &CallLongMethod,
- &CallLongMethodV,
- &CallLongMethodA,
- &CallFloatMethod,
- &CallFloatMethodV,
- &CallFloatMethodA,
- &CallDoubleMethod,
- &CallDoubleMethodV,
- &CallDoubleMethodA,
- &CallVoidMethod,
- &CallVoidMethodV,
- &CallVoidMethodA,
- &CallNonvirtualObjectMethod,
- &CallNonvirtualObjectMethodV,
- &CallNonvirtualObjectMethodA,
- &CallNonvirtualBooleanMethod,
- &CallNonvirtualBooleanMethodV,
- &CallNonvirtualBooleanMethodA,
- &CallNonvirtualByteMethod,
- &CallNonvirtualByteMethodV,
- &CallNonvirtualByteMethodA,
- &CallNonvirtualCharMethod,
- &CallNonvirtualCharMethodV,
- &CallNonvirtualCharMethodA,
- &CallNonvirtualShortMethod,
- &CallNonvirtualShortMethodV,
- &CallNonvirtualShortMethodA,
- &CallNonvirtualIntMethod,
- &CallNonvirtualIntMethodV,
- &CallNonvirtualIntMethodA,
- &CallNonvirtualLongMethod,
- &CallNonvirtualLongMethodV,
- &CallNonvirtualLongMethodA,
- &CallNonvirtualFloatMethod,
- &CallNonvirtualFloatMethodV,
- &CallNonvirtualFloatMethodA,
- &CallNonvirtualDoubleMethod,
- &CallNonvirtualDoubleMethodV,
- &CallNonvirtualDoubleMethodA,
- &CallNonvirtualVoidMethod,
- &CallNonvirtualVoidMethodV,
- &CallNonvirtualVoidMethodA,
- &GetFieldID,
- &GetObjectField,
- &GetBooleanField,
- &GetByteField,
- &GetCharField,
- &GetShortField,
- &GetIntField,
- &GetLongField,
- &GetFloatField,
- &GetDoubleField,
- &SetObjectField,
- &SetBooleanField,
- &SetByteField,
- &SetCharField,
- &SetShortField,
- &SetIntField,
- &SetLongField,
- &SetFloatField,
- &SetDoubleField,
- &GetStaticMethodID,
- &CallStaticObjectMethod,
- &CallStaticObjectMethodV,
- &CallStaticObjectMethodA,
- &CallStaticBooleanMethod,
- &CallStaticBooleanMethodV,
- &CallStaticBooleanMethodA,
- &CallStaticByteMethod,
- &CallStaticByteMethodV,
- &CallStaticByteMethodA,
- &CallStaticCharMethod,
- &CallStaticCharMethodV,
- &CallStaticCharMethodA,
- &CallStaticShortMethod,
- &CallStaticShortMethodV,
- &CallStaticShortMethodA,
- &CallStaticIntMethod,
- &CallStaticIntMethodV,
- &CallStaticIntMethodA,
- &CallStaticLongMethod,
- &CallStaticLongMethodV,
- &CallStaticLongMethodA,
- &CallStaticFloatMethod,
- &CallStaticFloatMethodV,
- &CallStaticFloatMethodA,
- &CallStaticDoubleMethod,
- &CallStaticDoubleMethodV,
- &CallStaticDoubleMethodA,
- &CallStaticVoidMethod,
- &CallStaticVoidMethodV,
- &CallStaticVoidMethodA,
- &GetStaticFieldID,
- &GetStaticObjectField,
- &GetStaticBooleanField,
- &GetStaticByteField,
- &GetStaticCharField,
- &GetStaticShortField,
- &GetStaticIntField,
- &GetStaticLongField,
- &GetStaticFloatField,
- &GetStaticDoubleField,
- &SetStaticObjectField,
- &SetStaticBooleanField,
- &SetStaticByteField,
- &SetStaticCharField,
- &SetStaticShortField,
- &SetStaticIntField,
- &SetStaticLongField,
- &SetStaticFloatField,
- &SetStaticDoubleField,
- &NewString,
- &GetStringLength,
- &GetStringChars,
- &ReleaseStringChars,
- &NewStringUTF,
- &GetStringUTFLength,
- &GetStringUTFChars,
- &ReleaseStringUTFChars,
- &GetArrayLength,
- &NewObjectArray,
- &GetObjectArrayElement,
- &SetObjectArrayElement,
- &NewBooleanArray,
- &NewByteArray,
- &NewCharArray,
- &NewShortArray,
- &NewIntArray,
- &NewLongArray,
- &NewFloatArray,
- &NewDoubleArray,
- &GetBooleanArrayElements,
- &GetByteArrayElements,
- &GetCharArrayElements,
- &GetShortArrayElements,
- &GetIntArrayElements,
- &GetLongArrayElements,
- &GetFloatArrayElements,
- &GetDoubleArrayElements,
- &ReleaseBooleanArrayElements,
- &ReleaseByteArrayElements,
- &ReleaseCharArrayElements,
- &ReleaseShortArrayElements,
- &ReleaseIntArrayElements,
- &ReleaseLongArrayElements,
- &ReleaseFloatArrayElements,
- &ReleaseDoubleArrayElements,
- &GetBooleanArrayRegion,
- &GetByteArrayRegion,
- &GetCharArrayRegion,
- &GetShortArrayRegion,
- &GetIntArrayRegion,
- &GetLongArrayRegion,
- &GetFloatArrayRegion,
- &GetDoubleArrayRegion,
- &SetBooleanArrayRegion,
- &SetByteArrayRegion,
- &SetCharArrayRegion,
- &SetShortArrayRegion,
- &SetIntArrayRegion,
- &SetLongArrayRegion,
- &SetFloatArrayRegion,
- &SetDoubleArrayRegion,
- &RegisterNatives,
- &UnregisterNatives,
- &MonitorEnter,
- &MonitorExit,
- &GetJavaVM,
- &GetStringRegion,
- &GetStringUTFRegion,
- &GetPrimitiveArrayCritical,
- &ReleasePrimitiveArrayCritical,
- &GetStringCritical,
- &ReleaseStringCritical,
- &NewWeakGlobalRef,
- &DeleteWeakGlobalRef,
- &ExceptionCheck
-};
+*******************************************************************************/
+
+jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
+{
+ log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
+
+ return 0;
+}
+
+
+/* JNI_CreateJavaVM ************************************************************
+
+ Loads and initializes a Java VM. The current thread becomes the main thread.
+ Sets the env argument to the JNI interface pointer of the main thread.
-JNIEnv env = &envTable;
+*******************************************************************************/
+
+jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
+{
+ const struct JNIInvokeInterface *vm;
+ struct JNINativeInterface *env;
+
+ vm = &JNI_JavaVMTable;
+ env = &JNI_JNIEnvTable;
+ *p_vm = (JavaVM *) vm;
+ *p_env = (JNIEnv *) env;
+
+ return 0;
+}
-jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID, jobject obj, java_objectarray *params)
+
+jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
+ jobject obj, java_objectarray *params)
{
- int argcount;
jni_callblock *blk;
- char retT;
- jobject retVal;
+ jobject o;
+ s4 argcount;
+ s4 paramcount;
if (methodID == 0) {
*exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return NULL;
}
- argcount = get_parametercount(methodID);
+ argcount = methodID->parseddesc->paramcount;
+ paramcount = argcount;
- if (obj && (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
- *exceptionptr = new_exception_message(string_java_lang_IllegalArgumentException,
- "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
- return 0;
- }
+ /* if method is non-static, remove the `this' pointer */
+ if (!(methodID->flags & ACC_STATIC))
+ paramcount--;
-#ifdef arglimit
- if (argcount > 3) {
- *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
- log_text("Too many arguments. invokeNativeHelper does not support that");
- return 0;
+ /* the method is an instance method the obj has to be an instance of the
+ class the method belongs to. For static methods the obj parameter
+ is ignored. */
+
+ if (!(methodID->flags & ACC_STATIC) && obj &&
+ (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
+ *exceptionptr =
+ new_exception_message(string_java_lang_IllegalArgumentException,
+ "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
+ return NULL;
}
-#endif
- if (((params==0) && (argcount != 0)) || (params && (params->header.size != argcount))) {
- *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
- return 0;
+
+ if (((params == NULL) && (paramcount != 0)) ||
+ (params && (params->header.size != paramcount))) {
+ *exceptionptr =
+ new_exception(string_java_lang_IllegalArgumentException);
+ return NULL;
}
- if (((methodID->flags & ACC_STATIC)==0) && (0==obj)) {
+ if (!(methodID->flags & ACC_STATIC) && !obj) {
*exceptionptr =
new_exception_message(string_java_lang_NullPointerException,
"Static mismatch in Java_java_lang_reflect_Method_invokeNative");
- return 0;
+ return NULL;
}
- if ((methodID->flags & ACC_STATIC) && (obj)) obj = 0;
+ if ((methodID->flags & ACC_STATIC) && (obj))
+ obj = NULL;
if (obj) {
- if ( (methodID->flags & ACC_ABSTRACT) || (methodID->class->flags & ACC_INTERFACE) ) {
- methodID=get_virtual(obj,methodID);
+ if ((methodID->flags & ACC_ABSTRACT) ||
+ (methodID->class->flags & ACC_INTERFACE)) {
+ methodID = get_virtual(obj, methodID);
}
}
- blk = MNEW(jni_callblock, /*4 */argcount+2);
+ blk = MNEW(jni_callblock, argcount);
- retT = fill_callblock_objA(obj, methodID->descriptor, blk, params);
+ if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
+ params))
+ return NULL;
- switch (retT) {
- case 'V':
- (void) asm_calljavafunction2(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
+ switch (methodID->parseddesc->returntype.decltype) {
+ case TYPE_VOID:
+ (void) asm_calljavafunction2(methodID, argcount,
+ argcount * sizeof(jni_callblock),
blk);
- retVal = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
+ o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
break;
- case 'I': {
- s4 intVal;
- intVal = (s4) asm_calljavafunction2(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
- blk);
- retVal = builtin_new(class_new(utf_new_char("java/lang/Integer")));
- CallVoidMethod(env,
- retVal,
- class_resolvemethod(retVal->vftbl->class,
- utf_new_char("<init>"),
- utf_new_char("(I)V")),
- intVal);
+ case PRIMITIVETYPE_INT: {
+ s4 i;
+ i = asm_calljavafunction2int(methodID, argcount,
+ argcount * sizeof(jni_callblock),
+ blk);
+
+ o = native_new_and_init_int(class_java_lang_Integer, i);
}
break;
- case 'B': {
- s4 intVal;
- intVal = (s4) asm_calljavafunction2(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
- blk);
- retVal = builtin_new(class_new(utf_new_char("java/lang/Byte")));
+ case PRIMITIVETYPE_BYTE: {
+ s4 i;
+ i = asm_calljavafunction2int(methodID, argcount,
+ argcount * sizeof(jni_callblock),
+ blk);
+
+/* o = native_new_and_init_int(class_java_lang_Byte, i); */
+ o = builtin_new(class_java_lang_Byte);
CallVoidMethod(env,
- retVal,
- class_resolvemethod(retVal->vftbl->class,
- utf_new_char("<init>"),
- utf_new_char("(B)V")),
- intVal);
+ o,
+ class_resolvemethod(o->vftbl->class,
+ utf_init,
+ utf_byte__void),
+ i);
}
break;
- case 'C': {
- s4 intVal;
- intVal = (s4) asm_calljavafunction2(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
- blk);
- retVal = builtin_new(class_new(utf_new_char("java/lang/Character")));
+ case PRIMITIVETYPE_CHAR: {
+ s4 intVal;
+ intVal = asm_calljavafunction2int(methodID,
+ argcount,
+ argcount * sizeof(jni_callblock),
+ blk);
+ o = builtin_new(class_java_lang_Character);
CallVoidMethod(env,
- retVal,
- class_resolvemethod(retVal->vftbl->class,
- utf_new_char("<init>"),
- utf_new_char("(C)V")),
+ o,
+ class_resolvemethod(o->vftbl->class,
+ utf_init,
+ utf_char__void),
intVal);
}
break;
- case 'S': {
- s4 intVal;
- intVal = (s4) asm_calljavafunction2(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
- blk);
- retVal = builtin_new(class_new(utf_new_char("java/lang/Short")));
+ case PRIMITIVETYPE_SHORT: {
+ s4 intVal;
+ intVal = asm_calljavafunction2int(methodID,
+ argcount,
+ argcount * sizeof(jni_callblock),
+ blk);
+ o = builtin_new(class_java_lang_Short);
CallVoidMethod(env,
- retVal,
- class_resolvemethod(retVal->vftbl->class,
- utf_new_char("<init>"),
- utf_new_char("(S)V")),
+ o,
+ class_resolvemethod(o->vftbl->class,
+ utf_init,
+ utf_short__void),
intVal);
}
break;
- case 'Z': {
- s4 intVal;
- intVal = (s4) asm_calljavafunction2(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
- blk);
- retVal = builtin_new(class_new(utf_new_char("java/lang/Boolean")));
+ case PRIMITIVETYPE_BOOLEAN: {
+ s4 intVal;
+ intVal = asm_calljavafunction2int(methodID,
+ argcount,
+ argcount * sizeof(jni_callblock),
+ blk);
+ o = builtin_new(class_java_lang_Boolean);
CallVoidMethod(env,
- retVal,
- class_resolvemethod(retVal->vftbl->class,
- utf_new_char("<init>"),
- utf_new_char("(Z)V")),
+ o,
+ class_resolvemethod(o->vftbl->class,
+ utf_init,
+ utf_boolean__void),
intVal);
}
break;
- case 'J': {
- jlong intVal;
- intVal = asm_calljavafunction2long(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
- blk);
- retVal = builtin_new(class_new(utf_new_char("java/lang/Long")));
+ case PRIMITIVETYPE_LONG: {
+ jlong longVal;
+ longVal = asm_calljavafunction2long(methodID,
+ argcount,
+ argcount * sizeof(jni_callblock),
+ blk);
+ o = builtin_new(class_java_lang_Long);
CallVoidMethod(env,
- retVal,
- class_resolvemethod(retVal->vftbl->class,
- utf_new_char("<init>"),
- utf_new_char("(J)V")),
- intVal);
+ o,
+ class_resolvemethod(o->vftbl->class,
+ utf_init,
+ utf_long__void),
+ longVal);
}
break;
- case 'F': {
+ case PRIMITIVETYPE_FLOAT: {
jdouble floatVal;
- floatVal = asm_calljavafunction2double(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
- blk);
- retVal = builtin_new(class_new(utf_new_char("java/lang/Float")));
+ floatVal = asm_calljavafunction2float(methodID,
+ argcount,
+ argcount * sizeof(jni_callblock),
+ blk);
+ o = builtin_new(class_java_lang_Float);
CallVoidMethod(env,
- retVal,
- class_resolvemethod(retVal->vftbl->class,
- utf_new_char("<init>"),
- utf_new_char("(F)V")),
+ o,
+ class_resolvemethod(o->vftbl->class,
+ utf_init,
+ utf_float__void),
floatVal);
}
break;
- case 'D': {
- jdouble floatVal;
- floatVal = asm_calljavafunction2double(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
- blk);
- retVal = builtin_new(class_new(utf_new_char("java/lang/Double")));
+ case PRIMITIVETYPE_DOUBLE: {
+ jdouble doubleVal;
+ doubleVal = asm_calljavafunction2double(methodID,
+ argcount,
+ argcount * sizeof(jni_callblock),
+ blk);
+ o = builtin_new(class_java_lang_Double);
CallVoidMethod(env,
- retVal,
- class_resolvemethod(retVal->vftbl->class,
- utf_new_char("<init>"),
- utf_new_char("(D)V")),
- floatVal);
+ o,
+ class_resolvemethod(o->vftbl->class,
+ utf_init,
+ utf_double__void),
+ doubleVal);
}
break;
- case 'L': /* fall through */
- case '[':
- retVal = asm_calljavafunction2(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
- blk);
+ case TYPE_ADR:
+ o = asm_calljavafunction2(methodID, argcount,
+ argcount * sizeof(jni_callblock), blk);
break;
default:
- /* if this happens the acception has already been set by fill_callblock_objA*/
- MFREE(blk, jni_callblock, /*4 */ argcount+2);
+ /* if this happens the exception has already been set by */
+ /* fill_callblock_from_objectarray */
+
+ MFREE(blk, jni_callblock, argcount);
return (jobject *) 0;
}
- MFREE(blk, jni_callblock, /* 4 */ argcount+2);
+ MFREE(blk, jni_callblock, argcount);
if (*exceptionptr) {
- java_objectheader *exceptionToWrap = *exceptionptr;
- classinfo *ivtec;
- java_objectheader *ivte;
+ java_objectheader *cause;
- *exceptionptr = NULL;
- ivtec = class_new(utf_new_char("java/lang/reflect/InvocationTargetException"));
- ivte = builtin_new(ivtec);
- asm_calljavafunction(class_resolvemethod(ivtec,
- utf_new_char("<init>"),
- utf_new_char("(Ljava/lang/Throwable;)V")),
- ivte,
- exceptionToWrap,
- 0,
- 0);
+ cause = *exceptionptr;
+
+ /* clear exception pointer, we are calling JIT code again */
- if (*exceptionptr != NULL)
- panic("jni.c: error while creating InvocationTargetException wrapper");
+ *exceptionptr = NULL;
- *exceptionptr = ivte;
+ *exceptionptr =
+ new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
+ (java_lang_Throwable *) cause);
}
- return (jobject *) retVal;
+ return (jobject *) o;
}
-
-
/*
* These are local overrides for various environment variables in Emacs.
* Please do not remove this and leave it at the end of the file, where