Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
- P. Tomsich, J. Wenninger
+ P. Tomsich, J. Wenninger, M. Platter
This file is part of CACAO.
Authors: ?
- Changes: Joseph Wenninger
+ Changes: Joseph Wenninger, Martin Platter
- $Id: jni.c 724 2003-12-09 18:56:11Z edwin $
+ $Id: jni.c 1426 2004-11-01 12:21:59Z twisti $
*/
#include <string.h>
+#include "exceptions.h"
+#include "main.h"
#include "jni.h"
#include "global.h"
#include "loader.h"
#include "tables.h"
#include "native.h"
#include "builtin.h"
+#include "options.h"
+#include "statistics.h"
#include "threads/thread.h"
-#include "toolbox/loging.h"
+#include "toolbox/logging.h"
#include "toolbox/memory.h"
#include "nat/java_lang_Byte.h"
#include "nat/java_lang_Character.h"
#include "nat/java_lang_Double.h"
#include "nat/java_lang_Throwable.h"
#include "jit/jit.h"
-#include "asmpart.h"
+#include "asmpart.h"
+#include "mm/boehm.h"
#define JNI_VERSION 0x00010002
+#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_float = 0;
static utf* utf_double = 0;
+/* global reference table */
+static jobject *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;
+
/********************* accessing instance-fields **********************************/
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 */
- java_objectarray* result;
- int parametercount = 0;
- int i;
+ 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;
- /* skip '(' */
- utf_nextu2(&utf_ptr);
+ /* skip '(' */
+ utf_nextu2(&utf_ptr);
/* determine number of parameters */
- while ( *utf_ptr != ')' ) {
- get_type(&utf_ptr,desc_end,true);
- parametercount++;
- }
+ while (*utf_ptr != ')') {
+ get_type(&utf_ptr, desc_end, true);
+ parametercount++;
+ }
- return parametercount;
+ return parametercount;
}
-void fill_callblock(void *obj,utf *descr,jni_callblock blk[], va_list data, char ret) {
- 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 */
-
+void fill_callblock(void *obj, utf *descr, jni_callblock blk[], va_list data, char ret)
+{
+ 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;
-
- jdouble d;
- jlong l;
u4 dummy;
char c;
+
/*
log_text("fill_callblock");
utf_display(descr);
utf_nextu2(utf_ptr);
/* determine number of parameters */
- if (obj) {
- blk[0].itemtype=TYPE_ADR;
- blk[0].item=(u8)(u4)obj;
- cnt=1;
- } else cnt=0;
- while ( **utf_ptr != ')' ) {
- if (*utf_ptr>=desc_end)
+ 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;
- 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;
-
- case 'J' :
- blk[cnt].itemtype=TYPE_LNG;
- blk[cnt].item=(u8)va_arg(data,jlong);
- break;
- case 'F' :
- blk[cnt].itemtype=TYPE_FLT;
- *((jfloat*)(&blk[cnt].item))=((jfloat)va_arg(data,jdouble));
- break;
-
- case 'D' :
- blk[cnt].itemtype=TYPE_DBL;
- *((jdouble*)(&blk[cnt].item))=(jdouble)va_arg(data,jdouble);
- break;
- 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=(u8)(u4)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)!=';') {}
- }
+ 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;
+
+ 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;
+
+ case 'J':
+ blk[cnt].itemtype = TYPE_LNG;
+ blk[cnt].item = (u8) va_arg(data, jlong);
+ break;
+
+ case 'F':
+ blk[cnt].itemtype = TYPE_FLT;
+ *((jfloat *) (&blk[cnt].item)) = (jfloat) va_arg(data, jdouble);
+ break;
+
+ case 'D':
+ blk[cnt].itemtype = TYPE_DBL;
+ *((jdouble *) (&blk[cnt].item)) = (jdouble) va_arg(data, jdouble);
+ break;
+
+ 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=(u8)(u4)va_arg(data,void*);
- break;
- }
+ ch = utf_nextu2(utf_ptr);
+ blk[cnt].itemtype = TYPE_ADR;
+ blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
+ break;
+ }
+ }
+ cnt++;
}
- 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====");
+ /*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====");
}
+
/* 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)
{
- 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 */
+ 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 */
jobject param;
int cnt;
int cnts;
-
- u4 dummy;
char c;
- char *cp;
+
+#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_float=utf_new_char("java/lang/Float");
utf_double=utf_new_char("java/lang/Double");
}
+#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
intsRestore();
+#endif
/*
log_text("fill_callblock");
/* determine number of parameters */
if (obj) {
blk[0].itemtype = TYPE_ADR;
- blk[0].item = (u8)(u4)obj;
+ blk[0].item = PTR_TO_ITEM(obj);
cnt=1;
} else {
cnt = 0;
}
- cnts=0;
+ cnts = 0;
while (**utf_ptr != ')') {
if (*utf_ptr >= desc_end)
panic("illegal method descriptor");
/* primitive types */
switch (utf_nextu2(utf_ptr)) {
- case 'B':
- param=params->data[cnts];
- if (param==0) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- return 0;
- }
- if (param->vftbl->class->name==utf_byte) {
- blk[cnt].itemtype=TYPE_INT;
- blk[cnt].item = (u8) ((struct java_lang_Byte * )param)->value;
- } else {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- return 0;
- }
- break;
+ 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;
+ }
+ break;
+
case 'C':
- param=params->data[cnts];
- if (param==0) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- return 0;
- }
- if (param->vftbl->class->name==utf_char) {
- blk[cnt].itemtype=TYPE_INT;
- blk[cnt].item = (u8) ((struct java_lang_Character * )param)->value;
- } else {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- return 0;
- }
- break;
+ 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;
- case 'S':
- param=params->data[cnts];
- if (param==0) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ } else {
+ *exceptionptr = new_exception("java/lang/IllegalArgumentException");
+ return 0;
+ }
+ 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;
}
- if (param->vftbl->class->name==utf_short) {
- blk[cnt].itemtype=TYPE_INT;
- blk[cnt].item = (u8) ((struct java_lang_Short* )param)->value;
+ }
+ 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 '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) ((struct java_lang_Byte * )param)->value;
- } else {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ 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;
}
}
- break;
+ }
+ break;
- case 'Z':
- param=params->data[cnts];
- if (param==0) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- return 0;
- }
- if (param->vftbl->class->name==utf_bool) {
- blk[cnt].itemtype=TYPE_INT;
- blk[cnt].item = (u8) ((struct java_lang_Boolean * )param)->value;
- } else {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- return 0;
- }
- 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;
- case 'I':
- /*log_text("fill_callblock_objA: param 'I'");*/
- param=params->data[cnts];
- if (param==0) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- return 0;
- }
- if (param->vftbl->class->name==utf_int) {
- blk[cnt].itemtype=TYPE_INT;
- blk[cnt].item = (u8) ((struct 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) ((struct java_lang_Short* )param)->value;
- } else {
- if (param->vftbl->class->name==utf_byte) {
- blk[cnt].itemtype=TYPE_INT;
- blk[cnt].item = (u8) ((struct java_lang_Byte * )param)->value;
+ 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=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ *exceptionptr = new_exception("java/lang/IllegalArgumentException");
return 0;
}
}
}
- break;
- case 'J':
- param=params->data[cnts];
- if (param==0) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- return 0;
- }
- if (param->vftbl->class->name==utf_long) {
- blk[cnt].itemtype=TYPE_LNG;
- blk[cnt].item = (u8) ((struct java_lang_Long * )param)->value;
- } else {
- if (param->vftbl->class->name==utf_int) {
- blk[cnt].itemtype=TYPE_LNG;
- blk[cnt].item = (u8) ((struct java_lang_Integer * )param)->value;
- } else {
- if (param->vftbl->class->name==utf_short) {
- blk[cnt].itemtype=TYPE_LNG;
- blk[cnt].item = (u8) ((struct java_lang_Short* )param)->value;
- } else {
- if (param->vftbl->class->name==utf_byte) {
- blk[cnt].itemtype=TYPE_LNG;
- blk[cnt].item = (u8) ((struct java_lang_Byte * )param)->value;
- } else {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- return 0;
- }
- }
- }
- }
- break;
+ }
+ break;
- case 'F' :
- param=params->data[cnts];
- if (param==0) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- return 0;
- }
+ 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;
+ }
+ 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;
- if (param->vftbl->class->name==utf_float) {
- blk[cnt].itemtype=TYPE_FLT;
- *((jfloat*)(&blk[cnt].item))=(jfloat) ((struct java_lang_Float*)param)->value;
} else {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- return 0;
- }
- break;
- case 'D' :
- param=params->data[cnts];
- if (param==0) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ *exceptionptr = new_exception("java/lang/IllegalArgumentException");
return 0;
}
+ }
+ break;
- if (param->vftbl->class->name==utf_double) {
- blk[cnt].itemtype=TYPE_DBL;
- *((jdouble*)(&blk[cnt].item))=(jdouble) ((struct java_lang_Float*)param)->value;
- } else {
- if (param->vftbl->class->name==utf_float) {
- blk[cnt].itemtype=TYPE_DBL;
- *((jdouble*)(&blk[cnt].item))=(jdouble) ((struct java_lang_Float*)param)->value;
- } else {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- return 0;
- }
- }
- break;
case 'V':
panic("V not allowed as function parameter");
break;
- case 'L': {
- char *start=(*utf_ptr)-1;
- char *end;
+ case 'L':
+ {
+ char *start = (*utf_ptr) - 1;
+ char *end = NULL;
while (utf_nextu2(utf_ptr) != ';')
- end=(*utf_ptr)+1;
- if (!builtin_instanceof(params->data[cnts],class_from_descriptor(start,end,0,CLASSLOAD_LOAD))) {
- if (params->data[cnts]!=0) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ end = (*utf_ptr) + 1;
+
+ if (!builtin_instanceof(params->data[cnts], class_from_descriptor(start, end, 0, CLASSLOAD_LOAD))) {
+ if (params->data[cnts] != 0) {
+ *exceptionptr = new_exception("java/lang/IllegalArgumentException");
return 0;
}
}
- blk[cnt].itemtype = TYPE_ADR;
- blk[cnt].item= (u8)(u4) (params->data[cnts]);
+
+ blk[cnt].itemtype = TYPE_ADR;
+ blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
break;
+ }
- }
- case '[' :
+ case '[':
{
- char *start=(*utf_ptr)-1;
+ char *start = (*utf_ptr) - 1;
char *end;
char ch;
if (ch == 'L') {
while (utf_nextu2(utf_ptr) != ';') {}
}
- end=(*utf_ptr)-1;
+
+ end = (*utf_ptr) - 1;
ch = utf_nextu2(utf_ptr);
- if (!builtin_arrayinstanceof(params->data[cnts],class_from_descriptor(start,end,0,CLASSLOAD_LOAD))) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+
+ if (!builtin_arrayinstanceof(params->data[cnts], class_from_descriptor(start, end, 0, CLASSLOAD_LOAD)->vftbl)) {
+ *exceptionptr = new_exception("java/lang/IllegalArgumentException");
return 0;
-
}
blk[cnt].itemtype = TYPE_ADR;
- blk[cnt].item = (u8)(u4) (params->data[cnts]);
+ blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
break;
}
}
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);
}
jni_callblock *blk;
jobject 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");
- */
+
if (methodID == 0) {
- exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return 0;
}
if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
- exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return 0;
}
-
+
if (obj && !builtin_instanceof(obj, methodID->class)) {
- exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return 0;
}
+#ifdef arglimit
+
if (argcount > 3) {
- exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ *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, 'O');
-
/* printf("parameter: obj: %p",blk[0].item); */
ret = asm_calljavafunction2(methodID,
argcount + 1,
(argcount + 1) * sizeof(jni_callblock),
blk);
-
MFREE(blk, jni_callblock, argcount + 1);
/* printf("(CallObjectMethodV)-->%p\n",ret); */
+
return ret;
}
printf("\n");
*/
if (methodID == 0) {
- exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return 0;
}
if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
- exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return 0;
}
if (obj && !builtin_instanceof(obj, methodID->class)) {
- exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return 0;
}
-
+#ifdef arglimit
if (argcount > 3) {
- exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- log_text("Too many arguments. CallObjectMethod does not support that");
+ *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
+ log_text("Too many arguments. CallIntegerMethod does not support that");
return 0;
}
+#endif
blk = MNEW(jni_callblock, 4 /*argcount+2*/);
jni_callblock *blk;
jlong 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");
- */
+*/
if (methodID == 0) {
- exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return 0;
}
if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
- exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return 0;
}
if (obj && !builtin_instanceof(obj,methodID->class)) {
- exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return 0;
}
-
+#ifdef arglimit
if (argcount > 3) {
- exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ *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, 'L');
+ fill_callblock(obj, methodID->descriptor, blk, args, 'J');
/* printf("parameter: obj: %p",blk[0].item); */
ret = asm_calljavafunction2long(methodID,
printf("\n");
*/
+#ifdef arglimit
if (argcount > 3) {
- exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ *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*/);
return JNI_VERSION;
}
-/****************** loads a class from a buffer of raw class data *****************/
+
+/************** loads a class from a buffer of raw class data *****************/
jclass DefineClass(JNIEnv* env, const char *name, jobject loader, const jbyte *buf, jsize len)
{
- jclass clazz;
+ jclass c;
+ jclass r;
+ classbuffer *cb;
+
+ c = class_new(utf_new_char_classname((char *) name));
+
+ /* enter a monitor on the class */
+
+ builtin_monitorenter((java_objectheader *) c);
+
+ /* measure time */
+ if (getloadingtime)
+ loadingtime_start();
+
+ /* 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;
+
+ r = class_load_intern(cb);
+
+ /* if return value is NULL, we had a problem and the class is not loaded */
+ if (!r) {
+ c->loaded = false;
+
+ /* now free the allocated memory, otherwise we could ran into a DOS */
+ class_remove(c);
+ }
+
+ /* free memory */
+ FREE(cb, classbuffer);
+
+ /* measure time */
+ if (getloadingtime)
+ loadingtime_stop();
+
+ /* leave the monitor */
- /* change suck-mode, so subsequent class_load will read from memory-buffer */
- classload_buffer( (u1*) buf,len);
+ builtin_monitorexit((java_objectheader *) c);
- clazz = loader_load(utf_new_char ((char *) name));
+ /* XXX link the class here? */
+/* if (class_link(c)) */
+/* return NULL; */
- /* restore old suck-mode */
- classload_buffer(NULL,0);
+ if (r)
+ c->classloader = loader;
- return clazz;
+ return r;
}
-/*************** loads locally defined class with the specified name **************/
+/*********** loads locally defined class with the specified name **************/
-jclass FindClass (JNIEnv* env, const char *name)
+jclass FindClass(JNIEnv* env, const char *name)
{
classinfo *c;
-/* if (strcmp(name,"[B")==0) {
- c = loader_load(utf_new_char("The_Array_Class"));
- }
- else*/
- c = loader_load(utf_new_char_classname ((char *) name));
+ c = class_new(utf_new_char_classname((char *) name));
+
+ if (!class_load(c))
+ return NULL;
- if (!c) exceptionptr = native_new_and_init(class_java_lang_ClassFormatError);
+ if (!class_link(c))
+ return NULL;
return c;
}
-/***********************************************************************************
+/*******************************************************************************
converts java.lang.reflect.Method or
java.lang.reflect.Constructor object to a method ID
- **********************************************************************************/
+*******************************************************************************/
jmethodID FromReflectedMethod(JNIEnv* env, jobject method)
{
jint Throw(JNIEnv* env, jthrowable obj)
{
- exceptionptr = (java_objectheader*) obj;
+ *exceptionptr = (java_objectheader*) obj;
return 0;
}
-/***********************************************************************************
+/*******************************************************************************
create exception object from the class clazz with the
specified message and cause it to be thrown
- **********************************************************************************/
-
+*******************************************************************************/
-jint ThrowNew (JNIEnv* env, jclass clazz, const char *msg)
+jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
{
java_lang_Throwable *o;
/* instantiate exception object */
- o = (java_lang_Throwable *) native_new_and_init ((classinfo*) clazz);
+ o = (java_lang_Throwable *) native_new_and_init((classinfo*) clazz);
if (!o) return (-1);
- o->detailMessage = (java_lang_String*) javastring_new_char((char *) msg);
+ o->detailMessage = (java_lang_String *) javastring_new_char((char *) msg);
+
+ *exceptionptr = (java_objectheader *) o;
- exceptionptr = (java_objectheader*) o;
return 0;
}
+
/************************* check if exception occured *****************************/
jthrowable ExceptionOccurred (JNIEnv* env)
{
- return (jthrowable) exceptionptr;
+ return (jthrowable) *exceptionptr;
}
/********** print exception and a backtrace of the stack (for debugging) **********/
void ExceptionDescribe (JNIEnv* env)
{
- utf_display(exceptionptr->vftbl->class->name);
+ utf_display((*exceptionptr)->vftbl->class->name);
printf ("\n");
fflush (stdout);
}
void ExceptionClear (JNIEnv* env)
{
- exceptionptr = NULL;
+ *exceptionptr = NULL;
}
jobject PopLocalFrame(JNIEnv* env, jobject result)
{
+ log_text("JNI-Call: PopLocalFrame");
/* empty */
return NULL;
}
-
-
-/** Creates a new global reference to the object referred to by the obj argument **/
-
-jobject NewGlobalRef(JNIEnv* env, jobject lobj)
-{
- heap_addreference((void**) &lobj);
-
- return lobj;
-}
-
-/************* Deletes the global reference pointed to by globalRef **************/
-
-void DeleteGlobalRef (JNIEnv* env, jobject gref)
-{
- /* empty */
-}
/*************** Deletes the local reference pointed to by localRef ***************/
void DeleteLocalRef (JNIEnv* env, jobject localRef)
{
+/* log_text("JNI-Call: DeleteLocalRef");*/
/* empty */
}
/* log_text("JNI-Call: NewObject"); */
- if (argcount>3) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+#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 */
args[i]=va_arg(vaargs,void*);
}
va_end(vaargs);
- exceptionptr=asm_calljavamethod(methodID,o,args[0],args[1],args[2]);
+ asm_calljavafunction(methodID,o,args[0],args[1],args[2]);
return o;
}
jclass GetObjectClass(JNIEnv* env, jobject obj)
{
classinfo *c = obj->vftbl->class;
-/* log_text("GetObjectClass");
- utf_display(obj->vftbl->class->name);*/
+
use_class_as_object(c);
- /*printf("\nPointer: %p\n",c);*/
return c;
}
utf_new_char ((char*) sig)
);
- if (!m) exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
-
+ if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+ else if (m->flags & ACC_STATIC) {
+ m=0;
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+ }
return m;
}
jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
{
- log_text("JNI-Call: CallLongMethod");
+ jlong ret;
+ va_list vaargs;
+
+ va_start(vaargs,methodID);
+ ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
+ va_end(vaargs);
- return 0;
+ return ret;
}
jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
{
- log_text("JNI-Call: CallLongMethodV");
-
- return 0;
+ return callLongMethod(obj,get_virtual(obj, methodID),args);
}
);
if (!f) {
-/* utf_display(clazz->name);
+ utf_display(clazz->name);
log_text(name);
- log_text(sig);*/
- exceptionptr = native_new_and_init(class_java_lang_NoSuchFieldError);
+ log_text(sig);
+ *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
}
return f;
}
jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
{
- return getField(obj,jobject,fieldID);
+ jobject dbg,dretval,*dpretval;
+ long int dli1, dli2, dli3;
+
+/* 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);*/
+
+ 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;
+
+ 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);*/
+
+
+ return dbg;
}
jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
setField(obj,jdouble,fieldID,val);
}
+
/**************** JNI-functions for calling static methods **********************/
-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;
- m = class_resolvemethod (
- clazz,
- utf_new_char ((char*) name),
- utf_new_char ((char*) sig)
- );
+ m = class_resolvemethod(clazz,
+ utf_new_char((char *) name),
+ utf_new_char((char *) sig));
- if (!m) exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+ if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+ else if (!(m->flags & ACC_STATIC)) {
+ m=0;
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+ }
return m;
}
-jobject CallStaticObjectMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
+
+jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
{
- log_text("JNI-Call: CallStaticObjectMethod");
+ jobject ret;
+ va_list vaargs;
- return NULL;
+ /* log_text("JNI-Call: CallStaticObjectMethod");*/
+
+ va_start(vaargs, methodID);
+ ret = callObjectMethod(0, methodID, vaargs);
+ va_end(vaargs);
+
+ return ret;
}
-jobject CallStaticObjectMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
+jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
{
- log_text("JNI-Call: CallStaticObjectMethodV");
-
- return NULL;
+ /* log_text("JNI-Call: CallStaticObjectMethodV"); */
+
+ return callObjectMethod(0,methodID,args);
}
-jobject CallStaticObjectMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
+jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
{
log_text("JNI-Call: CallStaticObjectMethodA");
}
-jboolean CallStaticBooleanMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
+jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
{
- jboolean ret;
- va_list vaargs;
-
-/* log_text("JNI-Call: CallStaticBooleanMethod");*/
+ jboolean ret;
+ va_list vaargs;
- va_start(vaargs,methodID);
- ret = (jboolean)callIntegerMethod(0,methodID,'Z',vaargs);
- va_end(vaargs);
- return ret;
+ va_start(vaargs, methodID);
+ ret = (jboolean) callIntegerMethod(0, methodID, 'Z', vaargs);
+ va_end(vaargs);
+ return ret;
}
return (jboolean) callIntegerMethod(0, methodID, 'Z', args);
}
+
jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
{
log_text("JNI-Call: CallStaticBooleanMethodA");
/* log_text("JNI-Call: CallStaticByteMethod");*/
- va_start(vaargs,methodID);
+ va_start(vaargs, methodID);
ret = (jshort) callIntegerMethod(0, methodID, 'S', vaargs);
va_end(vaargs);
utf_new_char ((char*) sig)
);
- if (!f) exceptionptr = native_new_and_init(class_java_lang_NoSuchFieldError);
+ if (!f) *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
return f;
}
jstring NewStringUTF (JNIEnv *env, const char *utf)
{
/* log_text("NewStringUTF called");*/
- return javastring_new(utf_new_char(utf));
+ return (jstring) javastring_new(utf_new_char((char *) utf));
}
/****************** returns the utf8 length in bytes of a string *******************/
return (jsize) u2_utflength(s->value->data, s->count);
}
+
/************ converts a Javastring to an array of UTF-8 characters ****************/
-const char* GetStringUTFChars (JNIEnv *env, jstring string, jboolean *isCopy)
+const char* GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
{
utf *u;
- if (verbose) log_text("GetStringUTFChars:");
- u=javastring_toutf((java_lang_String*) string,false);
- if (isCopy) *isCopy=JNI_FALSE;
- if (u) {
- return u->text;
- }
+ u = javastring_toutf((java_lang_String *) string, false);
+
+ if (isCopy)
+ *isCopy = JNI_FALSE;
+
+ if (u)
+ return u->text;
+
return emptyString;
}
+
/***************** native code no longer needs access to utf ***********************/
void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
/************************** array operations ***************************************/
-jsize GetArrayLength (JNIEnv *env, jarray array)
+jsize GetArrayLength(JNIEnv *env, jarray array)
{
return array->size;
}
+
jobjectArray NewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init)
{
java_objectarray *j;
- if (len<0) {
- exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+ if (len < 0) {
+ *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
return NULL;
}
- j = builtin_anewarray (len, clazz);
- if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
+ j = builtin_anewarray(len, clazz);
+
return j;
}
-jobject GetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index)
+
+jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
{
jobject j = NULL;
- if (index<array->header.size)
- j = array->data[index];
+ if (index < array->header.size)
+ j = array->data[index];
else
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
return j;
}
-void SetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index, jobject val)
+
+void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
{
- if (index>=array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
- else {
+ if (index >= array->header.size)
+ *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
- /* check if the class of value is a subclass of the element class of the array */
+ else {
+ /* check if the class of value is a subclass of the element class of the array */
+ if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
+ *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
- if (!builtin_canstore((java_objectarray*)array,(java_objectheader*)val))
- exceptionptr = proto_java_lang_ArrayStoreException;
else
array->data[index] = val;
}
-jbooleanArray NewBooleanArray (JNIEnv *env, jsize len)
+jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
{
java_booleanarray *j;
- if (len<0) {
- exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+ if (len < 0) {
+ *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
return NULL;
}
+
j = builtin_newarray_boolean(len);
- if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
return j;
}
-jbyteArray NewByteArray (JNIEnv *env, jsize len)
+jbyteArray NewByteArray(JNIEnv *env, jsize len)
{
java_bytearray *j;
- if (len<0) {
- exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+ if (len < 0) {
+ *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
return NULL;
}
+
j = builtin_newarray_byte(len);
- if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
return j;
}
-jcharArray NewCharArray (JNIEnv *env, jsize len)
+jcharArray NewCharArray(JNIEnv *env, jsize len)
{
java_chararray *j;
- if (len<0) {
- exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+ if (len < 0) {
+ *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
return NULL;
}
+
j = builtin_newarray_char(len);
- if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
return j;
}
-jshortArray NewShortArray (JNIEnv *env, jsize len)
+jshortArray NewShortArray(JNIEnv *env, jsize len)
{
java_shortarray *j;
- if (len<0) {
- exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+ if (len < 0) {
+ *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
return NULL;
}
- j = builtin_newarray_short(len);
- if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
+ j = builtin_newarray_short(len);
+
return j;
}
-jintArray NewIntArray (JNIEnv *env, jsize len)
+jintArray NewIntArray(JNIEnv *env, jsize len)
{
java_intarray *j;
- if (len<0) {
- exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+ if (len < 0) {
+ *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
return NULL;
}
+
j = builtin_newarray_int(len);
- if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
return j;
}
-jlongArray NewLongArray (JNIEnv *env, jsize len)
+jlongArray NewLongArray(JNIEnv *env, jsize len)
{
java_longarray *j;
- if (len<0) {
- exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+ if (len < 0) {
+ *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
return NULL;
}
+
j = builtin_newarray_long(len);
- if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
return j;
}
-jfloatArray NewFloatArray (JNIEnv *env, jsize len)
+jfloatArray NewFloatArray(JNIEnv *env, jsize len)
{
java_floatarray *j;
- if (len<0) {
- exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+ if (len < 0) {
+ *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
return NULL;
}
+
j = builtin_newarray_float(len);
- if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
return j;
}
-jdoubleArray NewDoubleArray (JNIEnv *env, jsize len)
+jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
{
java_doublearray *j;
- if (len<0) {
- exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+ if (len < 0) {
+ *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
return NULL;
}
+
j = builtin_newarray_double(len);
- if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
return j;
}
/* empty */
}
-void GetBooleanArrayRegion (JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
+
+void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
{
- if (start<0 || len<0 || start+len>array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ 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]));
+ memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
}
-void GetByteArrayRegion (JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
+void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
{
- if (start<0 || len<0 || start+len>array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ 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]));
+ memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
}
-void GetCharArrayRegion (JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
+void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
{
- if (start<0 || len<0 || start+len>array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ 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]));
+ memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
}
-void GetShortArrayRegion (JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
+void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
{
- if (start<0 || len<0 || start+len>array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ 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]));
+ memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
}
-void GetIntArrayRegion (JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
+void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
{
- if (start<0 || len<0 || start+len>array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ 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]));
+ memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
}
-void GetLongArrayRegion (JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
+void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
{
- if (start<0 || len<0 || start+len>array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ 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]));
+ memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
}
-void GetFloatArrayRegion (JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
+void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
{
- if (start<0 || len<0 || start+len>array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ 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]));
+ memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
}
-void GetDoubleArrayRegion (JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
+void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
{
- if (start<0 || len<0 || start+len>array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ 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]));
+ memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
}
-void SetBooleanArrayRegion (JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
+void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
{
- if (start<0 || len<0 || start+len>array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ if (start < 0 || len < 0 || start + len > array->header.size)
+ *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
else
- memcpy(&array->data[start],buf,len*sizeof(array->data[0]));
+ memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
}
-void SetByteArrayRegion (JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
+void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
{
- if (start<0 || len<0 || start+len>array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ if (start < 0 || len < 0 || start + len > array->header.size)
+ *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
else
- memcpy(&array->data[start],buf,len*sizeof(array->data[0]));
+ memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
}
-void SetCharArrayRegion (JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
+void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
{
- if (start<0 || len<0 || start+len>array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ if (start < 0 || len < 0 || start + len > array->header.size)
+ *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
else
- memcpy(&array->data[start],buf,len*sizeof(array->data[0]));
+ memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
}
-void SetShortArrayRegion (JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
+void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
{
- if (start<0 || len<0 || start+len>array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ if (start < 0 || len < 0 || start + len > array->header.size)
+ *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
else
- memcpy(&array->data[start],buf,len*sizeof(array->data[0]));
+ memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
}
-void SetIntArrayRegion (JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
+void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
{
- if (start<0 || len<0 || start+len>array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ if (start < 0 || len < 0 || start + len > array->header.size)
+ *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
else
- memcpy(&array->data[start],buf,len*sizeof(array->data[0]));
+ memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
}
-void SetLongArrayRegion (JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
+
+void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
{
- if (start<0 || len<0 || start+len>array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ if (start < 0 || len < 0 || start + len > array->header.size)
+ *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
else
- memcpy(&array->data[start],buf,len*sizeof(array->data[0]));
+ memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
}
-void SetFloatArrayRegion (JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
+
+void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
{
- if (start<0 || len<0 || start+len>array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ if (start < 0 || len < 0 || start + len > array->header.size)
+ *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
else
- memcpy(&array->data[start],buf,len*sizeof(array->data[0]));
+ memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
}
-void SetDoubleArrayRegion (JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
+
+void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
{
- if (start<0 || len<0 || start+len>array->header.size)
- exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+ if (start < 0 || len < 0 || start + len > array->header.size)
+ *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
else
- memcpy(&array->data[start],buf,len*sizeof(array->data[0]));
+ memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
}
+
jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
{
log_text("JNI-Call: RegisterNatives");
}
-/****************** obtain direct pointer to array elements ***********************/
+/************** obtain direct pointer to array elements ***********************/
void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
{
/* empty */
}
-/********* returns a pointer to an array of Unicode characters of the string *******/
+/**** returns a pointer to an array of Unicode characters of the string *******/
const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
{
return GetStringChars(env,string,isCopy);
}
-/**************** native code no longer needs access to chars **********************/
+/*********** native code no longer needs access to chars **********************/
void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
{
}
+/** 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;
+
+ MonitorEnter(env, *global_ref_table);
+
+ refcount = CallObjectMethod(env, *global_ref_table, getmid, lobj);
+ val = (refcount == NULL) ? 0 : CallIntMethod(env, refcount, intvalue);
+ newval = NewObject(env, intclass, newint, val + 1);
+
+ if (newval != NULL) {
+ CallObjectMethod(env, *global_ref_table, putmid, lobj, newval);
+ MonitorExit(env, *global_ref_table);
+ return lobj;
+
+ } else {
+ log_text("JNI-NewGlobalRef: unable to create new java.lang.Integer");
+ MonitorExit(env, *global_ref_table);
+ return NULL;
+ }
+}
+
+/************* Deletes the global reference pointed to by globalRef **************/
+
+void DeleteGlobalRef(JNIEnv* env, jobject gref)
+{
+ jobject refcount;
+ jint val;
+
+ MonitorEnter(env, *global_ref_table);
+ refcount = CallObjectMethod(env, *global_ref_table, getmid, gref);
+
+ if (refcount == NULL) {
+ log_text("JNI-DeleteGlobalRef: unable to find global reference");
+ return;
+ }
+
+ val = CallIntMethod(env, refcount, intvalue);
+ val--;
+
+ if (val == 0) {
+ CallObjectMethod(env, *global_ref_table, removemid,refcount);
+
+ } else {
+ jobject newval = NewObject(env, intclass, newint, val);
+
+ if (newval != NULL) {
+ CallObjectMethod(env,*global_ref_table, putmid,newval);
+
+ } else {
+ log_text("JNI-DeleteGlobalRef: unable to create new java.lang.Integer");
+ }
+ }
+
+ MonitorExit(env,*global_ref_table);
+}
+
/******************************* check for pending exception ***********************/
{
log_text("JNI-Call: ExceptionCheck");
- return exceptionptr ? JNI_TRUE : JNI_FALSE;
+ return *exceptionptr ? JNI_TRUE : JNI_FALSE;
}
}
-
-
-
-
-
-
-
-
-
/********************************* JNI invocation table ******************************/
struct _JavaVM javaVMTable={
&ExceptionCheck
};
-
JNIEnv env = &envTable;
-
-
-
-
-
-
-jobject *jni_method_invokeNativeHelper(JNIEnv *env,struct methodinfo *methodID,jobject obj, java_objectarray *params) {
+jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID, jobject obj, java_objectarray *params)
+{
int argcount;
jni_callblock *blk;
- jobject ret;
char retT;
jobject retVal;
- if (methodID==0) {
- exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
- return 0;
+
+ if (methodID == 0) {
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+ return NULL;
}
- argcount=get_parametercount(methodID);
- if (obj && (!builtin_instanceof((java_objectheader*)obj,methodID->class))) {
- (*env)->ThrowNew(env,loader_load(utf_new_char("java/lang/IllegalArgumentException")),
- "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
- return 0;
- }
+ argcount = get_parametercount(methodID);
+ 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 (argcount>3) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+#ifdef arglimit
+ if (argcount > 3) {
+ *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
log_text("Too many arguments. invokeNativeHelper does not support that");
return 0;
}
+#endif
- if ( ((!params) && (argcount!=0)) ||
- (params && (params->header.size!=argcount))
- ) {
- exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ if (((!params) && (argcount != 0)) || (params && (params->header.size != argcount))) {
+ *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
return 0;
}
- if (!(methodID->flags & ACC_STATIC) && (!obj)) {
- (*env)->ThrowNew(env,loader_load(utf_new_char("java/lang/NullPointerException")),
- "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
- return 0;
- }
+ 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;
+ }
- if ((methodID->flags & ACC_STATIC) && (obj)) obj=0;
+ if ((methodID->flags & ACC_STATIC) && (obj)) obj = 0;
blk = MNEW(jni_callblock, 4 /*argcount+2*/);
- retT=fill_callblock_objA(obj,methodID->descriptor,blk,params);
+ retT = fill_callblock_objA(obj, methodID->descriptor, blk, params);
switch (retT) {
- case 'V': (void)asm_calljavafunction2(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=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(loader_load_sysclass(NULL,utf_new_char("java/lang/Integer")));
- CallVoidMethod(env,retVal,
- class_resolvemethod(retVal->vftbl->class,
- utf_new_char("<init>"),utf_new_char("(I)V")),intVal);
- }
- break;
- case 'B': {
- s4 intVal;
- intVal=(s4)asm_calljavafunction2(methodID,
- argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Byte")));
- CallVoidMethod(env,retVal,
- class_resolvemethod(retVal->vftbl->class,
- utf_new_char("<init>"),utf_new_char("(B)V")),intVal);
- }
- break;
- case 'C': {
- s4 intVal;
- intVal=(s4)asm_calljavafunction2(methodID,
- argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Character")));
- CallVoidMethod(env,retVal,
- class_resolvemethod(retVal->vftbl->class,
- utf_new_char("<init>"),utf_new_char("(C)V")),intVal);
- }
- break;
- case 'S': {
- s4 intVal;
- intVal=(s4)asm_calljavafunction2(methodID,
- argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Short")));
- CallVoidMethod(env,retVal,
- class_resolvemethod(retVal->vftbl->class,
- utf_new_char("<init>"),utf_new_char("(S)V")),intVal);
- }
+ case 'V':
+ (void) asm_calljavafunction2(methodID,
+ argcount + 1,
+ (argcount + 1) * sizeof(jni_callblock),
+ blk);
+ retVal = 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);
+ }
+ 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")));
+ CallVoidMethod(env,
+ retVal,
+ class_resolvemethod(retVal->vftbl->class,
+ utf_new_char("<init>"),
+ utf_new_char("(B)V")),
+ intVal);
+ }
+ 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")));
+ CallVoidMethod(env,
+ retVal,
+ class_resolvemethod(retVal->vftbl->class,
+ utf_new_char("<init>"),
+ utf_new_char("(C)V")),
+ 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")));
+ CallVoidMethod(env,
+ retVal,
+ class_resolvemethod(retVal->vftbl->class,
+ utf_new_char("<init>"),
+ utf_new_char("(S)V")),
+ 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")));
+ CallVoidMethod(env,
+ retVal,
+ class_resolvemethod(retVal->vftbl->class,
+ utf_new_char("<init>"),
+ utf_new_char("(Z)V")),
+ 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")));
+ CallVoidMethod(env,
+ retVal,
+ class_resolvemethod(retVal->vftbl->class,
+ utf_new_char("<init>"),
+ utf_new_char("(J)V")),
+ intVal);
+ }
+ break;
+
+ case 'F': {
+ 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")));
+ CallVoidMethod(env,
+ retVal,
+ class_resolvemethod(retVal->vftbl->class,
+ utf_new_char("<init>"),
+ utf_new_char("(F)V")),
+ 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")));
+ CallVoidMethod(env,
+ retVal,
+ class_resolvemethod(retVal->vftbl->class,
+ utf_new_char("<init>"),
+ utf_new_char("(D)V")),
+ floatVal);
+ }
+ break;
- case 'Z': {
- s4 intVal;
- intVal=(s4)asm_calljavafunction2(methodID,
- argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Boolean")));
- CallVoidMethod(env,retVal,
- class_resolvemethod(retVal->vftbl->class,
- utf_new_char("<init>"),utf_new_char("(Z)V")),intVal);
- }
- break;
- case 'J': {
- jlong intVal;
- intVal=asm_calljavafunction2long(methodID,
- argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Long")));
- CallVoidMethod(env,retVal,
- class_resolvemethod(retVal->vftbl->class,
- utf_new_char("<init>"),utf_new_char("(J)V")),intVal);
- }
- break;
- case 'F': {
- jdouble floatVal;
- floatVal=asm_calljavafunction2double(methodID,
- argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Float")));
- CallVoidMethod(env,retVal,
- class_resolvemethod(retVal->vftbl->class,
- utf_new_char("<init>"),utf_new_char("(F)V")),floatVal);
- }
- break;
- case 'D': {
- jdouble floatVal;
- floatVal=asm_calljavafunction2double(methodID,
- argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Double")));
- CallVoidMethod(env,retVal,
- class_resolvemethod(retVal->vftbl->class,
- utf_new_char("<init>"),utf_new_char("(D)V")),floatVal);
- }
- break;
+ case 'L': /* fall through */
+ case '[':
+ retVal = asm_calljavafunction2(methodID,
+ argcount + 1,
+ (argcount + 1) * sizeof(jni_callblock),
+ blk);
+ break;
- case 'L': /* fall through */
- case '[': retVal=asm_calljavafunction2(methodID,argcount+1,(argcount+1)*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*/);
- return (jobject*)0;
- }
+ default:
+ /* if this happens the acception has already been set by fill_callblock_objA*/
+ MFREE(blk, jni_callblock, 4 /*argcount+2*/);
+ return (jobject *) 0;
}
+
MFREE(blk, jni_callblock, 4 /*argcount+2*/);
- if (exceptionptr) {
- java_objectheader *exceptionToWrap=exceptionptr;
- classinfo *ivtec=loader_load_sysclass(NULL,utf_new_char("java/lang/reflect/InvocationTargetException"));
- java_objectheader* ivte=builtin_new(ivtec);
- if (asm_calljavamethod(class_resolvemethod(ivtec,utf_new_char("<init>"),utf_new_char("(Ljava/lang/Throwable;)V")),
- ivte,exceptionToWrap,0,0)!=NULL) panic("jni.c: error while creating InvocationTargetException wrapper");
- exceptionptr=ivte;
+ if (*exceptionptr) {
+ java_objectheader *exceptionToWrap = *exceptionptr;
+ classinfo *ivtec;
+ java_objectheader *ivte;
+
+ *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);
+
+ if (*exceptionptr != NULL)
+ panic("jni.c: error while creating InvocationTargetException wrapper");
+
+ *exceptionptr = ivte;
}
- return retVal;
+ return (jobject *) retVal;
}
+void jni_init() {
+ jmethodID mid;
+
+ 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");
+ }
+
+ 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);
+
+ if (*global_ref_table == NULL) {
+ log_text("JNI-Init: unable to create new global_ref_table");
+ }
+
+ 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");
+ }
+
+ 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");
+ }
+
+ 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");
+ }
+
+ newint = GetMethodID(NULL, intclass, "<init>","(I)V");
+ if (newint == NULL) {
+ log_text("JNI-Init: unable to find constructor in java.lang.Integer");
+ }
+
+ intvalue = GetMethodID(NULL, intclass, "intValue","()I");
+ if (intvalue == NULL) {
+ log_text("JNI-Init: unable to find method \"intValue\" in java.lang.Integer");
+ }
+
+ 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");
+ }
+}
/*