-/* jni.c - implementation of the Java Native Interface functions
+/* src/native/jni.c - implementation of the Java Native Interface functions
- 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
+ Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, Institut f. Computersprachen - TU Wien
This file is part of CACAO.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
- Contact: cacao@complang.tuwien.ac.at
+ $Id: jni.c 8321 2007-08-16 11:37:25Z michi $
- Authors: ?
+*/
- Changes: Joseph Wenninger
- $Id: jni.c 1005 2004-03-30 23:01:45Z twisti $
+#include "config.h"
-*/
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+#include "vm/types.h"
-#include <string.h>
-#include "jni.h"
-#include "global.h"
-#include "loader.h"
-#include "tables.h"
-#include "native.h"
-#include "builtin.h"
-#include "threads/thread.h"
-#include "toolbox/loging.h"
-#include "toolbox/memory.h"
-#include "nat/java_lang_Byte.h"
-#include "nat/java_lang_Character.h"
-#include "nat/java_lang_Short.h"
-#include "nat/java_lang_Integer.h"
-#include "nat/java_lang_Boolean.h"
-#include "nat/java_lang_Long.h"
-#include "nat/java_lang_Float.h"
-#include "nat/java_lang_Double.h"
-#include "nat/java_lang_Throwable.h"
-#include "jit/jit.h"
-#include "asmpart.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_short = 0;
-static utf* utf_int = 0;
-static utf* utf_long = 0;
-static utf* utf_float = 0;
-static utf* utf_double = 0;
-
-
-/********************* accessing instance-fields **********************************/
-
-#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);
-
-
-
-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;
-
- /* skip '(' */
- utf_nextu2(&utf_ptr);
-
- /* determine number of parameters */
- while (*utf_ptr != ')') {
- get_type(&utf_ptr, desc_end, true);
- parametercount++;
- }
+#include "mm/gc-common.h"
+#include "mm/memory.h"
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/localref.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_CLASSPATH_GNU)
+# 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
+# endif
+#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_Integer.h"
+#include "native/include/java_lang_Boolean.h"
+#include "native/include/java_lang_Long.h"
+#include "native/include/java_lang_Float.h"
+#include "native/include/java_lang_Double.h"
+#include "native/include/java_lang_String.h"
+#include "native/include/java_lang_Throwable.h"
+
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_CLASSPATH_SUN)
+# include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
+# endif
+
+# include "native/include/java_lang_ClassLoader.h"
+
+# include "native/include/java_lang_reflect_Constructor.h"
+# include "native/include/java_lang_reflect_Field.h"
+# include "native/include/java_lang_reflect_Method.h"
+
+# include "native/include/java_nio_Buffer.h"
+
+# if defined(WITH_CLASSPATH_GNU)
+# include "native/include/java_nio_DirectByteBufferImpl.h"
+# endif
+#endif
+
+#if defined(ENABLE_JVMTI)
+# include "native/jvmti/cacaodbg.h"
+#endif
+
+#include "native/vm/java_lang_Class.h"
+
+#if defined(ENABLE_JAVASE)
+# include "native/vm/java_lang_ClassLoader.h"
+# include "native/vm/reflect.h"
+#endif
+
+#include "threads/lock-common.h"
+#include "threads/threads-common.h"
+
+#include "toolbox/logging.h"
+
+#include "vm/builtin.h"
+#include "vm/exceptions.h"
+#include "vm/global.h"
+#include "vm/initialize.h"
+#include "vm/primitive.h"
+#include "vm/resolve.h"
+#include "vm/stringlocal.h"
+#include "vm/vm.h"
+
+#include "vm/jit/asmpart.h"
+#include "vm/jit/jit.h"
+#include "vm/jit/stacktrace.h"
+
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/statistics.h"
+
+
+/* debug **********************************************************************/
+
+#if !defined(NDEBUG)
+# define TRACEJNICALLS(format, ...) \
+ do { \
+ if (opt_TraceJNICalls) { \
+ log_println((format), __VA_ARGS__); \
+ } \
+ } while (0)
+#else
+# define TRACEJNICALLS(format, ...)
+#endif
- return parametercount;
-}
+/* global variables ***********************************************************/
+/* global reference table *****************************************************/
-void fill_callblock(void *obj, utf *descr, jni_callblock blk[], va_list data, char ret)
+/* hashsize must be power of 2 */
+
+#define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
+
+static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
+
+
+/* direct buffer stuff ********************************************************/
+
+#if defined(ENABLE_JAVASE)
+static classinfo *class_java_nio_Buffer;
+static classinfo *class_java_nio_DirectByteBufferImpl;
+static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
+
+# if defined(WITH_CLASSPATH_GNU)
+# if SIZEOF_VOID_P == 8
+static classinfo *class_gnu_classpath_Pointer64;
+# else
+static classinfo *class_gnu_classpath_Pointer32;
+# endif
+# endif
+
+static methodinfo *dbbirw_init;
+#endif
+
+
+/* accessing instance fields macros *******************************************/
+
+#define SET_FIELD(o,type,f,value) \
+ *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
+
+#define GET_FIELD(o,type,f) \
+ *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
+
+
+/* some forward declarations **************************************************/
+
+jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
+jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity);
+
+
+/* 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;
+ /* create global ref hashtable */
- /*
- log_text("fill_callblock");
- utf_display(descr);
- log_text("====");
- */
- /* skip '(' */
- utf_nextu2(utf_ptr);
-
- /* 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;
-
- 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 = PTR_TO_ITEM(va_arg(data, void*));
- break;
- }
- }
- cnt++;
- }
+ hashtable_global_ref = NEW(hashtable);
+
+ hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
- /*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====");
+
+#if defined(ENABLE_JAVASE)
+ /* direct buffer stuff */
+
+ if (!(class_java_nio_Buffer =
+ load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
+ !link_class(class_java_nio_Buffer))
+ return false;
+
+# if defined(WITH_CLASSPATH_GNU)
+ if (!(class_java_nio_DirectByteBufferImpl =
+ load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
+ !link_class(class_java_nio_DirectByteBufferImpl))
+ return false;
+
+ if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
+ load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
+ !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
+ return false;
+
+ if (!(dbbirw_init =
+ class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
+ utf_init,
+ utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
+ return false;
+
+# if SIZEOF_VOID_P == 8
+ if (!(class_gnu_classpath_Pointer64 =
+ load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
+ !link_class(class_gnu_classpath_Pointer64))
+ return false;
+# else
+ if (!(class_gnu_classpath_Pointer32 =
+ load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
+ !link_class(class_gnu_classpath_Pointer32))
+ return false;
+# endif
+# endif
+#endif /* defined(ENABLE_JAVASE) */
+
+ 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)
+/* jni_init_localref_table *****************************************************
+
+ Frees the local references table of the current thread.
+
+*******************************************************************************/
+
+bool jni_free_localref_table(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 */
+ localref_table *lrt;
- jobject param;
- int cnt;
- int cnts;
- char c;
+#if defined(ENABLE_GC_CACAO)
+ lrt = LOCALREFTABLE;
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
- intsDisable();
+ assert(lrt);
+ assert(lrt->prev == NULL);
+
+ FREE(lrt, localref_table);
+
+ LOCALREFTABLE = NULL;
#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");
+
+ return true;
+}
+
+
+/* _Jv_jni_CallObjectMethod ****************************************************
+
+ Internal function to call Java Object methods.
+
+*******************************************************************************/
+
+static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
+ vftbl_t *vftbl,
+ methodinfo *m, va_list ap)
+{
+ methodinfo *resm;
+ java_handle_t *ro;
+
+ STATISTICS(jniinvokation());
+
+ if (m == NULL) {
+ exceptions_throw_nullpointerexception();
+ return NULL;
}
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
- intsRestore();
-#endif
- /*
- log_text("fill_callblock");
- utf_display(descr);
- log_text("====");
- */
- /* skip '(' */
- utf_nextu2(utf_ptr);
+ /* Class initialization is done by the JIT compiler. This is ok
+ since a static method always belongs to the declaring class. */
- /* determine number of parameters */
- if (obj) {
- blk[0].itemtype = TYPE_ADR;
- blk[0].item = PTR_TO_ITEM(obj);
- cnt=1;
+ if (m->flags & ACC_STATIC) {
+ /* For static methods we reset the object. */
+
+ if (o != NULL)
+ o = NULL;
+
+ /* for convenience */
+
+ resm = m;
} else {
- cnt = 0;
+ /* For instance methods we make a virtual function table lookup. */
+
+ resm = method_vftbl_lookup(vftbl, m);
}
- 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 = 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;
+ STATISTICS(jnicallXmethodnvokation());
- } else {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
- break;
+ ro = vm_call_method_valist(resm, o, ap);
- 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;
+ return ro;
+}
- } 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;
- }
- }
- break;
+/* _Jv_jni_CallObjectMethodA ***************************************************
- 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;
+ Internal function to call Java Object methods.
- } 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) ((java_lang_Byte *) param)->value;
-
- } else {
- *exceptionptr = new_exception("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;
-
- } 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;
- }
- }
- }
+static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
+ vftbl_t *vftbl,
+ methodinfo *m,
+ const jvalue *args)
+{
+ methodinfo *resm;
+ java_handle_t *ro;
- }
- break;
+ STATISTICS(jniinvokation());
- case 'F':
- param = params->data[cnts];
- if (param == 0) {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
+ if (m == NULL) {
+ exceptions_throw_nullpointerexception();
+ return NULL;
+ }
- if (param->vftbl->class->name == utf_float) {
- blk[cnt].itemtype = TYPE_FLT;
- *((jfloat *) (&blk[cnt].item)) = (jfloat) ((java_lang_Float *) param)->value;
+ /* Class initialization is done by the JIT compiler. This is ok
+ since a static method always belongs to the declaring class. */
- } else {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
- break;
+ if (m->flags & ACC_STATIC) {
+ /* For static methods we reset the object. */
- case 'D':
- param = params->data[cnts];
- if (param == 0) {
- *exceptionptr = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
+ if (o != NULL)
+ o = NULL;
- if (param->vftbl->class->name == utf_double) {
- blk[cnt].itemtype = TYPE_DBL;
- *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
+ /* for convenience */
- } else {
- if (param->vftbl->class->name == utf_float) {
- blk[cnt].itemtype = TYPE_DBL;
- *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
+ resm = m;
- } else {
- *exceptionptr = new_exception("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 = 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 = new_exception("java/lang/IllegalArgumentException");
- return 0;
- }
- }
-
- blk[cnt].itemtype = TYPE_ADR;
- blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
- break;
- }
+ } else {
+ /* For instance methods we make a virtual function table lookup. */
- case '[':
- {
- char *start = (*utf_ptr) - 1;
- char *end;
+ resm = method_vftbl_lookup(vftbl, m);
+ }
- char ch;
- while ((ch = utf_nextu2(utf_ptr)) == '[')
- if (ch == 'L') {
- while (utf_nextu2(utf_ptr) != ';') {}
- }
+ STATISTICS(jnicallXmethodnvokation());
- end = (*utf_ptr) - 1;
- ch = utf_nextu2(utf_ptr);
+ ro = vm_call_method_jvalue(resm, o, args);
- 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 = PTR_TO_ITEM(params->data[cnts]);
- break;
- }
- }
- cnt++;
- cnts++;
+ return ro;
+}
+
+
+/* _Jv_jni_CallIntMethod *******************************************************
+
+ Internal function to call Java integer class methods (boolean,
+ byte, char, short, int).
+
+*******************************************************************************/
+
+static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
+ methodinfo *m, va_list ap)
+{
+ methodinfo *resm;
+ jint i;
+
+ STATISTICS(jniinvokation());
+
+ if (m == NULL) {
+ exceptions_throw_nullpointerexception();
+ return 0;
}
+
+ /* Class initialization is done by the JIT compiler. This is ok
+ since a static method always belongs to the declaring class. */
+
+ if (m->flags & ACC_STATIC) {
+ /* For static methods we reset the object. */
+
+ if (o != NULL)
+ o = NULL;
- c = utf_nextu2(utf_ptr);
- c = utf_nextu2(utf_ptr);
- return c; /*return type needed usage of the right lowlevel methods*/
+ /* for convenience */
+
+ resm = m;
+
+ } else {
+ /* For instance methods we make a virtual function table lookup. */
+
+ resm = method_vftbl_lookup(vftbl, m);
+ }
+
+ STATISTICS(jnicallXmethodnvokation());
+
+ i = vm_call_method_int_valist(resm, o, ap);
+
+ return i;
}
+/* _Jv_jni_CallIntMethodA ******************************************************
+
+ Internal function to call Java integer class methods (boolean,
+ byte, char, short, int).
+*******************************************************************************/
+static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
+ methodinfo *m, const jvalue *args)
+{
+ methodinfo *resm;
+ jint i;
+ STATISTICS(jniinvokation());
+ if (m == NULL) {
+ exceptions_throw_nullpointerexception();
+ return 0;
+ }
+
+ /* Class initialization is done by the JIT compiler. This is ok
+ since a static method always belongs to the declaring class. */
+ if (m->flags & ACC_STATIC) {
+ /* For static methods we reset the object. */
+ if (o != NULL)
+ o = NULL;
+ /* for convenience */
+ resm = m;
+ } else {
+ /* For instance methods we make a virtual function table lookup. */
+ resm = method_vftbl_lookup(vftbl, m);
+ }
+ STATISTICS(jnicallXmethodnvokation());
+ i = vm_call_method_int_jvalue(resm, o, args);
-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);
+ return i;
}
-jmethodID get_nonvirtual(jclass clazz,jmethodID methodID) {
- if (clazz==methodID->class) return methodID;
- return class_resolvemethod (clazz, methodID->name, methodID->descriptor);
-}
+/* _Jv_jni_CallLongMethod ******************************************************
+ Internal function to call Java long methods.
-jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
-{
- int argcount;
- 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");
- */
+*******************************************************************************/
+
+static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
+ methodinfo *m, va_list ap)
+{
+ methodinfo *resm;
+ jlong l;
+
+ STATISTICS(jniinvokation());
- if (methodID == 0) {
- *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+ if (m == NULL) {
+ exceptions_throw_nullpointerexception();
return 0;
}
- argcount = get_parametercount(methodID);
+ /* Class initialization is done by the JIT compiler. This is ok
+ since a static method always belongs to the declaring class. */
- if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
- ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
- *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
- return 0;
+ if (m->flags & ACC_STATIC) {
+ /* For static methods we reset the object. */
+
+ if (o != NULL)
+ o = NULL;
+
+ /* for convenience */
+
+ resm = m;
+
+ } else {
+ /* For instance methods we make a virtual function table lookup. */
+
+ resm = method_vftbl_lookup(vftbl, m);
}
-
- if (obj && !builtin_instanceof(obj, methodID->class)) {
- *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+
+ STATISTICS(jnicallXmethodnvokation());
+
+ l = vm_call_method_long_valist(resm, o, ap);
+
+ return l;
+}
+
+
+/* _Jv_jni_CallLongMethodA *****************************************************
+
+ Internal function to call Java long methods.
+
+*******************************************************************************/
+
+static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
+ methodinfo *m, const jvalue *args)
+{
+ methodinfo *resm;
+ jlong l;
+
+ STATISTICS(jniinvokation());
+
+ if (m == NULL) {
+ exceptions_throw_nullpointerexception();
return 0;
}
- 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");
- return 0;
+ /* Class initialization is done by the JIT compiler. This is ok
+ since a static method always belongs to the declaring class. */
+
+ if (m->flags & ACC_STATIC) {
+ /* For static methods we reset the object. */
+
+ if (o != NULL)
+ o = NULL;
+
+ /* for convenience */
+
+ resm = m;
}
+ else {
+ /* For instance methods we make a virtual function table lookup. */
- blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+ resm = method_vftbl_lookup(vftbl, m);
+ }
- fill_callblock(obj, methodID->descriptor, blk, args, 'O');
+ STATISTICS(jnicallXmethodnvokation());
- /* printf("parameter: obj: %p",blk[0].item); */
- ret = asm_calljavafunction2(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
- blk);
+ l = vm_call_method_long_jvalue(resm, o, args);
- MFREE(blk, jni_callblock, argcount + 1);
- /* printf("(CallObjectMethodV)-->%p\n",ret); */
- return ret;
+ return l;
}
-/*
- 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)
-{
- int argcount;
- jni_callblock *blk;
- jint ret;
-
-/* printf("%p, %c\n",retType,methodID,retType);*/
-
- /*
- 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;
+/* _Jv_jni_CallFloatMethod *****************************************************
+
+ Internal function to call Java float methods.
+
+*******************************************************************************/
+
+static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
+ methodinfo *m, va_list ap)
+{
+ methodinfo *resm;
+ jfloat f;
+
+ /* Class initialization is done by the JIT compiler. This is ok
+ since a static method always belongs to the declaring class. */
+
+ if (m->flags & ACC_STATIC) {
+ /* For static methods we reset the object. */
+
+ if (o != NULL)
+ o = NULL;
+
+ /* for convenience */
+
+ resm = m;
+
+ } else {
+ /* For instance methods we make a virtual function table lookup. */
+
+ resm = method_vftbl_lookup(vftbl, m);
}
-
- 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;
+ STATISTICS(jnicallXmethodnvokation());
+
+ f = vm_call_method_float_valist(resm, o, ap);
+
+ return f;
+}
+
+
+/* _Jv_jni_CallFloatMethodA ****************************************************
+
+ Internal function to call Java float methods.
+
+*******************************************************************************/
+
+static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
+ methodinfo *m, const jvalue *args)
+{
+ methodinfo *resm;
+ jfloat f;
+
+ /* Class initialization is done by the JIT compiler. This is ok
+ since a static method always belongs to the declaring class. */
+
+ if (m->flags & ACC_STATIC) {
+ /* For static methods we reset the object. */
+
+ if (o != NULL)
+ o = NULL;
+
+ /* for convenience */
+
+ resm = m;
}
+ else {
+ /* For instance methods we make a virtual function table lookup. */
- if (obj && !builtin_instanceof(obj, methodID->class)) {
- *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
- return 0;
+ resm = method_vftbl_lookup(vftbl, m);
}
+ STATISTICS(jnicallXmethodnvokation());
- if (argcount > 3) {
- *exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- log_text("Too many arguments. CallIntegerMethod does not support that");
- return 0;
- }
+ f = vm_call_method_float_jvalue(resm, o, args);
+
+ return f;
+}
+
+
+/* _Jv_jni_CallDoubleMethod ****************************************************
+
+ Internal function to call Java double methods.
+
+*******************************************************************************/
+
+static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
+ methodinfo *m, va_list ap)
+{
+ methodinfo *resm;
+ jdouble d;
+
+ /* Class initialization is done by the JIT compiler. This is ok
+ since a static method always belongs to the declaring class. */
+
+ if (m->flags & ACC_STATIC) {
+ /* For static methods we reset the object. */
+
+ if (o != NULL)
+ o = NULL;
- blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+ /* for convenience */
- fill_callblock(obj, methodID->descriptor, blk, args, retType);
+ resm = m;
- /* printf("parameter: obj: %p",blk[0].item); */
- ret = (jint) asm_calljavafunction2(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
- blk);
+ } else {
+ /* For instance methods we make a virtual function table lookup. */
+
+ resm = method_vftbl_lookup(vftbl, m);
+ }
- MFREE(blk, jni_callblock, argcount + 1);
- /* printf("(CallObjectMethodV)-->%p\n",ret); */
+ d = vm_call_method_double_valist(resm, o, ap);
- return ret;
+ return d;
}
-/*core function for long class functions*/
-jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
+/* _Jv_jni_CallDoubleMethodA ***************************************************
+
+ Internal function to call Java double methods.
+
+*******************************************************************************/
+
+static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
+ methodinfo *m, const jvalue *args)
{
- int argcount;
- jni_callblock *blk;
- jlong ret;
+ methodinfo *resm;
+ jdouble d;
- /*
- 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;
+ /* Class initialization is done by the JIT compiler. This is ok
+ since a static method always belongs to the declaring class. */
+
+ if (m->flags & ACC_STATIC) {
+ /* For static methods we reset the object. */
+
+ if (o != NULL)
+ o = NULL;
+
+ /* for convenience */
+
+ resm = m;
+ }
+ else {
+ /* For instance methods we make a virtual function table lookup. */
+
+ resm = method_vftbl_lookup(vftbl, m);
}
- argcount = get_parametercount(methodID);
+ d = vm_call_method_double_jvalue(resm, o, args);
- if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
- ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
- *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
- return 0;
+ return d;
+}
+
+
+/* _Jv_jni_CallVoidMethod ******************************************************
+
+ Internal function to call Java void methods.
+
+*******************************************************************************/
+
+static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
+ methodinfo *m, va_list ap)
+{
+ methodinfo *resm;
+
+ if (m == NULL) {
+ exceptions_throw_nullpointerexception();
+ return;
}
- if (obj && !builtin_instanceof(obj,methodID->class)) {
- *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
- return 0;
+ /* Class initialization is done by the JIT compiler. This is ok
+ since a static method always belongs to the declaring class. */
+
+ if (m->flags & ACC_STATIC) {
+ /* For static methods we reset the object. */
+
+ if (o != NULL)
+ o = NULL;
+
+ /* for convenience */
+
+ resm = m;
+
+ } else {
+ /* For instance methods we make a virtual function table lookup. */
+
+ resm = method_vftbl_lookup(vftbl, m);
}
+ STATISTICS(jnicallXmethodnvokation());
- 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");
- return 0;
+ (void) vm_call_method_valist(resm, o, ap);
+}
+
+
+/* _Jv_jni_CallVoidMethodA *****************************************************
+
+ Internal function to call Java void methods.
+
+*******************************************************************************/
+
+static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
+ methodinfo *m, const jvalue *args)
+{
+ methodinfo *resm;
+
+ if (m == NULL) {
+ exceptions_throw_nullpointerexception();
+ return;
}
- blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+ /* Class initialization is done by the JIT compiler. This is ok
+ since a static method always belongs to the declaring class. */
+
+ if (m->flags & ACC_STATIC) {
+ /* For static methods we reset the object. */
- fill_callblock(obj, methodID->descriptor, blk, args, 'L');
+ if (o != NULL)
+ o = NULL;
- /* printf("parameter: obj: %p",blk[0].item); */
- ret = asm_calljavafunction2long(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
- blk);
+ /* for convenience */
- MFREE(blk, jni_callblock, argcount + 1);
- /* printf("(CallObjectMethodV)-->%p\n",ret); */
+ resm = m;
- return ret;
+ } else {
+ /* For instance methods we make a virtual function table lookup. */
+
+ resm = method_vftbl_lookup(vftbl, m);
+ }
+
+ STATISTICS(jnicallXmethodnvokation());
+
+ (void) vm_call_method_jvalue(resm, o, args);
}
-/*core function for float class methods (float,double)*/
-jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,char retType)
+/* _Jv_jni_invokeNative ********************************************************
+
+ Invoke a method on the given object with the given arguments.
+
+ For instance methods OBJ must be != NULL and the method is looked up
+ in the vftbl of the object.
+
+ For static methods, OBJ is ignored.
+
+*******************************************************************************/
+
+java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
+ java_handle_objectarray_t *params)
{
- int argcount = get_parametercount(methodID);
- jni_callblock *blk;
- jdouble ret;
+ methodinfo *resm;
+ java_handle_t *ro;
+ s4 argcount;
+ s4 paramcount;
+ java_handle_t *xptr;
+ int32_t dumpsize;
+ uint64_t *array;
+ imm_union value;
- /*
- 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 (m == NULL) {
+ exceptions_throw_nullpointerexception();
+ return NULL;
+ }
- 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");
- return 0;
+ argcount = m->parseddesc->paramcount;
+ paramcount = argcount;
+
+ /* if method is non-static, remove the `this' pointer */
+
+ if (!(m->flags & ACC_STATIC))
+ paramcount--;
+
+ /* For instance methods the object has to be an instance of the
+ class the method belongs to. For static methods the obj
+ parameter is ignored. */
+
+ if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
+ exceptions_throw_illegalargumentexception();
+ return NULL;
+ }
+
+ /* check if we got the right number of arguments */
+
+ if (((params == NULL) && (paramcount != 0)) ||
+ (params && (LLNI_array_size(params) != paramcount)))
+ {
+ exceptions_throw_illegalargumentexception();
+ return NULL;
+ }
+
+ /* for instance methods we need an object */
+
+ if (!(m->flags & ACC_STATIC) && (o == NULL)) {
+ /* XXX not sure if that is the correct exception */
+ exceptions_throw_nullpointerexception();
+ return NULL;
}
- blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+ /* for static methods, zero object to make subsequent code simpler */
+ if (m->flags & ACC_STATIC)
+ o = NULL;
- fill_callblock(obj, methodID->descriptor, blk, args, retType);
+ if (o != NULL) {
+ /* for instance methods we must do a vftbl lookup */
+ resm = method_vftbl_lookup(o->vftbl, m);
+ }
+ else {
+ /* for static methods, just for convenience */
+ resm = m;
+ }
+
+ /* mark start of dump memory area */
+
+ dumpsize = dump_size();
+
+ /* Fill the argument array from a object-array. */
+
+ array = vm_array_from_objectarray(resm, o, params);
+
+ /* The array can be NULL if we don't have any arguments to pass
+ and the architecture does not have any argument registers
+ (e.g. i386). In that case we additionally check for an
+ exception thrown. */
+
+ if ((array == NULL) && (exceptions_get_exception() != NULL)) {
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+ return NULL;
+ }
+
+ switch (resm->parseddesc->returntype.decltype) {
+ case TYPE_VOID:
+ (void) vm_call_array(resm, array);
+ ro = NULL;
+ break;
+
+ case PRIMITIVETYPE_BOOLEAN:
+ case PRIMITIVETYPE_BYTE:
+ case PRIMITIVETYPE_CHAR:
+ case PRIMITIVETYPE_SHORT:
+ case PRIMITIVETYPE_INT:
+ value.i = vm_call_int_array(resm, array);
+ ro = primitive_box(resm->parseddesc->returntype.decltype, value);
+ break;
+
+ case PRIMITIVETYPE_LONG:
+ value.l = vm_call_long_array(resm, array);
+ ro = primitive_box(resm->parseddesc->returntype.decltype, value);
+ break;
+
+ case PRIMITIVETYPE_FLOAT:
+ value.f = vm_call_float_array(resm, array);
+ ro = primitive_box(resm->parseddesc->returntype.decltype, value);
+ break;
+
+ case PRIMITIVETYPE_DOUBLE:
+ value.d = vm_call_double_array(resm, array);
+ ro = primitive_box(resm->parseddesc->returntype.decltype, value);
+ break;
+
+ case TYPE_ADR:
+ ro = vm_call_array(resm, array);
+ break;
+
+ default:
+ vm_abort("_Jv_jni_invokeNative: invalid return type %d", resm->parseddesc->returntype.decltype);
+ }
+
+ xptr = exceptions_get_exception();
+
+ if (xptr != NULL) {
+ /* clear exception pointer, we are calling JIT code again */
+
+ exceptions_clear_exception();
+
+ exceptions_throw_invocationtargetexception(xptr);
+ }
+
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+ return ro;
+}
+
+
+/* GetVersion ******************************************************************
+
+ Returns the major version number in the higher 16 bits and the
+ minor version number in the lower 16 bits.
+
+*******************************************************************************/
+
+jint _Jv_JNI_GetVersion(JNIEnv *env)
+{
+ STATISTICS(jniinvokation());
+
+ /* we support JNI 1.4 */
+
+ return JNI_VERSION_1_4;
+}
+
+
+/* Class Operations ***********************************************************/
+
+/* DefineClass *****************************************************************
+
+ 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.
+
+*******************************************************************************/
+
+jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
+ const jbyte *buf, jsize bufLen)
+{
+#if defined(ENABLE_JAVASE)
+ utf *u;
+ classloader *cl;
+ classinfo *c;
+
+ TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d", env, name, loader, buf, bufLen);
+
+ u = utf_new_char(name);
+ cl = (classloader *) loader;
+
+ c = class_define(u, cl, bufLen, (const uint8_t *) buf);
+
+ return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
+#else
+ vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
+
+ /* keep compiler happy */
+
+ return 0;
+#endif
+}
+
+
+/* FindClass *******************************************************************
+
+ 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.
+
+*******************************************************************************/
+
+jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
+{
+#if defined(ENABLE_JAVASE)
+ utf *u;
+ classinfo *cc;
+ classinfo *c;
+
+ STATISTICS(jniinvokation());
+
+ u = utf_new_char_classname((char *) name);
+
+ /* Check stacktrace for classloader, if one found use it,
+ otherwise use the system classloader. */
+
+ /* Quote from the JNI documentation:
+
+ In the Java 2 Platform, FindClass locates the class loader
+ associated with the current native method. If the native code
+ belongs to a system class, no class loader will be
+ involved. Otherwise, the proper class loader will be invoked to
+ load and link the named class. When FindClass is called through
+ the Invocation Interface, there is no current native method or
+ its associated class loader. In that case, the result of
+ ClassLoader.getBaseClassLoader is used." */
+
+ cc = stacktrace_getCurrentClass();
+
+ if (cc == NULL)
+ c = load_class_from_sysloader(u);
+ else
+ c = load_class_from_classloader(u, cc->classloader);
+
+ if (c == NULL)
+ return NULL;
+
+ if (!link_class(c))
+ return NULL;
+
+ return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
+#else
+ vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
+
+ /* keep compiler happy */
+
+ return NULL;
+#endif
+}
+
+
+/* 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 _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
+{
+ classinfo *c;
+ classinfo *super;
+
+ TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
+
+ c = (classinfo *) sub;
+
+ if (c == NULL)
+ return NULL;
+
+ super = class_get_superclass(c);
+
+ return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) super);
+}
+
+
+/* IsAssignableFrom ************************************************************
+
+ Determines whether an object of sub can be safely cast to sup.
+
+*******************************************************************************/
+
+jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
+{
+ java_lang_Class *csup;
+ java_lang_Class *csub;
+
+ csup = (java_lang_Class *) sup;
+ csub = (java_lang_Class *) sub;
+
+ STATISTICS(jniinvokation());
+
+ return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
+}
+
+
+/* Throw ***********************************************************************
+
+ Causes a java.lang.Throwable object to be thrown.
+
+*******************************************************************************/
+
+jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
+{
+ java_handle_t *o;
+
+ STATISTICS(jniinvokation());
+
+ o = (java_handle_t *) obj;
+
+ exceptions_set_exception(o);
+
+ return JNI_OK;
+}
+
+
+/* ThrowNew ********************************************************************
+
+ Constructs an exception object from the specified class with the
+ message specified by message and causes that exception to be
+ thrown.
+
+*******************************************************************************/
+
+jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
+{
+ classinfo *c;
+ java_handle_t *o;
+ java_handle_t *s;
- /* printf("parameter: obj: %p",blk[0].item); */
- ret = asm_calljavafunction2double(methodID,
- argcount + 1,
- (argcount + 1) * sizeof(jni_callblock),
- blk);
+ STATISTICS(jniinvokation());
- MFREE(blk, jni_callblock, argcount + 1);
- /* printf("(CallObjectMethodV)-->%p\n",ret); */
+ c = (classinfo *) clazz;
+ if (msg == NULL)
+ msg = "";
+ s = javastring_new_from_utf_string(msg);
- return ret;
-}
+ /* instantiate exception object */
+ o = native_new_and_init_string(c, s);
-/*************************** function: jclass_findfield ****************************
-
- searches for field with specified name and type in a 'classinfo'-structur
- if no such field is found NULL is returned
-
-************************************************************************************/
-
-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 (o == NULL)
+ return -1;
- if (c->super) return jclass_findfield(c->super,name,desc);
+ exceptions_set_exception(o);
- return NULL;
+ return 0;
}
-/********************* returns version of native method interface *****************/
-jint GetVersion (JNIEnv* env)
-{
- return JNI_VERSION;
-}
+/* ExceptionOccurred ***********************************************************
-/****************** loads a class from a buffer of raw class data *****************/
+ 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.
-jclass DefineClass(JNIEnv* env, const char *name, jobject loader, const jbyte *buf, jsize len)
+*******************************************************************************/
+
+jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
{
- jclass clazz;
+ java_handle_t *o;
- /* change suck-mode, so subsequent class_load will read from memory-buffer */
- classload_buffer( (u1*) buf,len);
+ STATISTICS(jniinvokation());
- clazz = loader_load(utf_new_char ((char *) name));
+ o = exceptions_get_exception();
- /* restore old suck-mode */
- classload_buffer(NULL,0);
- if (clazz) clazz->classloader=loader;
- return clazz;
+ return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
}
-/*************** loads locally defined class with the specified name **************/
+/* ExceptionDescribe ***********************************************************
-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));
+ 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.
- if (!c)
- *exceptionptr = new_exception(string_java_lang_ClassFormatError);
+*******************************************************************************/
- return c;
-}
-
+void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
+{
+ java_handle_t *o;
+ methodinfo *m;
-/***********************************************************************************
+ STATISTICS(jniinvokation());
- converts java.lang.reflect.Method or
- java.lang.reflect.Constructor object to a method ID
-
- **********************************************************************************/
-
-jmethodID FromReflectedMethod(JNIEnv* env, jobject method)
-{
- /* log_text("JNI-Call: FromReflectedMethod"); */
+ o = exceptions_get_exception();
- return 0;
-}
+ if (o == NULL) {
+ /* clear exception, because we are calling jit code again */
+ exceptions_clear_exception();
-/*************** return superclass of the class represented by sub ****************/
-
-jclass GetSuperclass(JNIEnv* env, jclass sub)
-{
- classinfo *c;
+ /* get printStackTrace method from exception class */
- c = ((classinfo*) sub)->super;
+ m = class_resolveclassmethod(o->vftbl->class,
+ utf_printStackTrace,
+ utf_void__void,
+ NULL,
+ true);
- if (!c) return NULL;
+ if (m == NULL)
+ /* XXX what should we do? */
+ return;
- use_class_as_object(c);
+ /* print the stacktrace */
- return c;
-}
-
-
-/*********************** check whether sub can be cast to sup ********************/
-
-jboolean IsAssignableForm(JNIEnv* env, jclass sub, jclass sup)
-{
- return builtin_isanysubclass(sub, sup);
+ (void) vm_call_method(m, o);
+ }
}
-/***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
+/* ExceptionClear **************************************************************
-jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
+ Clears any exception that is currently being thrown. If no
+ exception is currently being thrown, this routine has no effect.
+
+*******************************************************************************/
+
+void _Jv_JNI_ExceptionClear(JNIEnv *env)
{
- /* log_text("JNI-Call: ToReflectedField"); */
+ STATISTICS(jniinvokation());
- return NULL;
+ exceptions_clear_exception();
}
-/***************** throw java.lang.Throwable object ******************************/
+/* FatalError ******************************************************************
-jint Throw(JNIEnv* env, jthrowable obj)
+ Raises a fatal error and does not expect the VM to recover. This
+ function does not return.
+
+*******************************************************************************/
+
+void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
{
- *exceptionptr = (java_objectheader*) obj;
+ STATISTICS(jniinvokation());
- return 0;
+ /* this seems to be the best way */
+
+ vm_abort("JNI Fatal error: %s", msg);
}
-/*******************************************************************************
+/* PushLocalFrame **************************************************************
- create exception object from the class clazz with the
- specified message and cause it to be thrown
+ Creates a new local reference frame, in which at least a given
+ number of local references can be created.
*******************************************************************************/
-jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
+jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
{
- java_lang_Throwable *o;
-
- /* instantiate exception object */
- o = (java_lang_Throwable *) native_new_and_init((classinfo*) clazz);
+ STATISTICS(jniinvokation());
- if (!o) return (-1);
+ if (capacity <= 0)
+ return -1;
- o->detailMessage = (java_lang_String *) javastring_new_char((char *) msg);
+ /* add new local reference frame to current table */
- *exceptionptr = (java_objectheader *) o;
+ if (!localref_frame_push(capacity))
+ return -1;
return 0;
}
-/************************* check if exception occured *****************************/
+/* PopLocalFrame ***************************************************************
-jthrowable ExceptionOccurred (JNIEnv* env)
-{
- return (jthrowable) *exceptionptr;
-}
+ 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.
-/********** print exception and a backtrace of the stack (for debugging) **********/
+*******************************************************************************/
-void ExceptionDescribe (JNIEnv* env)
+jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
{
- utf_display((*exceptionptr)->vftbl->class->name);
- printf ("\n");
- fflush (stdout);
-}
-
+ STATISTICS(jniinvokation());
-/******************* clear any exception currently being thrown *******************/
+ /* release all current local frames */
-void ExceptionClear (JNIEnv* env)
-{
- *exceptionptr = NULL;
-}
+ localref_frame_pop_all();
+ /* add local reference and return the value */
-/********** raises a fatal error and does not expect the VM to recover ************/
-
-void FatalError (JNIEnv* env, const char *msg)
-{
- panic((char *) msg);
+ return _Jv_JNI_NewLocalRef(env, result);
}
-/******************* creates a new local reference frame **************************/
-jint PushLocalFrame(JNIEnv* env, jint capacity)
-{
- /* empty */
+/* DeleteLocalRef **************************************************************
- return 0;
-}
+ Deletes the local reference pointed to by localRef.
-/**************** Pops off the current local reference frame **********************/
+*******************************************************************************/
-jobject PopLocalFrame(JNIEnv* env, jobject result)
+void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
{
- /* empty */
+ java_handle_t *o;
+ localref_table *lrt;
+ s4 i;
- return NULL;
-}
-
+ STATISTICS(jniinvokation());
-/** Creates a new global reference to the object referred to by the obj argument **/
-
-jobject NewGlobalRef(JNIEnv* env, jobject lobj)
-{
- return lobj;
-}
+ o = (java_handle_t *) localRef;
-/************* Deletes the global reference pointed to by globalRef **************/
+ /* get local reference table (thread specific) */
-void DeleteGlobalRef (JNIEnv* env, jobject gref)
-{
- /* empty */
-}
+ lrt = LOCALREFTABLE;
+ /* go through all local frames */
-/*************** Deletes the local reference pointed to by localRef ***************/
+ for (; lrt != NULL; lrt = lrt->prev) {
-void DeleteLocalRef (JNIEnv* env, jobject localRef)
-{
- /* empty */
-}
+ /* and try to remove the reference */
-/********** Tests whether two references refer to the same Java object ************/
+ for (i = 0; i < lrt->capacity; i++) {
+ if (lrt->refs[i] == o) {
+ lrt->refs[i] = NULL;
+ lrt->used--;
-jboolean IsSameObject (JNIEnv* env, jobject obj1, jobject obj2)
-{
- return (obj1==obj2);
-}
+ return;
+ }
+ }
+ }
-/***** Creates a new local reference that refers to the same object as ref *******/
+ /* this should not happen */
-jobject NewLocalRef (JNIEnv* env, jobject ref)
-{
- return ref;
+/* if (opt_checkjni) */
+/* FatalError(env, "Bad global or local ref passed to JNI"); */
+ log_text("JNI-DeleteLocalRef: Local ref passed to JNI not found");
}
-/***********************************************************************************
- Ensures that at least a given number of local references can
- be created in the current thread
+/* IsSameObject ****************************************************************
- **********************************************************************************/
+ Tests whether two references refer to the same Java object.
-jint EnsureLocalCapacity (JNIEnv* env, jint capacity)
+*******************************************************************************/
+
+jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
{
- return 0; /* return 0 on success */
+ STATISTICS(jniinvokation());
+
+ if (ref1 == ref2)
+ return JNI_TRUE;
+ else
+ return JNI_FALSE;
}
-/********* Allocates a new Java object without invoking a constructor *************/
+/* NewLocalRef *****************************************************************
-jobject AllocObject (JNIEnv* env, jclass clazz)
-{
- java_objectheader *o = builtin_new(clazz);
- return o;
-}
+ Creates a new local reference that refers to the same object as ref.
+
+*******************************************************************************/
+jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
+{
+ localref_table *lrt;
+ s4 i;
-/***********************************************************************************
+ STATISTICS(jniinvokation());
- Constructs a new Java object
- arguments that are to be passed to the constructor are placed after methodID
+ if (ref == NULL)
+ return NULL;
-***********************************************************************************/
+ /* get local reference table (thread specific) */
-jobject NewObject (JNIEnv* env, jclass clazz, jmethodID methodID, ...)
-{
- java_objectheader *o;
- void* args[3];
- int argcount=get_parametercount(methodID);
- int i;
- va_list vaargs;
+ lrt = LOCALREFTABLE;
- /* log_text("JNI-Call: NewObject"); */
+ /* Check if we have space for the requested reference? No,
+ allocate a new frame. This is actually not what the spec says,
+ but for compatibility reasons... */
- if (argcount>3) {
- *exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- log_text("Too many arguments. NewObject does not support that");
- return 0;
- }
+ if (lrt->used == lrt->capacity) {
+ if (_Jv_JNI_EnsureLocalCapacity(env, 16) != 0)
+ return NULL;
-
- o = builtin_new (clazz); /* create object */
-
- if (!o) return NULL;
+ /* get the new local reference table */
- va_start(vaargs,methodID);
- for (i=0;i<argcount;i++) {
- args[i]=va_arg(vaargs,void*);
+ lrt = LOCALREFTABLE;
}
- va_end(vaargs);
- asm_calljavafunction(methodID,o,args[0],args[1],args[2]);
- return o;
-}
+ /* insert the reference */
+ for (i = 0; i < lrt->capacity; i++) {
+ if (lrt->refs[i] == NULL) {
+ lrt->refs[i] = (java_handle_t *) ref;
+ lrt->used++;
-/***********************************************************************************
+ return ref;
+ }
+ }
- Constructs a new Java object
- arguments that are to be passed to the constructor are placed in va_list args
+ /* should not happen, just to be sure */
-***********************************************************************************/
+ assert(0);
-jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
-{
- /* log_text("JNI-Call: NewObjectV"); */
+ /* keep compiler happy */
return NULL;
}
-/***********************************************************************************
+/* EnsureLocalCapacity *********************************************************
- Constructs a new Java object
- arguments that are to be passed to the constructor are placed in
- args array of jvalues
+ Ensures that at least a given number of local references can be
+ created in the current thread
-***********************************************************************************/
+*******************************************************************************/
-jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
+jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
{
- /* log_text("JNI-Call: NewObjectA"); */
+ localref_table *lrt;
- return NULL;
-}
+ STATISTICS(jniinvokation());
+ /* get local reference table (thread specific) */
-/************************ returns the class of an object **************************/
+ lrt = LOCALREFTABLE;
-jclass GetObjectClass(JNIEnv* env, jobject obj)
-{
- classinfo *c = obj->vftbl->class;
+ /* check if capacity elements are available in the local references table */
- use_class_as_object(c);
+ if ((lrt->used + capacity) > lrt->capacity)
+ return _Jv_JNI_PushLocalFrame(env, capacity);
- return c;
+ return 0;
}
-/************* tests whether an object is an instance of a class ******************/
+/* AllocObject *****************************************************************
-jboolean IsInstanceOf(JNIEnv* env, jobject obj, jclass clazz)
-{
- return builtin_instanceof(obj,clazz);
-}
+ Allocates a new Java object without invoking any of the
+ constructors for the object. Returns a reference to the object.
+*******************************************************************************/
-/***************** converts a java.lang.reflect.Field to a field ID ***************/
-
-jfieldID FromReflectedField(JNIEnv* env, jobject field)
+jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
{
- log_text("JNI-Call: FromReflectedField");
+ classinfo *c;
+ java_handle_t *o;
- return 0;
+ STATISTICS(jniinvokation());
+
+ c = (classinfo *) clazz;
+
+ if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
+ exceptions_throw_instantiationexception(c);
+ return NULL;
+ }
+
+ o = builtin_new(c);
+
+ return _Jv_JNI_NewLocalRef(env, (jobject) o);
}
-/**********************************************************************************
+/* NewObject *******************************************************************
- converts a method ID to a java.lang.reflect.Method or
- java.lang.reflect.Constructor object
+ 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 ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
+jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
{
- log_text("JNI-Call: ToReflectedMethod");
+ java_handle_t *o;
+ classinfo *c;
+ methodinfo *m;
+ va_list ap;
- return NULL;
-}
+ STATISTICS(jniinvokation());
+ c = (classinfo *) clazz;
+ m = (methodinfo *) methodID;
-/**************** returns the method ID for an instance method ********************/
+ /* create object */
-jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
-{
- jmethodID m;
+ o = builtin_new(c);
+
+ if (o == NULL)
+ return NULL;
- m = class_resolvemethod (
- clazz,
- utf_new_char ((char*) name),
- utf_new_char ((char*) sig)
- );
+ /* call constructor */
- if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+ va_start(ap, methodID);
+ _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
+ va_end(ap);
- return m;
+ return _Jv_JNI_NewLocalRef(env, (jobject) o);
}
-/******************** JNI-functions for calling instance methods ******************/
+/* NewObjectV ******************************************************************
-jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
- jobject ret;
- va_list vaargs;
+ Programmers place all arguments that are to be passed to the
+ constructor in an args argument of type va_list that immediately
+ follows the methodID argument. NewObjectV() accepts these
+ arguments, and, in turn, passes them to the Java method that the
+ programmer wishes to invoke.
-/* log_text("JNI-Call: CallObjectMethod");*/
+*******************************************************************************/
- va_start(vaargs, methodID);
- ret = callObjectMethod(obj, methodID, vaargs);
- va_end(vaargs);
+jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
+ va_list args)
+{
+ java_handle_t *o;
+ classinfo *c;
+ methodinfo *m;
- return ret;
-}
+ STATISTICS(jniinvokation());
+ c = (classinfo *) clazz;
+ m = (methodinfo *) methodID;
-jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
-{
- return callObjectMethod(obj,methodID,args);
-}
+ /* create object */
+ o = builtin_new(c);
+
+ if (o == NULL)
+ return NULL;
-jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
-{
- log_text("JNI-Call: CallObjectMethodA");
+ /* call constructor */
- return NULL;
+ _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
+
+ return _Jv_JNI_NewLocalRef(env, (jobject) o);
}
+/* NewObjectA *****************************************************************
+ Programmers place all arguments that are to be passed to the
+ constructor in an args array of jvalues that immediately follows
+ the methodID argument. NewObjectA() accepts the arguments in this
+ array, and, in turn, passes them to the Java method that the
+ programmer wishes to invoke.
+
+*******************************************************************************/
-jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
+jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
+ const jvalue *args)
{
- jboolean ret;
- va_list vaargs;
+ java_handle_t *o;
+ classinfo *c;
+ methodinfo *m;
-/* log_text("JNI-Call: CallBooleanMethod");*/
+ STATISTICS(jniinvokation());
- va_start(vaargs,methodID);
- ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',vaargs);
- va_end(vaargs);
- return ret;
+ c = (classinfo *) clazz;
+ m = (methodinfo *) methodID;
-}
+ /* create object */
-jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
-{
- return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',args);
+ o = builtin_new(c);
+
+ if (o == NULL)
+ return NULL;
-}
+ /* call constructor */
-jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
-{
- log_text("JNI-Call: CallBooleanMethodA");
+ _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
- return 0;
+ return _Jv_JNI_NewLocalRef(env, (jobject) o);
}
-jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
- jbyte ret;
- va_list vaargs;
-/* log_text("JNI-Call: CallVyteMethod");*/
+/* GetObjectClass **************************************************************
- va_start(vaargs,methodID);
- ret = callIntegerMethod(obj,get_virtual(obj,methodID),'B',vaargs);
- va_end(vaargs);
- return ret;
+ Returns the class of an object.
-}
+*******************************************************************************/
-jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
+jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
{
-/* log_text("JNI-Call: CallByteMethodV");*/
- return callIntegerMethod(obj,methodID,'B',args);
-}
+ java_handle_t *o;
+ classinfo *c;
+ STATISTICS(jniinvokation());
-jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallByteMethodA");
+ o = (java_handle_t *) obj;
- return 0;
-}
+ if ((o == NULL) || (o->vftbl == NULL))
+ return NULL;
+ c = o->vftbl->class;
-jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
- jchar ret;
- va_list vaargs;
+ return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
+}
-/* log_text("JNI-Call: CallCharMethod");*/
- va_start(vaargs,methodID);
- ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'C', vaargs);
- va_end(vaargs);
+/* IsInstanceOf ****************************************************************
- return ret;
-}
+ Tests whether an object is an instance of a class.
+*******************************************************************************/
-jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
+jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
{
-/* log_text("JNI-Call: CallCharMethodV");*/
- return callIntegerMethod(obj,get_virtual(obj,methodID),'C',args);
-}
+ java_lang_Class *c;
+ java_lang_Object *o;
+ STATISTICS(jniinvokation());
-jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallCharMethodA");
+ c = (java_lang_Class *) clazz;
+ o = (java_lang_Object *) obj;
- return 0;
+ return _Jv_java_lang_Class_isInstance(c, o);
}
-jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
- jshort ret;
- va_list vaargs;
+/* Reflection Support *********************************************************/
-/* log_text("JNI-Call: CallShortMethod");*/
+/* FromReflectedMethod *********************************************************
- va_start(vaargs, methodID);
- ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'S', vaargs);
- va_end(vaargs);
+ Converts java.lang.reflect.Method or java.lang.reflect.Constructor
+ object to a method ID.
+
+*******************************************************************************/
+
+jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
+{
+#if defined(ENABLE_JAVASE)
+ java_handle_t *o;
+ classinfo *c;
+ methodinfo *m;
+ s4 slot;
- return ret;
-}
+ STATISTICS(jniinvokation());
+ o = (java_handle_t *) method;
-jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
-{
- return callIntegerMethod(obj, get_virtual(obj, methodID), 'S', args);
-}
+ if (o == NULL)
+ return NULL;
+
+ if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
+ java_lang_reflect_Method *rm;
+ rm = (java_lang_reflect_Method *) method;
+ LLNI_field_get_cls(rm, clazz, c);
+ LLNI_field_get_val(rm, slot , slot);
+ }
+ else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
+ java_lang_reflect_Constructor *rc;
-jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallShortMethodA");
+ rc = (java_lang_reflect_Constructor *) method;
+ LLNI_field_get_cls(rc, clazz, c);
+ LLNI_field_get_val(rc, slot , slot);
+ }
+ else
+ return NULL;
- return 0;
-}
+ m = &(c->methods[slot]);
+ return (jmethodID) m;
+#else
+ vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
+ /* keep compiler happy */
-jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
- jint ret;
- va_list vaargs;
+ return NULL;
+#endif
+}
- va_start(vaargs,methodID);
- ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'I', vaargs);
- va_end(vaargs);
- return ret;
-}
+/* FromReflectedField **********************************************************
+ Converts a java.lang.reflect.Field to a field ID.
-jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
+*******************************************************************************/
+
+jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
{
- return callIntegerMethod(obj, get_virtual(obj, methodID), 'I', args);
-}
+#if defined(ENABLE_JAVASE)
+ java_lang_reflect_Field *rf;
+ classinfo *c;
+ fieldinfo *f;
+ int32_t slot;
+ STATISTICS(jniinvokation());
-jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallIntMethodA");
+ rf = (java_lang_reflect_Field *) field;
- return 0;
-}
+ if (rf == NULL)
+ return NULL;
+ LLNI_field_get_cls(rf, clazz, c);
+ LLNI_field_get_val(rf, slot , slot);
+ f = &(c->fields[slot]);
+ return (jfieldID) f;
+#else
+ vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
-jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
- log_text("JNI-Call: CallLongMethod");
+ /* keep compiler happy */
- return 0;
+ return NULL;
+#endif
}
-jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
-{
- log_text("JNI-Call: CallLongMethodV");
+/* ToReflectedMethod ***********************************************************
- return 0;
-}
+ Converts a method ID derived from cls to an instance of the
+ java.lang.reflect.Method class or to an instance of the
+ java.lang.reflect.Constructor class.
+*******************************************************************************/
-jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
+jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
+ jboolean isStatic)
{
- log_text("JNI-Call: CallLongMethodA");
+#if defined(ENABLE_JAVASE)
+ methodinfo *m;
+ java_lang_reflect_Constructor *rc;
+ java_lang_reflect_Method *rm;
- return 0;
-}
+ STATISTICS(jniinvokation());
+ m = (methodinfo *) methodID;
+ /* HotSpot does the same assert. */
-jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
- jfloat ret;
- va_list vaargs;
+ assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
-/* log_text("JNI-Call: CallFloatMethod");*/
+ if (m->name == utf_init) {
+ rc = reflect_constructor_new(m);
- va_start(vaargs,methodID);
- ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'F');
- va_end(vaargs);
+ return (jobject) rc;
+ }
+ else {
+ rm = reflect_method_new(m);
- return ret;
-}
+ return (jobject) rm;
+ }
+#else
+ vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
+ /* keep compiler happy */
-jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
-{
- log_text("JNI-Call: CallFloatMethodV");
- return callFloatMethod(obj, get_virtual(obj, methodID), args, 'F');
+ return NULL;
+#endif
}
-jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallFloatMethodA");
-
- return 0;
-}
+/* ToReflectedField ************************************************************
+ Converts a field ID derived from cls to an instance of the
+ java.lang.reflect.Field class.
+*******************************************************************************/
-jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
+jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
+ jboolean isStatic)
{
- jdouble ret;
- va_list vaargs;
-
-/* log_text("JNI-Call: CallDoubleMethod");*/
+ STATISTICS(jniinvokation());
- va_start(vaargs,methodID);
- ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'D');
- va_end(vaargs);
+ log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
- return ret;
+ return NULL;
}
-jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
-{
- log_text("JNI-Call: CallDoubleMethodV");
- return callFloatMethod(obj, get_virtual(obj, methodID), args, 'D');
-}
+/* Calling Instance Methods ***************************************************/
+/* GetMethodID *****************************************************************
-jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallDoubleMethodA");
- return 0;
-}
+ 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.
+*******************************************************************************/
-void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
+jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
+ const char *sig)
{
- va_list vaargs;
+ classinfo *c;
+ utf *uname;
+ utf *udesc;
+ methodinfo *m;
-/* log_text("JNI-Call: CallVoidMethod");*/
+ STATISTICS(jniinvokation());
- va_start(vaargs,methodID);
- (void) callIntegerMethod(obj, get_virtual(obj, methodID), 'V', vaargs);
- va_end(vaargs);
-}
+ c = (classinfo *) clazz;
+ if (c == NULL)
+ return NULL;
-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);
-}
+ if (!(c->state & CLASS_INITIALIZED))
+ if (!initialize_class(c))
+ return NULL;
+ /* try to get the method of the class or one of it's superclasses */
-void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
-{
- log_text("JNI-Call: CallVoidMethodA");
-}
+ uname = utf_new_char((char *) name);
+ udesc = utf_new_char((char *) sig);
+ m = class_resolvemethod(c, uname, udesc);
+ if ((m == NULL) || (m->flags & ACC_STATIC)) {
+ exceptions_throw_nosuchmethoderror(c, uname, udesc);
-jobject CallNonvirtualObjectMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
-{
- log_text("JNI-Call: CallNonvirtualObjectMethod");
+ return NULL;
+ }
- return NULL;
+ return (jmethodID) m;
+}
+
+
+/* JNI-functions for calling instance methods *********************************/
+
+#define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
+type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
+ jmethodID methodID, ...) \
+{ \
+ java_handle_t *o; \
+ methodinfo *m; \
+ va_list ap; \
+ type ret; \
+ \
+ o = (java_handle_t *) obj; \
+ m = (methodinfo *) methodID; \
+ \
+ va_start(ap, methodID); \
+ ret = _Jv_jni_Call##intern##Method(o, o->vftbl, m, ap); \
+ va_end(ap); \
+ \
+ return ret; \
}
+JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
+JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
+JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
+JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
+JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
+JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
+JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
+JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
-jobject CallNonvirtualObjectMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
-{
- log_text("JNI-Call: CallNonvirtualObjectMethodV");
- return NULL;
+#define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
+type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
+ jmethodID methodID, va_list args) \
+{ \
+ java_handle_t *o; \
+ methodinfo *m; \
+ type ret; \
+ \
+ o = (java_handle_t *) obj; \
+ m = (methodinfo *) methodID; \
+ \
+ ret = _Jv_jni_Call##intern##Method(o, o->vftbl, m, args); \
+ \
+ return ret; \
}
+JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
+JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
+JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
+JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
+JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
+JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
+JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
+JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
-jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
-{
- log_text("JNI-Call: CallNonvirtualObjectMethodA");
- return NULL;
+#define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
+type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
+ jmethodID methodID, \
+ const jvalue *args) \
+{ \
+ java_handle_t *o; \
+ methodinfo *m; \
+ type ret; \
+ \
+ o = (java_handle_t *) obj; \
+ m = (methodinfo *) methodID; \
+ \
+ ret = _Jv_jni_Call##intern##MethodA(o, o->vftbl, m, args); \
+ \
+ return ret; \
}
+JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
+JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
+JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
+JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
+JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
+JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
+JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
+JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
-jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
+jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
+ ...)
{
- jboolean ret;
- va_list vaargs;
+ java_handle_t *o;
+ methodinfo *m;
+ java_handle_t *ret;
+ va_list ap;
-/* log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
+ o = (java_handle_t *) obj;
+ m = (methodinfo *) methodID;
- va_start(vaargs,methodID);
- ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',vaargs);
- va_end(vaargs);
- return ret;
+ va_start(ap, methodID);
+ ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, ap);
+ va_end(ap);
+ return _Jv_JNI_NewLocalRef(env, (jobject) ret);
}
-jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
+jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
+ va_list args)
{
-/* log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
- return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',args);
-}
+ java_handle_t *o;
+ methodinfo *m;
+ java_handle_t *ret;
+ o = (java_handle_t *) obj;
+ m = (methodinfo *) methodID;
-jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
-{
- log_text("JNI-Call: CallNonvirtualBooleanMethodA");
+ ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, args);
- return 0;
+ return _Jv_JNI_NewLocalRef(env, (jobject) ret);
}
-
-jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
+jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
+ const jvalue *args)
{
- jbyte ret;
- va_list vaargs;
+ java_handle_t *o;
+ methodinfo *m;
+ java_handle_t *ret;
+
+ o = (java_handle_t *) obj;
+ m = (methodinfo *) methodID;
-/* log_text("JNI-Call: CallNonvirutalByteMethod");*/
+ ret = _Jv_jni_CallObjectMethodA(o, o->vftbl, m, args);
- va_start(vaargs,methodID);
- ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',vaargs);
- va_end(vaargs);
- return ret;
+ return _Jv_JNI_NewLocalRef(env, (jobject) ret);
}
-jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
+
+void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
{
- /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
- return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',args);
+ java_handle_t *o;
+ methodinfo *m;
+ va_list ap;
+
+ o = (java_handle_t *) obj;
+ m = (methodinfo *) methodID;
+ va_start(ap, methodID);
+ _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
+ va_end(ap);
}
-jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
+void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
+ va_list args)
{
- log_text("JNI-Call: CallNonvirtualByteMethodA");
+ java_handle_t *o;
+ methodinfo *m;
- return 0;
-}
+ o = (java_handle_t *) obj;
+ m = (methodinfo *) methodID;
+ _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
+}
-jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
+void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
+ const jvalue *args)
{
- jchar ret;
- va_list vaargs;
+ java_handle_t *o;
+ methodinfo *m;
-/* log_text("JNI-Call: CallNonVirtualCharMethod");*/
+ o = (java_handle_t *) obj;
+ m = (methodinfo *) methodID;
- va_start(vaargs,methodID);
- ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',vaargs);
- va_end(vaargs);
- return ret;
+ _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
}
-jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
-{
- /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
- return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',args);
+
+#define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
+type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
+ jclass clazz, jmethodID methodID, \
+ ...) \
+{ \
+ java_handle_t *o; \
+ classinfo *c; \
+ methodinfo *m; \
+ va_list ap; \
+ type ret; \
+ \
+ o = (java_handle_t *) obj; \
+ c = (classinfo *) clazz; \
+ m = (methodinfo *) methodID; \
+ \
+ va_start(ap, methodID); \
+ ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
+ va_end(ap); \
+ \
+ return ret; \
}
+JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
+JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
+JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
+JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
+JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
+JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
+JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
+JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
-jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallNonvirtualCharMethodA");
- return 0;
+#define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
+type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
+ jclass clazz, jmethodID methodID, \
+ va_list args) \
+{ \
+ java_handle_t *o; \
+ classinfo *c; \
+ methodinfo *m; \
+ type ret; \
+ \
+ o = (java_handle_t *) obj; \
+ c = (classinfo *) clazz; \
+ m = (methodinfo *) methodID; \
+ \
+ ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
+ \
+ return ret; \
}
+JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
+JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
+JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
+JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
+JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
+JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
+JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
+JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
+
+#define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
+type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
+ jclass clazz, jmethodID methodID, \
+ const jvalue *args) \
+{ \
+ log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
+ \
+ return 0; \
+}
+
+JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
+JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
+JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
+JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
+JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
+JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
+JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
+JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
-jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
+jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
+ jclass clazz, jmethodID methodID,
+ ...)
{
- jshort ret;
- va_list vaargs;
+ java_handle_t *o;
+ classinfo *c;
+ methodinfo *m;
+ java_handle_t *r;
+ va_list ap;
- /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
+ o = (java_handle_t *) obj;
+ c = (classinfo *) clazz;
+ m = (methodinfo *) methodID;
- va_start(vaargs,methodID);
- ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',vaargs);
- va_end(vaargs);
- return ret;
+ va_start(ap, methodID);
+ r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
+ va_end(ap);
+
+ return _Jv_JNI_NewLocalRef(env, (jobject) r);
}
-jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
+jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
+ jclass clazz, jmethodID methodID,
+ va_list args)
{
- /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
- return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',args);
+ java_handle_t *o;
+ classinfo *c;
+ methodinfo *m;
+ java_handle_t *r;
+
+ o = (java_handle_t *) obj;
+ c = (classinfo *) clazz;
+ m = (methodinfo *) methodID;
+
+ r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
+
+ return _Jv_JNI_NewLocalRef(env, (jobject) r);
}
-jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
+jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
+ jclass clazz, jmethodID methodID,
+ const jvalue *args)
{
- log_text("JNI-Call: CallNonvirtualShortMethodA");
+ log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
- return 0;
+ return _Jv_JNI_NewLocalRef(env, NULL);
}
-
-jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
+void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
+ jmethodID methodID, ...)
{
+ java_handle_t *o;
+ classinfo *c;
+ methodinfo *m;
+ va_list ap;
- jint ret;
- va_list vaargs;
+ o = (java_handle_t *) obj;
+ c = (classinfo *) clazz;
+ m = (methodinfo *) methodID;
- /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
-
- va_start(vaargs,methodID);
- ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',vaargs);
- va_end(vaargs);
- return ret;
+ va_start(ap, methodID);
+ _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
+ va_end(ap);
}
-jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
+void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
+ jmethodID methodID, va_list args)
{
- /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
- return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',args);
+ java_handle_t *o;
+ classinfo *c;
+ methodinfo *m;
+
+ o = (java_handle_t *) obj;
+ c = (classinfo *) clazz;
+ m = (methodinfo *) methodID;
+
+ _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
}
-jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallNonvirtualIntMethodA");
+void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
+ jmethodID methodID, const jvalue * args)
+{
+ java_handle_t *o;
+ classinfo *c;
+ methodinfo *m;
- return 0;
+ o = (java_handle_t *) obj;
+ c = (classinfo *) clazz;
+ m = (methodinfo *) methodID;
+
+ _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
}
+/* Accessing Fields of Objects ************************************************/
-jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
-{
- log_text("JNI-Call: CallNonvirtualLongMethod");
+/* GetFieldID ******************************************************************
- return 0;
-}
+ 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.
+*******************************************************************************/
-jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
+jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
+ const char *sig)
{
- log_text("JNI-Call: CallNonvirtualLongMethodV");
+ classinfo *c;
+ fieldinfo *f;
+ utf *uname;
+ utf *udesc;
- return 0;
-}
+ STATISTICS(jniinvokation());
+ c = (classinfo *) clazz;
-jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallNonvirtualLongMethodA");
+ /* XXX NPE check? */
- return 0;
-}
+ uname = utf_new_char((char *) name);
+ udesc = utf_new_char((char *) sig);
+ f = class_findfield(c, uname, udesc);
+
+ if (f == NULL)
+ exceptions_throw_nosuchfielderror(c, uname);
+ return (jfieldID) f;
+}
-jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
-{
- jfloat ret;
- va_list vaargs;
- /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
+/* Get<type>Field Routines *****************************************************
+ 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().
- va_start(vaargs,methodID);
- ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'F');
- va_end(vaargs);
- return ret;
+*******************************************************************************/
+#define JNI_GET_FIELD(name, type, intern) \
+type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
+{ \
+ intern ret; \
+ \
+ STATISTICS(jniinvokation()); \
+ \
+ ret = GET_FIELD(obj, intern, fieldID); \
+ \
+ return (type) ret; \
}
+JNI_GET_FIELD(Boolean, jboolean, s4)
+JNI_GET_FIELD(Byte, jbyte, s4)
+JNI_GET_FIELD(Char, jchar, s4)
+JNI_GET_FIELD(Short, jshort, s4)
+JNI_GET_FIELD(Int, jint, s4)
+JNI_GET_FIELD(Long, jlong, s8)
+JNI_GET_FIELD(Float, jfloat, float)
+JNI_GET_FIELD(Double, jdouble, double)
+
-jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
+jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
{
- log_text("JNI-Call: CallNonvirtualFloatMethodV");
- return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'F');
-}
+ java_handle_t *o;
+ STATISTICS(jniinvokation());
-jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallNonvirtualFloatMethodA");
+#warning this needs to be fixed
+ o = GET_FIELD(obj, java_handle_t*, fieldID);
- return 0;
+ return _Jv_JNI_NewLocalRef(env, (jobject) o);
}
+/* Set<type>Field Routines *****************************************************
-jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
-{
- jdouble ret;
- va_list vaargs;
- log_text("JNI-Call: CallNonvirtualDoubleMethod");
+ 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().
- va_start(vaargs,methodID);
- ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'D');
- va_end(vaargs);
- return ret;
+*******************************************************************************/
+#define JNI_SET_FIELD(name, type, intern) \
+void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
+ type value) \
+{ \
+ STATISTICS(jniinvokation()); \
+ \
+ SET_FIELD(obj, intern, fieldID, value); \
}
-
-jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
-{
-/* log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
- return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'D');
-}
+JNI_SET_FIELD(Boolean, jboolean, s4)
+JNI_SET_FIELD(Byte, jbyte, s4)
+JNI_SET_FIELD(Char, jchar, s4)
+JNI_SET_FIELD(Short, jshort, s4)
+JNI_SET_FIELD(Int, jint, s4)
+JNI_SET_FIELD(Long, jlong, s8)
+JNI_SET_FIELD(Float, jfloat, float)
+JNI_SET_FIELD(Double, jdouble, double)
-jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
+void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
+ jobject value)
{
- log_text("JNI-Call: CallNonvirtualDoubleMethodA");
+ STATISTICS(jniinvokation());
- return 0;
+#warning this needs to be fixed
+ SET_FIELD(obj, java_handle_t*, fieldID, value);
}
+/* Calling Static Methods *****************************************************/
-void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
-{
- va_list vaargs;
-
-/* log_text("JNI-Call: CallNonvirtualVoidMethod");*/
+/* GetStaticMethodID ***********************************************************
- va_start(vaargs,methodID);
- (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',vaargs);
- va_end(vaargs);
+ 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.
+*******************************************************************************/
-void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
+jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
+ const char *sig)
{
-/* log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
-
- (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',args);
+ classinfo *c;
+ utf *uname;
+ utf *udesc;
+ methodinfo *m;
-}
+ STATISTICS(jniinvokation());
+ c = (classinfo *) clazz;
-void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
-{
- log_text("JNI-Call: CallNonvirtualVoidMethodA");
-}
+ if (!c)
+ return NULL;
-/************************* JNI-functions for accessing fields ************************/
+ if (!(c->state & CLASS_INITIALIZED))
+ if (!initialize_class(c))
+ return NULL;
-jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
-{
- jfieldID f;
+ /* try to get the static method of the class */
-/* log_text("========================= searching for:");
- log_text(name);
- log_text(sig);*/
- f = jclass_findfield(clazz,
- utf_new_char ((char*) name),
- utf_new_char ((char*) sig)
- );
-
- if (!f) {
-/* utf_display(clazz->name);
- log_text(name);
- log_text(sig);*/
- *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
- }
- return f;
-}
+ uname = utf_new_char((char *) name);
+ udesc = utf_new_char((char *) sig);
-/*************************** retrieve fieldid, abort on error ************************/
+ m = class_resolvemethod(c, uname, udesc);
-jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
-{
- jfieldID id = GetFieldID(env, clazz, name, sig);
+ if ((m == NULL) || !(m->flags & ACC_STATIC)) {
+ exceptions_throw_nosuchmethoderror(c, uname, udesc);
- if (!id) {
- log_text("class:");
- utf_display(clazz->name);
- log_text("\nfield:");
- log_text(name);
- log_text("sig:");
- log_text(sig);
+ return NULL;
+ }
- panic("setfield_critical failed");
- }
- return id;
+ return (jmethodID) m;
}
-jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
-{
- return getField(obj,jobject,fieldID);
+
+#define JNI_CALL_STATIC_METHOD(name, type, intern) \
+type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
+ jmethodID methodID, ...) \
+{ \
+ methodinfo *m; \
+ va_list ap; \
+ type res; \
+ \
+ m = (methodinfo *) methodID; \
+ \
+ va_start(ap, methodID); \
+ res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
+ va_end(ap); \
+ \
+ return res; \
}
-jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
-{
- return getField(obj,jboolean,fieldID);
-}
+JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
+JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
+JNI_CALL_STATIC_METHOD(Char, jchar, Int)
+JNI_CALL_STATIC_METHOD(Short, jshort, Int)
+JNI_CALL_STATIC_METHOD(Int, jint, Int)
+JNI_CALL_STATIC_METHOD(Long, jlong, Long)
+JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
+JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
-jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
-{
- return getField(obj,jbyte,fieldID);
+#define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
+type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
+ jmethodID methodID, va_list args) \
+{ \
+ methodinfo *m; \
+ type res; \
+ \
+ m = (methodinfo *) methodID; \
+ \
+ res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
+ \
+ return res; \
}
+JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
+JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
+JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
+JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
+JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
+JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
+JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
+JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
-jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
-{
- return getField(obj,jchar,fieldID);
+
+#define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
+type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
+ jmethodID methodID, const jvalue *args) \
+{ \
+ methodinfo *m; \
+ type res; \
+ \
+ m = (methodinfo *) methodID; \
+ \
+ res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
+ \
+ return res; \
}
+JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
+JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
+JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
+JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
+JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
+JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
+JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
+JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
+
-jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
+jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
+ jmethodID methodID, ...)
{
- return getField(obj,jshort,fieldID);
-}
+ methodinfo *m;
+ java_handle_t *o;
+ va_list ap;
+ m = (methodinfo *) methodID;
-jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
-{
- return getField(obj,jint,fieldID);
+ va_start(ap, methodID);
+ o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
+ va_end(ap);
+
+ return _Jv_JNI_NewLocalRef(env, (jobject) o);
}
-jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
+jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
+ jmethodID methodID, va_list args)
{
- return getField(obj,jlong,fieldID);
-}
+ methodinfo *m;
+ java_handle_t *o;
+ m = (methodinfo *) methodID;
-jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
-{
- return getField(obj,jfloat,fieldID);
+ o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
+
+ return _Jv_JNI_NewLocalRef(env, (jobject) o);
}
-jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
+jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
+ jmethodID methodID, const jvalue *args)
{
- return getField(obj,jdouble,fieldID);
-}
+ methodinfo *m;
+ java_handle_t *o;
-void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
-{
- setField(obj,jobject,fieldID,val);
-}
+ m = (methodinfo *) methodID;
+ o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
-void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
-{
- setField(obj,jboolean,fieldID,val);
+ return _Jv_JNI_NewLocalRef(env, (jobject) o);
}
-void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
+void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
+ jmethodID methodID, ...)
{
- setField(obj,jbyte,fieldID,val);
-}
+ methodinfo *m;
+ va_list ap;
+ m = (methodinfo *) methodID;
-void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
-{
- setField(obj,jchar,fieldID,val);
+ va_start(ap, methodID);
+ _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
+ va_end(ap);
}
-void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
+void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
+ jmethodID methodID, va_list args)
{
- setField(obj,jshort,fieldID,val);
-}
+ methodinfo *m;
+ m = (methodinfo *) methodID;
-void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
-{
- setField(obj,jint,fieldID,val);
+ _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
}
-void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
+void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
+ jmethodID methodID, const jvalue * args)
{
- setField(obj,jlong,fieldID,val);
-}
+ methodinfo *m;
+ m = (methodinfo *) methodID;
-void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
-{
- setField(obj,jfloat,fieldID,val);
+ _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
}
-void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
-{
- setField(obj,jdouble,fieldID,val);
-}
+/* Accessing Static Fields ****************************************************/
+/* GetStaticFieldID ************************************************************
-/**************** JNI-functions for calling static methods **********************/
+ 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.
+
+*******************************************************************************/
-jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
+jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
+ const char *sig)
{
- jmethodID m;
+ classinfo *c;
+ fieldinfo *f;
+ utf *uname;
+ utf *usig;
+
+ STATISTICS(jniinvokation());
- m = class_resolvemethod(clazz,
- utf_new_char((char *) name),
- utf_new_char((char *) sig));
+ c = (classinfo *) clazz;
- if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+ uname = utf_new_char((char *) name);
+ usig = utf_new_char((char *) sig);
+
+ f = class_findfield(c, uname, usig);
+
+ if (f == NULL)
+ exceptions_throw_nosuchfielderror(c, uname);
- return m;
+ return (jfieldID) f;
}
-jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
- log_text("JNI-Call: CallStaticObjectMethod");
+/* GetStatic<type>Field ********************************************************
- return NULL;
-}
+ This family of accessor routines returns the value of a static
+ field of an object.
+*******************************************************************************/
-jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
+#define JNI_GET_STATIC_FIELD(name, type, field) \
+type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
+ jfieldID fieldID) \
+{ \
+ classinfo *c; \
+ fieldinfo *f; \
+ \
+ STATISTICS(jniinvokation()); \
+ \
+ c = (classinfo *) clazz; \
+ f = (fieldinfo *) fieldID; \
+ \
+ if (!(c->state & CLASS_INITIALIZED)) \
+ if (!initialize_class(c)) \
+ return 0; \
+ \
+ return f->value->field; \
+}
+
+JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
+JNI_GET_STATIC_FIELD(Byte, jbyte, i)
+JNI_GET_STATIC_FIELD(Char, jchar, i)
+JNI_GET_STATIC_FIELD(Short, jshort, i)
+JNI_GET_STATIC_FIELD(Int, jint, i)
+JNI_GET_STATIC_FIELD(Long, jlong, l)
+JNI_GET_STATIC_FIELD(Float, jfloat, f)
+JNI_GET_STATIC_FIELD(Double, jdouble, d)
+
+
+jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
+ jfieldID fieldID)
{
- log_text("JNI-Call: CallStaticObjectMethodV");
+ classinfo *c;
+ fieldinfo *f;
- return NULL;
-}
+ STATISTICS(jniinvokation());
+ c = (classinfo *) clazz;
+ f = (fieldinfo *) fieldID;
-jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallStaticObjectMethodA");
+ if (!(c->state & CLASS_INITIALIZED))
+ if (!initialize_class(c))
+ return NULL;
- return NULL;
+ return _Jv_JNI_NewLocalRef(env, f->value->a);
}
-jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
- jboolean ret;
- va_list vaargs;
+/* SetStatic<type>Field *******************************************************
- /* log_text("JNI-Call: CallStaticBooleanMethod");*/
+ This family of accessor routines sets the value of a static field
+ of an object.
- va_start(vaargs, methodID);
- ret = (jboolean) callIntegerMethod(0, methodID, 'Z', vaargs);
- va_end(vaargs);
+*******************************************************************************/
- return ret;
-}
+#define JNI_SET_STATIC_FIELD(name, type, field) \
+void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
+ jfieldID fieldID, \
+ type value) \
+{ \
+ classinfo *c; \
+ fieldinfo *f; \
+ \
+ STATISTICS(jniinvokation()); \
+ \
+ c = (classinfo *) clazz; \
+ f = (fieldinfo *) fieldID; \
+ \
+ if (!(c->state & CLASS_INITIALIZED)) \
+ if (!initialize_class(c)) \
+ return; \
+ \
+ f->value->field = value; \
+}
+
+JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
+JNI_SET_STATIC_FIELD(Byte, jbyte, i)
+JNI_SET_STATIC_FIELD(Char, jchar, i)
+JNI_SET_STATIC_FIELD(Short, jshort, i)
+JNI_SET_STATIC_FIELD(Int, jint, i)
+JNI_SET_STATIC_FIELD(Long, jlong, l)
+JNI_SET_STATIC_FIELD(Float, jfloat, f)
+JNI_SET_STATIC_FIELD(Double, jdouble, d)
+
+
+void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
+ jobject value)
+{
+ classinfo *c;
+ fieldinfo *f;
+ STATISTICS(jniinvokation());
-jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
-{
- return (jboolean) callIntegerMethod(0, methodID, 'Z', args);
+ c = (classinfo *) clazz;
+ f = (fieldinfo *) fieldID;
+
+ if (!(c->state & CLASS_INITIALIZED))
+ if (!initialize_class(c))
+ return;
+
+ f->value->a = value;
}
-jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallStaticBooleanMethodA");
+/* String Operations **********************************************************/
- return 0;
-}
+/* NewString *******************************************************************
+ Create new java.lang.String object from an array of Unicode
+ characters.
-jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
+*******************************************************************************/
+
+jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
{
- jbyte ret;
- va_list vaargs;
+ java_lang_String *s;
+ java_handle_chararray_t *a;
+ u4 i;
- /* log_text("JNI-Call: CallStaticByteMethod");*/
+ STATISTICS(jniinvokation());
+
+ s = (java_lang_String *) builtin_new(class_java_lang_String);
+ a = builtin_newarray_char(len);
- va_start(vaargs, methodID);
- ret = (jbyte) callIntegerMethod(0, methodID, 'B', vaargs);
- va_end(vaargs);
+ /* javastring or characterarray could not be created */
+ if ((a == NULL) || (s == NULL))
+ return NULL;
- return ret;
-}
+ /* copy text */
+ for (i = 0; i < len; i++)
+ LLNI_array_direct(a, i) = buf[i];
+ LLNI_field_set_ref(s, value , a);
+ LLNI_field_set_val(s, offset, 0);
+ LLNI_field_set_val(s, count , len);
-jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
-{
- return (jbyte) callIntegerMethod(0, methodID, 'B', args);
+ return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
}
-jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallStaticByteMethodA");
+static jchar emptyStringJ[]={0,0};
- return 0;
-}
+/* GetStringLength *************************************************************
+ Returns the length (the count of Unicode characters) of a Java
+ string.
-jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
+*******************************************************************************/
+
+jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
{
- jchar ret;
- va_list vaargs;
+ java_lang_String *s;
+ jsize len;
+
+ TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
- /* log_text("JNI-Call: CallStaticByteMethod");*/
+ s = (java_lang_String *) str;
- va_start(vaargs, methodID);
- ret = (jchar) callIntegerMethod(0, methodID, 'C', vaargs);
- va_end(vaargs);
+ LLNI_field_get_val(s, count, len);
- return ret;
+ return len;
}
-jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
+/******************** convertes javastring to u2-array ****************************/
+
+u2 *javastring_tou2(jstring so)
{
- return (jchar) callIntegerMethod(0, methodID, 'C', args);
-}
+ java_lang_String *s;
+ java_handle_chararray_t *a;
+ u2 *stringbuffer;
+ u4 i;
+ int32_t count;
+ int32_t offset;
+ STATISTICS(jniinvokation());
+
+ s = (java_lang_String *) so;
-jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallStaticCharMethodA");
+ if (!s)
+ return NULL;
- return 0;
-}
+ LLNI_field_get_ref(s, value, a);
+ if (!a)
+ return NULL;
+ LLNI_field_get_val(s, count, count);
+ LLNI_field_get_val(s, offset, offset);
-jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
- jshort ret;
- va_list vaargs;
+ /* allocate memory */
- /* log_text("JNI-Call: CallStaticByteMethod");*/
+ stringbuffer = MNEW(u2, count + 1);
- va_start(vaargs, methodID);
- ret = (jshort) callIntegerMethod(0, methodID, 'S', vaargs);
- va_end(vaargs);
+ /* copy text */
- return ret;
-}
+ for (i = 0; i < count; i++)
+ stringbuffer[i] = LLNI_array_direct(a, offset + i);
+
+ /* terminate string */
+ stringbuffer[i] = '\0';
-jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
-{
- /*log_text("JNI-Call: CallStaticShortMethodV");*/
- return (jshort) callIntegerMethod(0, methodID, 'S', args);
+ return stringbuffer;
}
-jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallStaticShortMethodA");
+/* GetStringChars **************************************************************
- return 0;
-}
+ Returns a pointer to the array of Unicode characters of the
+ string. This pointer is valid until ReleaseStringChars() is called.
+*******************************************************************************/
+const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
+{
+ jchar *jc;
-jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
- jint ret;
- va_list vaargs;
+ STATISTICS(jniinvokation());
- /* log_text("JNI-Call: CallStaticIntMethod");*/
+ jc = javastring_tou2(str);
- va_start(vaargs, methodID);
- ret = callIntegerMethod(0, methodID, 'I', vaargs);
- va_end(vaargs);
+ if (jc) {
+ if (isCopy)
+ *isCopy = JNI_TRUE;
+
+ return jc;
+ }
- return ret;
+ if (isCopy)
+ *isCopy = JNI_TRUE;
+
+ return emptyStringJ;
}
-jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
-{
- log_text("JNI-Call: CallStaticIntMethodV");
+/* ReleaseStringChars **********************************************************
- return callIntegerMethod(0, methodID, 'I', args);
-}
+ Informs the VM that the native code no longer needs access to
+ chars. The chars argument is a pointer obtained from string using
+ GetStringChars().
+*******************************************************************************/
-jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
+void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
{
- log_text("JNI-Call: CallStaticIntMethodA");
+ java_lang_String *s;
- return 0;
-}
+ STATISTICS(jniinvokation());
+ if (chars == emptyStringJ)
+ return;
+ s = (java_lang_String *) str;
-jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
- jlong ret;
- va_list vaargs;
+ MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
+}
- /* log_text("JNI-Call: CallStaticLongMethod");*/
- va_start(vaargs, methodID);
- ret = callLongMethod(0, methodID, vaargs);
- va_end(vaargs);
+/* NewStringUTF ****************************************************************
- return ret;
-}
+ Constructs a new java.lang.String object from an array of UTF-8
+ characters.
+*******************************************************************************/
-jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
+jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
{
- log_text("JNI-Call: CallStaticLongMethodV");
-
- return callLongMethod(0,methodID,args);
-}
+ java_lang_String *s;
+ TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
-jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallStaticLongMethodA");
+ s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
- return 0;
+ return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
}
+/****************** returns the utf8 length in bytes of a string *******************/
-jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
- jfloat ret;
- va_list vaargs;
+jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
+{
+ java_lang_String *s;
+ s4 length;
- /* log_text("JNI-Call: CallStaticLongMethod");*/
+ TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
- va_start(vaargs, methodID);
- ret = callFloatMethod(0, methodID, vaargs, 'F');
- va_end(vaargs);
+ s = (java_lang_String *) string;
- return ret;
-}
+ length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
+ return length;
+}
-jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
-{
- return callFloatMethod(0, methodID, args, 'F');
+/* GetStringUTFChars ***********************************************************
-}
+ Returns a pointer to an array of UTF-8 characters of the
+ string. This array is valid until it is released by
+ ReleaseStringUTFChars().
+*******************************************************************************/
-jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
+const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
+ jboolean *isCopy)
{
- log_text("JNI-Call: CallStaticFloatMethodA");
+ utf *u;
- return 0;
-}
+ STATISTICS(jniinvokation());
+ if (string == NULL)
+ return "";
+ if (isCopy)
+ *isCopy = JNI_TRUE;
+
+ u = javastring_toutf((java_handle_t *) string, false);
-jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
- jdouble ret;
- va_list vaargs;
+ if (u != NULL)
+ return u->text;
+
+ return "";
+}
- /* log_text("JNI-Call: CallStaticDoubleMethod");*/
- va_start(vaargs,methodID);
- ret = callFloatMethod(0, methodID, vaargs, 'D');
- va_end(vaargs);
+/* ReleaseStringUTFChars *******************************************************
- return ret;
-}
+ Informs the VM that the native code no longer needs access to
+ utf. The utf argument is a pointer derived from string using
+ GetStringUTFChars().
+*******************************************************************************/
-jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
+void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
{
- log_text("JNI-Call: CallStaticDoubleMethodV");
+ STATISTICS(jniinvokation());
- return callFloatMethod(0, methodID, args, 'D');
+ /* 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 */
}
-jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
-{
- log_text("JNI-Call: CallStaticDoubleMethodA");
+/* Array Operations ***********************************************************/
- return 0;
-}
+/* GetArrayLength **************************************************************
+ Returns the number of elements in the array.
+
+*******************************************************************************/
-void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
+jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
{
- va_list vaargs;
+ java_handle_t *a;
+ jsize size;
-/* log_text("JNI-Call: CallStaticVoidMethod");*/
+ STATISTICS(jniinvokation());
- va_start(vaargs, methodID);
- (void) callIntegerMethod(0, methodID, 'V', vaargs);
- va_end(vaargs);
-}
+ a = (java_handle_t *) array;
+ size = LLNI_array_size(a);
-void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
-{
- log_text("JNI-Call: CallStaticVoidMethodV");
- (void)callIntegerMethod(0, methodID, 'V', args);
+ return size;
}
-void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
-{
- log_text("JNI-Call: CallStaticVoidMethodA");
-}
+/* NewObjectArray **************************************************************
+ Constructs a new array holding objects in class elementClass. All
+ elements are initially set to initialElement.
-/****************** JNI-functions for accessing static fields ********************/
+*******************************************************************************/
-jfieldID GetStaticFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
+jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
+ jclass elementClass, jobject initialElement)
{
- jfieldID f;
+ classinfo *c;
+ java_handle_t *o;
+ java_handle_objectarray_t *oa;
+ s4 i;
- f = jclass_findfield(clazz,
- utf_new_char ((char*) name),
- utf_new_char ((char*) sig)
- );
-
- if (!f) *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
+ STATISTICS(jniinvokation());
- return f;
-}
+ c = (classinfo *) elementClass;
+ o = (java_handle_t *) initialElement;
+ if (length < 0) {
+ exceptions_throw_negativearraysizeexception();
+ return NULL;
+ }
-jobject GetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID)
-{
- class_init(clazz);
- return fieldID->value.a;
-}
+ oa = builtin_anewarray(length, c);
+ if (oa == NULL)
+ return NULL;
-jboolean GetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID)
-{
- class_init(clazz);
- return fieldID->value.i;
-}
+ /* set all elements to initialElement */
+ for (i = 0; i < length; i++)
+ LLNI_objectarray_element_set(oa, i, o);
-jbyte GetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID)
-{
- class_init(clazz);
- return fieldID->value.i;
+ return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
}
-jchar GetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID)
+jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
+ jsize index)
{
- class_init(clazz);
- return fieldID->value.i;
-}
-
+ java_handle_objectarray_t *oa;
+ java_handle_t *o;
-jshort GetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID)
-{
- class_init(clazz);
- return fieldID->value.i;
-}
+ STATISTICS(jniinvokation());
+ oa = (java_handle_objectarray_t *) array;
-jint GetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID)
-{
- class_init(clazz);
- return fieldID->value.i;
-}
+ if (index >= LLNI_array_size(oa)) {
+ exceptions_throw_arrayindexoutofboundsexception();
+ return NULL;
+ }
+ LLNI_objectarray_element_get(oa, index, o);
-jlong GetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID)
-{
- class_init(clazz);
- return fieldID->value.l;
+ return _Jv_JNI_NewLocalRef(env, (jobject) o);
}
-jfloat GetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID)
+void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
+ jsize index, jobject val)
{
- class_init(clazz);
- return fieldID->value.f;
-}
+ java_handle_objectarray_t *oa;
+ java_handle_t *o;
+ STATISTICS(jniinvokation());
-jdouble GetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID)
-{
- class_init(clazz);
- return fieldID->value.d;
-}
+ oa = (java_handle_objectarray_t *) array;
+ o = (java_handle_t *) val;
+ if (index >= LLNI_array_size(oa)) {
+ exceptions_throw_arrayindexoutofboundsexception();
+ return;
+ }
+ /* check if the class of value is a subclass of the element class
+ of the array */
-void SetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
-{
- class_init(clazz);
- fieldID->value.a = value;
+ if (!builtin_canstore(oa, o))
+ return;
+
+ LLNI_objectarray_element_set(oa, index, o);
}
-void SetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
-{
- class_init(clazz);
- fieldID->value.i = value;
+#define JNI_NEW_ARRAY(name, type, intern) \
+type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
+{ \
+ java_handle_##intern##array_t *a; \
+ \
+ STATISTICS(jniinvokation()); \
+ \
+ if (len < 0) { \
+ exceptions_throw_negativearraysizeexception(); \
+ return NULL; \
+ } \
+ \
+ a = builtin_newarray_##intern(len); \
+ \
+ return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
}
+JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
+JNI_NEW_ARRAY(Byte, jbyteArray, byte)
+JNI_NEW_ARRAY(Char, jcharArray, char)
+JNI_NEW_ARRAY(Short, jshortArray, byte)
+JNI_NEW_ARRAY(Int, jintArray, int)
+JNI_NEW_ARRAY(Long, jlongArray, long)
+JNI_NEW_ARRAY(Float, jfloatArray, float)
+JNI_NEW_ARRAY(Double, jdoubleArray, double)
-void SetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
-{
- class_init(clazz);
- fieldID->value.i = value;
-}
+/* Get<PrimitiveType>ArrayElements *********************************************
-void SetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
-{
- class_init(clazz);
- fieldID->value.i = value;
-}
+ A family of functions that returns the body of the primitive array.
+*******************************************************************************/
-void SetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
-{
- class_init(clazz);
- fieldID->value.i = value;
-}
+#define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
+type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
+ jboolean *isCopy) \
+{ \
+ java_handle_##intern##array_t *a; \
+ \
+ STATISTICS(jniinvokation()); \
+ \
+ a = (java_handle_##intern##array_t *) array; \
+ \
+ if (isCopy) \
+ *isCopy = JNI_FALSE; \
+ \
+ return LLNI_array_data(a); \
+}
+
+JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
+JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
+JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
+JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
+JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
+JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
+JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
+JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
+
+
+/* Release<PrimitiveType>ArrayElements *****************************************
+
+ 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 SetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
-{
- class_init(clazz);
- fieldID->value.i = value;
-}
+#define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
+void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
+ type *elems, jint mode) \
+{ \
+ java_handle_##intern##array_t *a; \
+ \
+ STATISTICS(jniinvokation()); \
+ \
+ a = (java_handle_##intern##array_t *) array; \
+ \
+ if (elems != LLNI_array_data(a)) { \
+ switch (mode) { \
+ case JNI_COMMIT: \
+ MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
+ break; \
+ case 0: \
+ MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
+ /* XXX TWISTI how should it be freed? */ \
+ break; \
+ case JNI_ABORT: \
+ /* XXX TWISTI how should it be freed? */ \
+ break; \
+ } \
+ } \
+}
+
+JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
+JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
+JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
+JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
+JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
+JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
+JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
+JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
+
+
+/* Get<PrimitiveType>ArrayRegion **********************************************
+
+ A family of functions that copies a region of a primitive array
+ into a buffer.
+*******************************************************************************/
-void SetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
-{
- class_init(clazz);
- fieldID->value.l = value;
-}
+#define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
+void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
+ jsize start, jsize len, type *buf) \
+{ \
+ java_handle_##intern##array_t *a; \
+ \
+ STATISTICS(jniinvokation()); \
+ \
+ a = (java_handle_##intern##array_t *) array; \
+ \
+ if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
+ exceptions_throw_arrayindexoutofboundsexception(); \
+ else \
+ MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
+}
+
+JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
+JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
+JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
+JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
+JNI_GET_ARRAY_REGION(Int, jint, int, s4)
+JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
+JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
+JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
+
+
+/* Set<PrimitiveType>ArrayRegion **********************************************
+
+ A family of functions that copies back a region of a primitive
+ array from a buffer.
+*******************************************************************************/
-void SetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
-{
- class_init(clazz);
- fieldID->value.f = value;
-}
+#define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
+void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
+ jsize start, jsize len, const type *buf) \
+{ \
+ java_handle_##intern##array_t *a; \
+ \
+ STATISTICS(jniinvokation()); \
+ \
+ a = (java_handle_##intern##array_t *) array; \
+ \
+ if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
+ exceptions_throw_arrayindexoutofboundsexception(); \
+ else \
+ MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
+}
+
+JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
+JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
+JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
+JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
+JNI_SET_ARRAY_REGION(Int, jint, int, s4)
+JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
+JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
+JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
+
+
+/* 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.
+*******************************************************************************/
-void SetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
+jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
+ const JNINativeMethod *methods, jint nMethods)
{
- class_init(clazz);
- fieldID->value.d = value;
-}
-
+ classinfo *c;
-/***** create new java.lang.String object from an array of Unicode characters ****/
+ STATISTICS(jniinvokation());
-jstring NewString (JNIEnv *env, const jchar *buf, jsize len)
-{
- u4 i;
- java_lang_String *s;
- java_chararray *a;
-
- s = (java_lang_String*) builtin_new (class_java_lang_String);
- a = builtin_newarray_char (len);
+ c = (classinfo *) clazz;
- /* javastring or characterarray could not be created */
- if ( (!a) || (!s) ) return NULL;
+ /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
+ if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
+ */
- /* copy text */
- for (i=0; i<len; i++) a->data[i] = buf[i];
- s -> value = a;
- s -> offset = 0;
- s -> count = len;
+ native_method_register(c->name, methods, nMethods);
- return (jstring) s;
+ return 0;
}
-static char emptyString[]="";
-static jchar emptyStringJ[]={0,0};
+/* UnregisterNatives ***********************************************************
-/******************* returns the length of a Java string ***************************/
+ Unregisters native methods of a class. The class goes back to the
+ state before it was linked or registered with its native method
+ functions.
-jsize GetStringLength (JNIEnv *env, jstring str)
-{
- return ((java_lang_String*) str)->count;
-}
+ This function should not be used in normal native code. Instead, it
+ provides special programs a way to reload and relink native
+ libraries.
+*******************************************************************************/
-/******************** convertes javastring to u2-array ****************************/
-
-u2 *javastring_tou2 (jstring so)
+jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
{
- java_lang_String *s = (java_lang_String*) so;
- java_chararray *a;
- u4 i;
- u2 *stringbuffer;
-
- if (!s) return NULL;
+ STATISTICS(jniinvokation());
- a = s->value;
- if (!a) return NULL;
-
- /* allocate memory */
- stringbuffer = MNEW( u2 , s->count + 1 );
+ /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
- /* copy text */
- for (i=0; i<s->count; i++) stringbuffer[i] = a->data[s->offset+i];
-
- /* terminate string */
- stringbuffer[i] = '\0';
+ log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
- return stringbuffer;
+ return 0;
}
-/********* returns a pointer to an array of Unicode characters of the string *******/
-
-const jchar *GetStringChars (JNIEnv *env, jstring str, jboolean *isCopy)
-{
- jchar *jc=javastring_tou2(str);
- if (jc) {
- if (isCopy) *isCopy=JNI_TRUE;
- return jc;
- }
- if (isCopy) *isCopy=JNI_TRUE;
- return emptyStringJ;
-}
+/* Monitor Operations *********************************************************/
-/**************** native code no longer needs access to chars **********************/
+/* MonitorEnter ****************************************************************
-void ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars)
-{
- if (chars==emptyStringJ) return;
- MFREE(((jchar*) chars),jchar,((java_lang_String*) str)->count+1);
-}
+ Enters the monitor associated with the underlying Java object
+ referred to by obj.
-/************ create new java.lang.String object from utf8-characterarray **********/
+*******************************************************************************/
-jstring NewStringUTF (JNIEnv *env, const char *utf)
+jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
{
-/* log_text("NewStringUTF called");*/
- return (jstring) javastring_new(utf_new_char((char *) utf));
-}
+ STATISTICS(jniinvokation());
-/****************** returns the utf8 length in bytes of a string *******************/
+ if (obj == NULL) {
+ exceptions_throw_nullpointerexception();
+ return JNI_ERR;
+ }
-jsize GetStringUTFLength (JNIEnv *env, jstring string)
-{
- java_lang_String *s = (java_lang_String*) string;
+ LOCK_MONITOR_ENTER(obj);
- return (jsize) u2_utflength(s->value->data, s->count);
+ return JNI_OK;
}
-/************ converts a Javastring to an array of UTF-8 characters ****************/
+/* MonitorExit *****************************************************************
-const char* GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
+ 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 _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
{
- utf *u;
+ STATISTICS(jniinvokation());
- u = javastring_toutf((java_lang_String *) string, false);
+ if (obj == NULL) {
+ exceptions_throw_nullpointerexception();
+ return JNI_ERR;
+ }
- if (isCopy)
- *isCopy = JNI_FALSE;
-
- if (u)
- return u->text;
+ LOCK_MONITOR_EXIT(obj);
- return emptyString;
-
+ return JNI_OK;
}
-/***************** native code no longer needs access to utf ***********************/
+/* JavaVM Interface ***********************************************************/
-void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
-{
- /*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));
- */
-}
+/* GetJavaVM *******************************************************************
-/************************** array operations ***************************************/
+ 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.
+
+*******************************************************************************/
-jsize GetArrayLength(JNIEnv *env, jarray array)
+jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
{
- return array->size;
-}
+ STATISTICS(jniinvokation());
+ *vm = (JavaVM *) _Jv_jvm;
-jobjectArray NewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init)
-{
- java_objectarray *j;
+ return 0;
+}
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
- return NULL;
- }
- j = builtin_anewarray(len, clazz);
+/* GetStringRegion *************************************************************
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
+ Copies len number of Unicode characters beginning at offset start
+ to the given buffer buf.
- return j;
-}
+ Throws StringIndexOutOfBoundsException on index overflow.
+*******************************************************************************/
-jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
+void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
+ jchar *buf)
{
- jobject j = NULL;
-
- if (index < array->header.size)
- j = array->data[index];
- else
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
-
- return j;
-}
+ java_lang_String *s;
+ java_handle_chararray_t *ca;
+ STATISTICS(jniinvokation());
-void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
-{
- if (index >= array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ s = (java_lang_String *) str;
+ LLNI_field_get_ref(s, value, ca);
- 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 ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
+ (start + len > LLNI_field_direct(s, count))) {
+ exceptions_throw_stringindexoutofboundsexception();
+ return;
+ }
- else
- array->data[index] = val;
- }
+ MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
}
+/* GetStringUTFRegion **********************************************************
+
+ Translates len number of Unicode characters beginning at offset
+ start into UTF-8 format and place the result in the given buffer
+ buf.
+
+ Throws StringIndexOutOfBoundsException on index overflow.
+
+*******************************************************************************/
-jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
+void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
+ jsize len, char *buf)
{
- java_booleanarray *j;
+ java_lang_String *s;
+ java_handle_chararray_t *ca;
+ s4 i;
+ int32_t count;
+ int32_t offset;
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
- return NULL;
- }
+ TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
+
+ s = (java_lang_String *) str;
+ LLNI_field_get_ref(s, value, ca);
+ LLNI_field_get_val(s, count, count);
+ LLNI_field_get_val(s, offset, offset);
- j = builtin_newarray_boolean(len);
+ if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
+ exceptions_throw_stringindexoutofboundsexception();
+ return;
+ }
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
+ for (i = 0; i < len; i++)
+ buf[i] = LLNI_array_direct(ca, offset + start + i);
- return j;
+ buf[i] = '\0';
}
-jbyteArray NewByteArray(JNIEnv *env, jsize len)
+/* GetPrimitiveArrayCritical ***************************************************
+
+ Obtain a direct pointer to array elements.
+
+*******************************************************************************/
+
+void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
+ jboolean *isCopy)
{
- java_bytearray *j;
+ java_handle_bytearray_t *ba;
+ jbyte *bp;
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
- return NULL;
- }
+ ba = (java_handle_bytearray_t *) array;
- j = builtin_newarray_byte(len);
+ /* do the same as Kaffe does */
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
+ bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
- return j;
+ return (void *) bp;
}
-jcharArray NewCharArray(JNIEnv *env, jsize len)
-{
- java_chararray *j;
+/* ReleasePrimitiveArrayCritical ***********************************************
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
- return NULL;
- }
+ No specific documentation.
+
+*******************************************************************************/
- j = builtin_newarray_char(len);
+void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
+ void *carray, jint mode)
+{
+ STATISTICS(jniinvokation());
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
+ /* do the same as Kaffe does */
- return j;
+ _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
+ mode);
}
-jshortArray NewShortArray(JNIEnv *env, jsize len)
-{
- java_shortarray *j;
+/* GetStringCritical ***********************************************************
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
- return NULL;
- }
+ The semantics of these two functions are similar to the existing
+ Get/ReleaseStringChars functions.
- j = builtin_newarray_short(len);
+*******************************************************************************/
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
+const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
+ jboolean *isCopy)
+{
+ STATISTICS(jniinvokation());
- return j;
+ return _Jv_JNI_GetStringChars(env, string, isCopy);
}
-jintArray NewIntArray(JNIEnv *env, jsize len)
+void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
+ const jchar *cstring)
{
- java_intarray *j;
+ STATISTICS(jniinvokation());
+
+ _Jv_JNI_ReleaseStringChars(env, string, cstring);
+}
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
- return NULL;
- }
- j = builtin_newarray_int(len);
+jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
+{
+ STATISTICS(jniinvokation());
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
+ log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
- return j;
+ return obj;
}
-jlongArray NewLongArray(JNIEnv *env, jsize len)
+void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
{
- java_longarray *j;
-
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
- return NULL;
- }
+ STATISTICS(jniinvokation());
- j = builtin_newarray_long(len);
+ log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
+}
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
- return j;
-}
+/* NewGlobalRef ****************************************************************
+ Creates a new global reference to the object referred to by the obj
+ argument.
-jfloatArray NewFloatArray(JNIEnv *env, jsize len)
+*******************************************************************************/
+
+jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
{
- java_floatarray *j;
+ hashtable_global_ref_entry *gre;
+ u4 key; /* hashkey */
+ u4 slot; /* slot in hashtable */
+ java_handle_t *o;
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
- return NULL;
- }
+ STATISTICS(jniinvokation());
- j = builtin_newarray_float(len);
+ o = (java_handle_t *) obj;
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
+ LOCK_MONITOR_ENTER(hashtable_global_ref->header);
- return j;
-}
+ /* normally addresses are aligned to 4, 8 or 16 bytes */
+ key = ((u4) (ptrint) obj) >> 4; /* align to 16-byte boundaries */
+ slot = key & (hashtable_global_ref->size - 1);
+ gre = hashtable_global_ref->ptr[slot];
+
+ /* search external hash chain for the entry */
-jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
-{
- java_doublearray *j;
+ while (gre) {
+ if (gre->o == o) {
+ /* global object found, increment the reference */
- if (len < 0) {
- *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
- return NULL;
- }
+ gre->refs++;
- j = builtin_newarray_double(len);
+ LOCK_MONITOR_EXIT(hashtable_global_ref->header);
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
+ return obj;
+ }
- return j;
-}
+ gre = gre->hashlink; /* next element in external chain */
+ }
+ /* global ref not found, create a new one */
-jboolean * GetBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *isCopy)
-{
- if (isCopy) *isCopy = JNI_FALSE;
- return array->data;
-}
+ gre = NEW(hashtable_global_ref_entry);
+#if defined(ENABLE_GC_CACAO)
+ /* register global ref with the GC */
-jbyte * GetByteArrayElements (JNIEnv *env, jbyteArray array, jboolean *isCopy)
-{
- if (isCopy) *isCopy = JNI_FALSE;
- return array->data;
-}
+ gc_reference_register(&(gre->o));
+#endif
+ gre->o = o;
+ gre->refs = 1;
-jchar * GetCharArrayElements (JNIEnv *env, jcharArray array, jboolean *isCopy)
-{
- if (isCopy) *isCopy = JNI_FALSE;
- return array->data;
-}
+ /* insert entry into hashtable */
+ gre->hashlink = hashtable_global_ref->ptr[slot];
-jshort * GetShortArrayElements (JNIEnv *env, jshortArray array, jboolean *isCopy)
-{
- if (isCopy) *isCopy = JNI_FALSE;
- return array->data;
-}
+ hashtable_global_ref->ptr[slot] = gre;
+ /* update number of hashtable-entries */
-jint * GetIntArrayElements (JNIEnv *env, jintArray array, jboolean *isCopy)
-{
- if (isCopy) *isCopy = JNI_FALSE;
- return array->data;
-}
+ hashtable_global_ref->entries++;
+ LOCK_MONITOR_EXIT(hashtable_global_ref->header);
-jlong * GetLongArrayElements (JNIEnv *env, jlongArray array, jboolean *isCopy)
-{
- if (isCopy) *isCopy = JNI_FALSE;
- return array->data;
+ return obj;
}
-jfloat * GetFloatArrayElements (JNIEnv *env, jfloatArray array, jboolean *isCopy)
-{
- if (isCopy) *isCopy = JNI_FALSE;
- return array->data;
-}
+/* DeleteGlobalRef *************************************************************
+
+ Deletes the global reference pointed to by globalRef.
+*******************************************************************************/
-jdouble * GetDoubleArrayElements (JNIEnv *env, jdoubleArray array, jboolean *isCopy)
+void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
{
- if (isCopy) *isCopy = JNI_FALSE;
- return array->data;
-}
+ hashtable_global_ref_entry *gre;
+ hashtable_global_ref_entry *prevgre;
+ u4 key; /* hashkey */
+ u4 slot; /* slot in hashtable */
+ java_handle_t *o;
+ STATISTICS(jniinvokation());
+ o = (java_handle_t *) globalRef;
-void ReleaseBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode)
-{
- /* empty */
-}
+ LOCK_MONITOR_ENTER(hashtable_global_ref->header);
+ /* normally addresses are aligned to 4, 8 or 16 bytes */
-void ReleaseByteArrayElements (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode)
-{
- /* empty */
-}
+ key = ((u4) (ptrint) globalRef) >> 4; /* align to 16-byte boundaries */
+ slot = key & (hashtable_global_ref->size - 1);
+ gre = hashtable_global_ref->ptr[slot];
+ /* initialize prevgre */
-void ReleaseCharArrayElements (JNIEnv *env, jcharArray array, jchar *elems, jint mode)
-{
- /* empty */
-}
+ prevgre = NULL;
+ /* search external hash chain for the entry */
-void ReleaseShortArrayElements (JNIEnv *env, jshortArray array, jshort *elems, jint mode)
-{
- /* empty */
-}
+ while (gre) {
+ if (gre->o == o) {
+ /* global object found, decrement the reference count */
+ gre->refs--;
-void ReleaseIntArrayElements (JNIEnv *env, jintArray array, jint *elems, jint mode)
-{
- /* empty */
-}
+ /* if reference count is 0, remove the entry */
+ if (gre->refs == 0) {
+ /* special handling if it's the first in the chain */
-void ReleaseLongArrayElements (JNIEnv *env, jlongArray array, jlong *elems, jint mode)
-{
- /* empty */
-}
+ if (prevgre == NULL)
+ hashtable_global_ref->ptr[slot] = gre->hashlink;
+ else
+ prevgre->hashlink = gre->hashlink;
+#if defined(ENABLE_GC_CACAO)
+ /* unregister global ref with the GC */
-void ReleaseFloatArrayElements (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode)
-{
- /* empty */
-}
+ gc_reference_unregister(&(gre->o));
+#endif
+ FREE(gre, hashtable_global_ref_entry);
+ }
-void ReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode)
-{
- /* empty */
-}
+ LOCK_MONITOR_EXIT(hashtable_global_ref->header);
+ return;
+ }
-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);
+ prevgre = gre; /* save current pointer for removal */
+ gre = gre->hashlink; /* next element in external chain */
+ }
+
+ log_println("JNI-DeleteGlobalRef: global reference not found");
- else
- memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
+ LOCK_MONITOR_EXIT(hashtable_global_ref->header);
}
-void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
-{
- if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+/* ExceptionCheck **************************************************************
- else
- memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
-}
+ Returns JNI_TRUE when there is a pending exception; otherwise,
+ returns JNI_FALSE.
+*******************************************************************************/
-void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
+jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
{
- 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]));
-}
+ java_handle_t *o;
+ STATISTICS(jniinvokation());
-void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
-{
- if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ o = exceptions_get_exception();
- else
- memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
+ return (o != NULL) ? JNI_TRUE : JNI_FALSE;
}
-void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
-{
- if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+/* New JNI 1.4 functions ******************************************************/
- else
- memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
-}
+/* 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.
-void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
+*******************************************************************************/
+
+jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
{
- if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+#if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
+ java_handle_t *nbuf;
- else
- memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
-}
+# if SIZEOF_VOID_P == 8
+ gnu_classpath_Pointer64 *paddress;
+# else
+ gnu_classpath_Pointer32 *paddress;
+# endif
+ STATISTICS(jniinvokation());
-void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
-{
- if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ /* alocate a gnu.classpath.Pointer{32,64} object */
- else
- memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
-}
+# 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 */
-void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
-{
- if (start < 0 || len < 0 || start+len>array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ LLNI_field_set_val(paddress, data, (ptrint) address);
- else
- memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
-}
+ /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
+ nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
+ (jmethodID) dbbirw_init, NULL, paddress,
+ (jint) capacity, (jint) capacity, (jint) 0);
-void SetBooleanArrayRegion(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);
+ /* add local reference and return the value */
+
+ return _Jv_JNI_NewLocalRef(env, nbuf);
+#else
+ vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
+
+ /* keep compiler happy */
- else
- memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
+ return NULL;
+#endif
}
-void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
-{
- if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+/* GetDirectBufferAddress ******************************************************
- else
- memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
-}
+ Fetches and returns the starting address of the memory region
+ referenced by the given direct java.nio.Buffer.
+*******************************************************************************/
-void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
+void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
{
- if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+#if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
+ java_nio_DirectByteBufferImpl *nbuf;
+# if SIZEOF_VOID_P == 8
+ gnu_classpath_Pointer64 *paddress;
+# else
+ gnu_classpath_Pointer32 *paddress;
+# endif
+ void *address;
- else
- memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
+ STATISTICS(jniinvokation());
-}
+ if (!builtin_instanceof(buf, class_java_nio_Buffer))
+ return NULL;
+ nbuf = (java_nio_DirectByteBufferImpl *) buf;
-void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
-{
- if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+# if SIZEOF_VOID_P == 8
+ LLNI_field_get_ref(nbuf, address, paddress);
+ /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
+# else
+ LLNI_field_get_ref(nbuf, address, paddress);
+ /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
+# endif
- else
- memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
-}
+ if (paddress == NULL)
+ return NULL;
+ LLNI_field_get_val(paddress, data, address);
+ /* this was the cast to avaoid warning: (void *) paddress->data */
-void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
-{
- if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ return address;
+#else
+ vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
- else
- memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
+ /* keep compiler happy */
+ return NULL;
+#endif
}
-void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
-{
- 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]));
+/* GetDirectBufferCapacity *****************************************************
-}
+ Fetches and returns the capacity in bytes of the memory region
+ referenced by the given direct java.nio.Buffer.
+*******************************************************************************/
-void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
+jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
{
- if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+#if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
+ java_handle_t *o;
+ java_nio_Buffer *nbuf;
+ jlong capacity;
- else
- memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
+ STATISTICS(jniinvokation());
-}
+ o = (java_handle_t *) buf;
+ if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
+ return -1;
-void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
-{
- if (start < 0 || len < 0 || start + len > array->header.size)
- *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+ nbuf = (java_nio_Buffer *) o;
- else
- memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
-}
+ LLNI_field_get_val(nbuf, cap, capacity);
+ return capacity;
+#else
+ vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
-jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
-{
- log_text("JNI-Call: RegisterNatives");
- return 0;
+ /* keep compiler happy */
+
+ return 0;
+#endif
}
-jint UnregisterNatives (JNIEnv* env, jclass clazz)
-{
- log_text("JNI-Call: UnregisterNatives");
- return 0;
-}
+/* DestroyJavaVM ***************************************************************
-/******************************* monitor operations ********************************/
+ Unloads a Java VM and reclaims its resources. Only the main thread
+ can unload the VM. The system waits until the main thread is only
+ remaining user thread before it destroys the VM.
+
+*******************************************************************************/
-jint MonitorEnter (JNIEnv* env, jobject obj)
+jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
{
- builtin_monitorenter(obj);
- return 0;
-}
+ s4 status;
+ STATISTICS(jniinvokation());
-jint MonitorExit (JNIEnv* env, jobject obj)
-{
- builtin_monitorexit(obj);
- return 0;
+ status = vm_destroy(vm);
+
+ return status;
}
-/************************************* JavaVM interface ****************************/
-#ifdef __cplusplus
-#error CPP mode not supported yet
-#else
-jint GetJavaVM (JNIEnv* env, JavaVM **vm)
-{
- log_text("JNI-Call: GetJavaVM");
- *vm=&javaVM;
- return 0;
-}
-#endif /*__cplusplus*/
+/* AttachCurrentThread *********************************************************
-void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
-{
- log_text("JNI-Call: GetStringRegion");
+ 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.
-void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
-{
- log_text("JNI-Call: GetStringUTFRegion");
+ 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.
-/************** obtain direct pointer to array elements ***********************/
+*******************************************************************************/
-void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
+static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
{
- java_objectheader *s = (java_objectheader*) array;
- arraydescriptor *desc = s->vftbl->arraydesc;
+ JavaVMAttachArgs *vm_aargs;
- if (!desc) return NULL;
+#if defined(ENABLE_THREADS)
+ if (threads_get_current_threadobject() == NULL) {
+ vm_aargs = (JavaVMAttachArgs *) thr_args;
- return ((u1*)s) + desc->dataoffset;
-}
+ if (vm_aargs != NULL) {
+ if ((vm_aargs->version != JNI_VERSION_1_2) &&
+ (vm_aargs->version != JNI_VERSION_1_4))
+ return JNI_EVERSION;
+ }
+ if (!threads_attach_current_thread(vm_aargs, false))
+ return JNI_ERR;
-void ReleasePrimitiveArrayCritical (JNIEnv* env, jarray array, void *carray, jint mode)
-{
- log_text("JNI-Call: ReleasePrimitiveArrayCritical");
+ if (!localref_table_init())
+ return JNI_ERR;
+ }
+#endif
+
+ *p_env = _Jv_env;
- /* empty */
+ return JNI_OK;
}
-/**** returns a pointer to an array of Unicode characters of the string *******/
-const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
+jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
{
- log_text("JNI-Call: GetStringCritical");
+ STATISTICS(jniinvokation());
- return GetStringChars(env,string,isCopy);
+ return jni_attach_current_thread(p_env, thr_args, false);
}
-/*********** native code no longer needs access to chars **********************/
-void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
-{
- log_text("JNI-Call: ReleaseStringCritical");
+/* DetachCurrentThread *********************************************************
- ReleaseStringChars(env,string,cstring);
-}
+ Detaches the current thread from a Java VM. All Java monitors held
+ by this thread are released. All Java threads waiting for this
+ thread to die are notified.
+ In JDK 1.1, the main thread cannot be detached from the VM. It must
+ call DestroyJavaVM to unload the entire VM.
-jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
-{
- log_text("JNI-Call: NewWeakGlobalRef");
+ In the JDK, the main thread can be detached from the VM.
- return obj;
-}
+ The main thread, which is the thread that created the Java VM,
+ cannot be detached from the VM. Instead, the main thread must call
+ JNI_DestroyJavaVM() to unload the entire VM.
+*******************************************************************************/
-void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
+jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
{
- log_text("JNI-Call: DeleteWeakGlobalRef");
+#if defined(ENABLE_THREADS)
+ threadobject *thread;
- /* empty */
-}
+ STATISTICS(jniinvokation());
+ thread = threads_get_current_threadobject();
-/******************************* check for pending exception ***********************/
+ if (thread == NULL)
+ return JNI_ERR;
+ if (!jni_free_localref_table())
+ return JNI_ERR;
-jboolean ExceptionCheck(JNIEnv* env)
-{
- log_text("JNI-Call: ExceptionCheck");
+ if (!threads_detach_thread(thread))
+ return JNI_ERR;
+#endif
- return *exceptionptr ? JNI_TRUE : JNI_FALSE;
+ return JNI_OK;
}
+/* 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 DestroyJavaVM(JavaVM *vm)
+jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
{
- log_text("DestroyJavaVM called");
+ STATISTICS(jniinvokation());
- return 0;
-}
+#if defined(ENABLE_THREADS)
+ if (threads_get_current_threadobject() == NULL) {
+ *env = NULL;
+ return JNI_EDETACHED;
+ }
+#endif
-jint AttachCurrentThread(JavaVM *vm, void **par1, void *par2)
-{
- log_text("AttachCurrentThread called");
+ /* check the JNI version */
- return 0;
-}
+ switch (version) {
+ case JNI_VERSION_1_1:
+ case JNI_VERSION_1_2:
+ case JNI_VERSION_1_4:
+ *env = _Jv_env;
+ return JNI_OK;
+
+ default:
+ ;
+ }
+#if defined(ENABLE_JVMTI)
+ if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
+ == JVMTI_VERSION_INTERFACE_JVMTI) {
-jint DetachCurrentThread(JavaVM *vm)
-{
- log_text("DetachCurrentThread called");
+ *env = (void *) jvmti_new_environment();
- return 0;
+ if (env != NULL)
+ return JNI_OK;
+ }
+#endif
+
+ *env = NULL;
+
+ return JNI_EVERSION;
}
-jint GetEnv(JavaVM *vm, void **environment, jint jniversion)
-{
- *environment = &env;
+/* AttachCurrentThreadAsDaemon *************************************************
- return 0;
-}
+ Same semantics as AttachCurrentThread, but the newly-created
+ java.lang.Thread instance is a daemon.
+ If the thread has already been attached via either
+ AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
+ simply sets the value pointed to by penv to the JNIEnv of the
+ current thread. In this case neither AttachCurrentThread nor this
+ routine have any effect on the daemon status of the thread.
+
+*******************************************************************************/
-jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
+jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
{
- log_text("AttachCurrentThreadAsDaemon called");
+ STATISTICS(jniinvokation());
- return 0;
+ return jni_attach_current_thread(penv, args, true);
}
-/********************************* JNI invocation table ******************************/
+/* JNI invocation table *******************************************************/
+
+const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
+ NULL,
+ NULL,
+ NULL,
-struct _JavaVM javaVMTable={
- NULL,
- NULL,
- NULL,
- &DestroyJavaVM,
- &AttachCurrentThread,
- &DetachCurrentThread,
- &GetEnv,
- &AttachCurrentThreadAsDaemon
+ _Jv_JNI_DestroyJavaVM,
+ _Jv_JNI_AttachCurrentThread,
+ _Jv_JNI_DetachCurrentThread,
+ _Jv_JNI_GetEnv,
+ _Jv_JNI_AttachCurrentThreadAsDaemon
};
-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,
- &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,
- &GetStringRegion,
- &GetStringUTFRegion,
- &GetPrimitiveArrayCritical,
- &ReleasePrimitiveArrayCritical,
- &GetStringCritical,
- &ReleaseStringCritical,
- &NewWeakGlobalRef,
- &DeleteWeakGlobalRef,
- &ExceptionCheck
+
+/* JNI function table *********************************************************/
+
+struct JNINativeInterface_ _Jv_JNINativeInterface = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _Jv_JNI_GetVersion,
+
+ _Jv_JNI_DefineClass,
+ _Jv_JNI_FindClass,
+ _Jv_JNI_FromReflectedMethod,
+ _Jv_JNI_FromReflectedField,
+ _Jv_JNI_ToReflectedMethod,
+ _Jv_JNI_GetSuperclass,
+ _Jv_JNI_IsAssignableFrom,
+ _Jv_JNI_ToReflectedField,
+
+ _Jv_JNI_Throw,
+ _Jv_JNI_ThrowNew,
+ _Jv_JNI_ExceptionOccurred,
+ _Jv_JNI_ExceptionDescribe,
+ _Jv_JNI_ExceptionClear,
+ _Jv_JNI_FatalError,
+ _Jv_JNI_PushLocalFrame,
+ _Jv_JNI_PopLocalFrame,
+
+ _Jv_JNI_NewGlobalRef,
+ _Jv_JNI_DeleteGlobalRef,
+ _Jv_JNI_DeleteLocalRef,
+ _Jv_JNI_IsSameObject,
+ _Jv_JNI_NewLocalRef,
+ _Jv_JNI_EnsureLocalCapacity,
+
+ _Jv_JNI_AllocObject,
+ _Jv_JNI_NewObject,
+ _Jv_JNI_NewObjectV,
+ _Jv_JNI_NewObjectA,
+
+ _Jv_JNI_GetObjectClass,
+ _Jv_JNI_IsInstanceOf,
+
+ _Jv_JNI_GetMethodID,
+
+ _Jv_JNI_CallObjectMethod,
+ _Jv_JNI_CallObjectMethodV,
+ _Jv_JNI_CallObjectMethodA,
+ _Jv_JNI_CallBooleanMethod,
+ _Jv_JNI_CallBooleanMethodV,
+ _Jv_JNI_CallBooleanMethodA,
+ _Jv_JNI_CallByteMethod,
+ _Jv_JNI_CallByteMethodV,
+ _Jv_JNI_CallByteMethodA,
+ _Jv_JNI_CallCharMethod,
+ _Jv_JNI_CallCharMethodV,
+ _Jv_JNI_CallCharMethodA,
+ _Jv_JNI_CallShortMethod,
+ _Jv_JNI_CallShortMethodV,
+ _Jv_JNI_CallShortMethodA,
+ _Jv_JNI_CallIntMethod,
+ _Jv_JNI_CallIntMethodV,
+ _Jv_JNI_CallIntMethodA,
+ _Jv_JNI_CallLongMethod,
+ _Jv_JNI_CallLongMethodV,
+ _Jv_JNI_CallLongMethodA,
+ _Jv_JNI_CallFloatMethod,
+ _Jv_JNI_CallFloatMethodV,
+ _Jv_JNI_CallFloatMethodA,
+ _Jv_JNI_CallDoubleMethod,
+ _Jv_JNI_CallDoubleMethodV,
+ _Jv_JNI_CallDoubleMethodA,
+ _Jv_JNI_CallVoidMethod,
+ _Jv_JNI_CallVoidMethodV,
+ _Jv_JNI_CallVoidMethodA,
+
+ _Jv_JNI_CallNonvirtualObjectMethod,
+ _Jv_JNI_CallNonvirtualObjectMethodV,
+ _Jv_JNI_CallNonvirtualObjectMethodA,
+ _Jv_JNI_CallNonvirtualBooleanMethod,
+ _Jv_JNI_CallNonvirtualBooleanMethodV,
+ _Jv_JNI_CallNonvirtualBooleanMethodA,
+ _Jv_JNI_CallNonvirtualByteMethod,
+ _Jv_JNI_CallNonvirtualByteMethodV,
+ _Jv_JNI_CallNonvirtualByteMethodA,
+ _Jv_JNI_CallNonvirtualCharMethod,
+ _Jv_JNI_CallNonvirtualCharMethodV,
+ _Jv_JNI_CallNonvirtualCharMethodA,
+ _Jv_JNI_CallNonvirtualShortMethod,
+ _Jv_JNI_CallNonvirtualShortMethodV,
+ _Jv_JNI_CallNonvirtualShortMethodA,
+ _Jv_JNI_CallNonvirtualIntMethod,
+ _Jv_JNI_CallNonvirtualIntMethodV,
+ _Jv_JNI_CallNonvirtualIntMethodA,
+ _Jv_JNI_CallNonvirtualLongMethod,
+ _Jv_JNI_CallNonvirtualLongMethodV,
+ _Jv_JNI_CallNonvirtualLongMethodA,
+ _Jv_JNI_CallNonvirtualFloatMethod,
+ _Jv_JNI_CallNonvirtualFloatMethodV,
+ _Jv_JNI_CallNonvirtualFloatMethodA,
+ _Jv_JNI_CallNonvirtualDoubleMethod,
+ _Jv_JNI_CallNonvirtualDoubleMethodV,
+ _Jv_JNI_CallNonvirtualDoubleMethodA,
+ _Jv_JNI_CallNonvirtualVoidMethod,
+ _Jv_JNI_CallNonvirtualVoidMethodV,
+ _Jv_JNI_CallNonvirtualVoidMethodA,
+
+ _Jv_JNI_GetFieldID,
+
+ _Jv_JNI_GetObjectField,
+ _Jv_JNI_GetBooleanField,
+ _Jv_JNI_GetByteField,
+ _Jv_JNI_GetCharField,
+ _Jv_JNI_GetShortField,
+ _Jv_JNI_GetIntField,
+ _Jv_JNI_GetLongField,
+ _Jv_JNI_GetFloatField,
+ _Jv_JNI_GetDoubleField,
+ _Jv_JNI_SetObjectField,
+ _Jv_JNI_SetBooleanField,
+ _Jv_JNI_SetByteField,
+ _Jv_JNI_SetCharField,
+ _Jv_JNI_SetShortField,
+ _Jv_JNI_SetIntField,
+ _Jv_JNI_SetLongField,
+ _Jv_JNI_SetFloatField,
+ _Jv_JNI_SetDoubleField,
+
+ _Jv_JNI_GetStaticMethodID,
+
+ _Jv_JNI_CallStaticObjectMethod,
+ _Jv_JNI_CallStaticObjectMethodV,
+ _Jv_JNI_CallStaticObjectMethodA,
+ _Jv_JNI_CallStaticBooleanMethod,
+ _Jv_JNI_CallStaticBooleanMethodV,
+ _Jv_JNI_CallStaticBooleanMethodA,
+ _Jv_JNI_CallStaticByteMethod,
+ _Jv_JNI_CallStaticByteMethodV,
+ _Jv_JNI_CallStaticByteMethodA,
+ _Jv_JNI_CallStaticCharMethod,
+ _Jv_JNI_CallStaticCharMethodV,
+ _Jv_JNI_CallStaticCharMethodA,
+ _Jv_JNI_CallStaticShortMethod,
+ _Jv_JNI_CallStaticShortMethodV,
+ _Jv_JNI_CallStaticShortMethodA,
+ _Jv_JNI_CallStaticIntMethod,
+ _Jv_JNI_CallStaticIntMethodV,
+ _Jv_JNI_CallStaticIntMethodA,
+ _Jv_JNI_CallStaticLongMethod,
+ _Jv_JNI_CallStaticLongMethodV,
+ _Jv_JNI_CallStaticLongMethodA,
+ _Jv_JNI_CallStaticFloatMethod,
+ _Jv_JNI_CallStaticFloatMethodV,
+ _Jv_JNI_CallStaticFloatMethodA,
+ _Jv_JNI_CallStaticDoubleMethod,
+ _Jv_JNI_CallStaticDoubleMethodV,
+ _Jv_JNI_CallStaticDoubleMethodA,
+ _Jv_JNI_CallStaticVoidMethod,
+ _Jv_JNI_CallStaticVoidMethodV,
+ _Jv_JNI_CallStaticVoidMethodA,
+
+ _Jv_JNI_GetStaticFieldID,
+
+ _Jv_JNI_GetStaticObjectField,
+ _Jv_JNI_GetStaticBooleanField,
+ _Jv_JNI_GetStaticByteField,
+ _Jv_JNI_GetStaticCharField,
+ _Jv_JNI_GetStaticShortField,
+ _Jv_JNI_GetStaticIntField,
+ _Jv_JNI_GetStaticLongField,
+ _Jv_JNI_GetStaticFloatField,
+ _Jv_JNI_GetStaticDoubleField,
+ _Jv_JNI_SetStaticObjectField,
+ _Jv_JNI_SetStaticBooleanField,
+ _Jv_JNI_SetStaticByteField,
+ _Jv_JNI_SetStaticCharField,
+ _Jv_JNI_SetStaticShortField,
+ _Jv_JNI_SetStaticIntField,
+ _Jv_JNI_SetStaticLongField,
+ _Jv_JNI_SetStaticFloatField,
+ _Jv_JNI_SetStaticDoubleField,
+
+ _Jv_JNI_NewString,
+ _Jv_JNI_GetStringLength,
+ _Jv_JNI_GetStringChars,
+ _Jv_JNI_ReleaseStringChars,
+
+ _Jv_JNI_NewStringUTF,
+ _Jv_JNI_GetStringUTFLength,
+ _Jv_JNI_GetStringUTFChars,
+ _Jv_JNI_ReleaseStringUTFChars,
+
+ _Jv_JNI_GetArrayLength,
+
+ _Jv_JNI_NewObjectArray,
+ _Jv_JNI_GetObjectArrayElement,
+ _Jv_JNI_SetObjectArrayElement,
+
+ _Jv_JNI_NewBooleanArray,
+ _Jv_JNI_NewByteArray,
+ _Jv_JNI_NewCharArray,
+ _Jv_JNI_NewShortArray,
+ _Jv_JNI_NewIntArray,
+ _Jv_JNI_NewLongArray,
+ _Jv_JNI_NewFloatArray,
+ _Jv_JNI_NewDoubleArray,
+
+ _Jv_JNI_GetBooleanArrayElements,
+ _Jv_JNI_GetByteArrayElements,
+ _Jv_JNI_GetCharArrayElements,
+ _Jv_JNI_GetShortArrayElements,
+ _Jv_JNI_GetIntArrayElements,
+ _Jv_JNI_GetLongArrayElements,
+ _Jv_JNI_GetFloatArrayElements,
+ _Jv_JNI_GetDoubleArrayElements,
+
+ _Jv_JNI_ReleaseBooleanArrayElements,
+ _Jv_JNI_ReleaseByteArrayElements,
+ _Jv_JNI_ReleaseCharArrayElements,
+ _Jv_JNI_ReleaseShortArrayElements,
+ _Jv_JNI_ReleaseIntArrayElements,
+ _Jv_JNI_ReleaseLongArrayElements,
+ _Jv_JNI_ReleaseFloatArrayElements,
+ _Jv_JNI_ReleaseDoubleArrayElements,
+
+ _Jv_JNI_GetBooleanArrayRegion,
+ _Jv_JNI_GetByteArrayRegion,
+ _Jv_JNI_GetCharArrayRegion,
+ _Jv_JNI_GetShortArrayRegion,
+ _Jv_JNI_GetIntArrayRegion,
+ _Jv_JNI_GetLongArrayRegion,
+ _Jv_JNI_GetFloatArrayRegion,
+ _Jv_JNI_GetDoubleArrayRegion,
+ _Jv_JNI_SetBooleanArrayRegion,
+ _Jv_JNI_SetByteArrayRegion,
+ _Jv_JNI_SetCharArrayRegion,
+ _Jv_JNI_SetShortArrayRegion,
+ _Jv_JNI_SetIntArrayRegion,
+ _Jv_JNI_SetLongArrayRegion,
+ _Jv_JNI_SetFloatArrayRegion,
+ _Jv_JNI_SetDoubleArrayRegion,
+
+ _Jv_JNI_RegisterNatives,
+ _Jv_JNI_UnregisterNatives,
+
+ _Jv_JNI_MonitorEnter,
+ _Jv_JNI_MonitorExit,
+
+ _Jv_JNI_GetJavaVM,
+
+ /* new JNI 1.2 functions */
+
+ _Jv_JNI_GetStringRegion,
+ _Jv_JNI_GetStringUTFRegion,
+
+ _Jv_JNI_GetPrimitiveArrayCritical,
+ _Jv_JNI_ReleasePrimitiveArrayCritical,
+
+ _Jv_JNI_GetStringCritical,
+ _Jv_JNI_ReleaseStringCritical,
+
+ _Jv_JNI_NewWeakGlobalRef,
+ _Jv_JNI_DeleteWeakGlobalRef,
+
+ _Jv_JNI_ExceptionCheck,
+
+ /* new JNI 1.4 functions */
+
+ _Jv_JNI_NewDirectByteBuffer,
+ _Jv_JNI_GetDirectBufferAddress,
+ _Jv_JNI_GetDirectBufferCapacity
};
-JNIEnv env = &envTable;
+/* Invocation API Functions ***************************************************/
+
+/* JNI_GetDefaultJavaVMInitArgs ************************************************
-jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID, jobject obj, java_objectarray *params)
+ Returns a default configuration for the Java VM.
+
+*******************************************************************************/
+
+jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
{
- int argcount;
- jni_callblock *blk;
- char retT;
- jobject retVal;
+ JavaVMInitArgs *_vm_args;
- if (methodID == 0) {
- *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
- return NULL;
- }
+ _vm_args = (JavaVMInitArgs *) vm_args;
- argcount = get_parametercount(methodID);
+ /* GNU classpath currently supports JNI 1.2 */
- 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;
+ switch (_vm_args->version) {
+ case JNI_VERSION_1_1:
+ _vm_args->version = JNI_VERSION_1_1;
+ break;
+
+ case JNI_VERSION_1_2:
+ case JNI_VERSION_1_4:
+ _vm_args->ignoreUnrecognized = JNI_FALSE;
+ _vm_args->options = NULL;
+ _vm_args->nOptions = 0;
+ break;
+
+ default:
+ return -1;
}
+
+ return 0;
+}
+/* JNI_GetCreatedJavaVMs *******************************************************
- if (argcount > 3) {
- *exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- log_text("Too many arguments. invokeNativeHelper does not support that");
- return 0;
- }
+ 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.
- if (((!params) && (argcount != 0)) || (params && (params->header.size != argcount))) {
- *exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
- return 0;
- }
+*******************************************************************************/
+jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
+{
+ TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
- 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 (bufLen <= 0)
+ return JNI_ERR;
- if ((methodID->flags & ACC_STATIC) && (obj)) obj = 0;
+ /* We currently only support 1 VM running. */
- blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+ vmBuf[0] = (JavaVM *) _Jv_jvm;
+ *nVMs = 1;
- retT = fill_callblock_objA(obj, methodID->descriptor, blk, params);
+ return JNI_OK;
+}
- 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);
- }
- 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;
+/* JNI_CreateJavaVM ************************************************************
- default:
- /* if this happens the acception has already been set by fill_callblock_objA*/
- MFREE(blk, jni_callblock, 4 /*argcount+2*/);
- return (jobject *) 0;
- }
+ 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.
- MFREE(blk, jni_callblock, 4 /*argcount+2*/);
-
- if (*exceptionptr) {
- java_objectheader *exceptionToWrap=*exceptionptr;
- classinfo *ivtec;
- java_objectheader *ivte;
-
- *exceptionptr=0;
- ivtec = loader_load_sysclass(NULL,
- 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;
- }
+*******************************************************************************/
+
+jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
+{
+ TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
+
+ /* actually create the JVM */
+
+ if (!vm_createjvm(p_vm, p_env, vm_args))
+ return JNI_ERR;
- return (jobject *) retVal;
+ return JNI_OK;
}
* c-basic-offset: 4
* tab-width: 4
* End:
+ * vim:noexpandtab:sw=4:ts=4:
*/