/* src/native/jni.cpp - implementation of the Java Native Interface functions
- Copyright (C) 1996-2005, 2006, 2007, 2008
+ Copyright (C) 1996-2005, 2006, 2007, 2008, 2009
CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
#include "vm/types.h"
#include "mm/gc.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
-#include "native/jni.h"
+#include "native/jni.hpp"
#include "native/llni.h"
-#include "native/localref.h"
-#include "native/native.h"
-
-#if defined(ENABLE_JAVASE)
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-# 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_String.h"
-#include "native/include/java_lang_Throwable.h"
-
-#if defined(ENABLE_JAVASE)
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-# include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
-# endif
-
-/* java_lang_ClassLoader is used in java_lang_Class and vice versa, so
- we pre-define it here to prevent a compiler warning for Sun
- configurations. */
-
-struct java_lang_ClassLoader;
-
-# include "native/include/java_lang_Class.h"
-# 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_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-# include "native/include/java_lang_reflect_VMConstructor.h"
-# include "native/include/java_lang_reflect_VMField.h"
-# include "native/include/java_lang_reflect_VMMethod.h"
-
-# include "native/include/java_nio_DirectByteBufferImpl.h"
-# endif
-#elif defined(ENABLE_JAVAME_CLDC1_1)
-# include "native/include/java_lang_Class.h"
-#endif
+#include "native/localref.hpp"
+#include "native/native.hpp"
#if defined(ENABLE_JVMTI)
# include "native/jvmti/cacaodbg.h"
#endif
-#if defined(ENABLE_JAVASE)
-# include "native/vm/reflect.h"
-#endif
-
-#include "threads/lock-common.h"
+#include "threads/lock.hpp"
+#include "threads/mutex.hpp"
#include "threads/thread.hpp"
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
-#include "vm/array.h"
-#include "vm/builtin.h"
+#include "vm/array.hpp"
+#include "vm/jit/builtin.hpp"
#include "vm/exceptions.hpp"
#include "vm/global.h"
-#include "vm/initialize.h"
+#include "vm/globals.hpp"
+#include "vm/initialize.hpp"
+#include "vm/javaobjects.hpp"
+#include "vm/loader.hpp"
+#include "vm/options.h"
#include "vm/primitive.hpp"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
+#include "vm/statistics.h"
#include "vm/string.hpp"
#include "vm/vm.hpp"
-#include "vm/jit/argument.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/stacktrace.hpp"
-#include "vmcore/globals.hpp"
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-#include "vmcore/statistics.h"
-
/* debug **********************************************************************/
{
TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
- /* We support JNI 1.6. */
-
- return JNI_VERSION_1_6;
+ return JNI_VERSION_SUPPORTED;
}
*******************************************************************************/
-jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
- const jbyte *buf, jsize bufLen)
+jclass jni_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize bufLen)
{
#if defined(ENABLE_JAVASE)
- utf *u;
- classloader_t *cl;
- classinfo *c;
- java_lang_Class *co;
+ utf *u;
+ classloader_t *cl;
+ classinfo *c;
+ java_handle_t* h;
- TRACEJNICALLS(("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
+ TRACEJNICALLS(("jni_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
u = utf_new_char(name);
cl = loader_hashtable_classloader_add((java_handle_t *) loader);
c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
- co = LLNI_classinfo_wrap(c);
+ h = LLNI_classinfo_wrap(c);
- return (jclass) jni_NewLocalRef(env, (jobject) co);
+ return (jclass) jni_NewLocalRef(env, (jobject) h);
#else
- vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
+ vm_abort("jni_DefineClass: Not implemented in this configuration");
- /* keep compiler happy */
+ // Keep compiler happy.
return 0;
#endif
{
#if defined(ENABLE_JAVASE)
- utf *u;
- classinfo *cc;
- classinfo *c;
- java_lang_Class *co;
+ utf* u;
+ classinfo* cc;
+ classinfo* c;
+ java_handle_t* h;
TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
if (!link_class(c))
return NULL;
- co = LLNI_classinfo_wrap(c);
+ h = LLNI_classinfo_wrap(c);
- return (jclass) jni_NewLocalRef(env, (jobject) co);
+ return (jclass) jni_NewLocalRef(env, (jobject) h);
#elif defined(ENABLE_JAVAME_CLDC1_1)
*******************************************************************************/
-jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
+jclass jni_GetSuperclass(JNIEnv *env, jclass sub)
{
- classinfo *c;
- classinfo *super;
- java_lang_Class *co;
+ classinfo* c;
+ classinfo* super;
- TRACEJNICALLS(("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub));
+ TRACEJNICALLS(("jni_GetSuperclass(env=%p, sub=%p)", env, sub));
c = LLNI_classinfo_unwrap(sub);
super = class_get_superclass(c);
- co = LLNI_classinfo_wrap(super);
+ java_handle_t* h = LLNI_classinfo_wrap(super);
- return (jclass) jni_NewLocalRef(env, (jobject) co);
+ return (jclass) jni_NewLocalRef(env, (jobject) h);
}
*******************************************************************************/
-jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
+jclass jni_GetObjectClass(JNIEnv *env, jobject obj)
{
- java_handle_t *o;
- classinfo *c;
- java_lang_Class *co;
+ java_handle_t* o;
+ classinfo* c;
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("jni_GetObjectClass(env=%p, obj=%p)", env, obj));
o = (java_handle_t *) obj;
LLNI_class_get(o, c);
- co = LLNI_classinfo_wrap(c);
+ java_handle_t* h = LLNI_classinfo_wrap(c);
- return (jclass) jni_NewLocalRef(env, (jobject) co);
+ return (jclass) jni_NewLocalRef(env, (jobject) h);
}
jmethodID jni_FromReflectedMethod(JNIEnv *env, jobject method)
{
#if defined(ENABLE_JAVASE)
- java_handle_t *o;
- java_lang_reflect_Method *rm;
- java_lang_reflect_Constructor *rc;
- classinfo *c;
- methodinfo *m;
- int32_t slot;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
- java_lang_reflect_VMMethod *rvmm;
- java_lang_reflect_VMConstructor *rvmc;
-#endif
+ methodinfo* m;
TRACEJNICALLS(("jni_FromReflectedMethod(env=%p, method=%p)", env, method));
- o = (java_handle_t *) method;
+ java_lang_Object o(method);
- if (o == NULL)
+ if (o.is_null())
return NULL;
- if (o->vftbl->clazz == class_java_lang_reflect_Constructor) {
- rc = (java_lang_reflect_Constructor *) method;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
- LLNI_field_get_ref(rc, cons , rvmc);
- LLNI_field_get_cls(rvmc, clazz, c);
- LLNI_field_get_val(rvmc, slot , slot);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
- LLNI_field_get_cls(rc, clazz, c);
- LLNI_field_get_val(rc, slot , slot);
-
-#else
-# error unknown configuration
-#endif
+ if (o.get_Class() == class_java_lang_reflect_Constructor) {
+ java_lang_reflect_Constructor rc(method);
+ m = rc.get_method();
}
else {
- assert(o->vftbl->clazz == class_java_lang_reflect_Method);
-
- rm = (java_lang_reflect_Method *) method;
+ assert(o.get_Class() == class_java_lang_reflect_Method);
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
- LLNI_field_get_ref(rm, m , rvmm);
- LLNI_field_get_cls(rvmm, clazz, c);
- LLNI_field_get_val(rvmm, slot , slot);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
- LLNI_field_get_cls(rm, clazz, c);
- LLNI_field_get_val(rm, slot , slot);
-
-#else
-# error unknown configuration
-#endif
+ java_lang_reflect_Method rm(method);
+ m = rm.get_method();
}
- m = &(c->methods[slot]);
-
return (jmethodID) m;
#else
vm_abort("jni_FromReflectedMethod: Not implemented in this configuration.");
- /* Keep compiler happy. */
-
+ // Keep compiler happy.
return NULL;
#endif
}
jfieldID jni_FromReflectedField(JNIEnv* env, jobject field)
{
#if defined(ENABLE_JAVASE)
- java_lang_reflect_Field *rf;
- classinfo *c;
- fieldinfo *f;
- int32_t slot;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
- java_lang_reflect_VMField *rvmf;
-#endif
TRACEJNICALLS(("jni_FromReflectedField(env=%p, field=%p)", env, field));
- rf = (java_lang_reflect_Field *) field;
+ java_lang_reflect_Field rf(field);
- if (rf == NULL)
+ if (rf.is_null())
return NULL;
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
- LLNI_field_get_ref(rf, f, rvmf);
- LLNI_field_get_cls(rvmf, clazz, c);
- LLNI_field_get_val(rvmf, slot , slot);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
- LLNI_field_get_cls(rf, clazz, c);
- LLNI_field_get_val(rf, slot , slot);
-
-#else
-# error unknown configuration
-#endif
-
- f = &(c->fields[slot]);
+ fieldinfo* f = rf.get_field();
return (jfieldID) f;
#else
vm_abort("jni_FromReflectedField: Not implemented in this configuration.");
- /* Keep compiler happy. */
-
+ // Keep compiler happy.
return NULL;
#endif
}
*******************************************************************************/
-jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
- jboolean isStatic)
+jobject jni_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
{
#if defined(ENABLE_JAVASE)
- methodinfo *m;
- java_lang_reflect_Constructor *rc;
- java_lang_reflect_Method *rm;
-
- TRACEJNICALLS(("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
+ TRACEJNICALLS(("jni_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
- m = (methodinfo *) methodID;
+ methodinfo* m = (methodinfo *) methodID;
/* HotSpot does the same assert. */
assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
- if (m->name == utf_init) {
- rc = reflect_constructor_new(m);
+ java_handle_t* h;
- return (jobject) rc;
+ if (m->name == utf_init) {
+ h = java_lang_reflect_Constructor(m).get_handle();
}
else {
- rm = reflect_method_new(m);
-
- return (jobject) rm;
+ h = java_lang_reflect_Method(m).get_handle();
}
+
+ return (jobject) h;
#else
- vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
+ vm_abort("jni_ToReflectedMethod: Not implemented in this configuration.");
/* keep compiler happy */
#define SET_FIELD(o,type,f,value) \
*((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
+#define GET_FIELDINFO(f) ((fieldinfo*) (f))
+
#define JNI_SET_FIELD(name, type, intern) \
void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
type value) \
\
SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
\
- LLNI_CRITICAL_START; \
+ LLNI_CRITICAL_END; \
+ \
+ if (GET_FIELDINFO(fieldID)->flags & ACC_VOLATILE) \
+ Atomic::memory_barrier(); \
}
JNI_SET_FIELD(Boolean, jboolean, s4)
SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
LLNI_CRITICAL_END;
+
+ if (GET_FIELDINFO(fieldID)->flags & ACC_VOLATILE)
+ Atomic::memory_barrier();
}
methodinfo *m;
java_handle_t *o;
- TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
+ TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p)", env, clazz, methodID));
m = (methodinfo *) methodID;
{
methodinfo *m;
- TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
+ TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p)", env, clazz, methodID));
m = (methodinfo *) methodID;
return; \
\
f->value->field = value; \
+ \
+ if (f->flags & ACC_VOLATILE) \
+ Atomic::memory_barrier(); \
}
JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
return;
f->value->a = LLNI_UNWRAP((java_handle_t *) value);
+
+ if (f->flags & ACC_VOLATILE)
+ Atomic::memory_barrier();
}
*******************************************************************************/
-jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
+jstring jni_NewString(JNIEnv *env, const jchar *buf, jsize len)
{
- java_lang_String *s;
- java_handle_chararray_t *a;
- int32_t i;
+ TRACEJNICALLS(("jni_NewString(env=%p, buf=%p, len=%d)", env, buf, len));
- STATISTICS(jniinvokation());
-
- s = (java_lang_String *) builtin_new(class_java_lang_String);
- a = builtin_newarray_char(len);
+ CharArray ca(len);
- /* javastring or characterarray could not be created */
- if ((a == NULL) || (s == NULL))
+ if (ca.is_null())
return NULL;
/* 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);
+ // XXX: Fix me!
+ uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
+ for (jsize i = 0; i < len; i++)
+ ptr[i] = buf[i];
- return (jstring) jni_NewLocalRef(env, (jobject) s);
+ java_handle_t* h = builtin_new(class_java_lang_String);
+
+ if (h == NULL)
+ return NULL;
+
+ java_lang_String s(h, ca.get_handle(), len, 0);
+
+ return (jstring) jni_NewLocalRef(env, (jobject) s.get_handle());
}
*******************************************************************************/
-jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
+jsize jni_GetStringLength(JNIEnv *env, jstring str)
{
- java_lang_String *s;
- jsize len;
-
- TRACEJNICALLS(("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str));
+ TRACEJNICALLSENTER(("jni_GetStringLength(env=%p, str=%p)", env, str));
- s = (java_lang_String *) str;
+ java_lang_String s(str);
+ jsize count = s.get_count();
- LLNI_field_get_val(s, count, len);
+ TRACEJNICALLSEXIT(("->%d)", count));
- return len;
+ return count;
}
const jchar* jni_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
{
- java_lang_String *s;
- java_handle_chararray_t *a;
- u2 *stringbuffer;
- int32_t count;
- int32_t offset;
- int32_t i;
+ u2 *stringbuffer;
+ int32_t i;
TRACEJNICALLS(("jni_GetStringChars(env=%p, str=%p, isCopy=%p)", env, str, isCopy));
// FIXME This is really ugly.
return emptyStringJ;
- s = (java_lang_String *) str;
+ java_lang_String s(str);
- LLNI_field_get_ref(s, value, a);
+ CharArray ca(s.get_value());
- if (a == NULL)
+ int32_t count = s.get_count();
+ int32_t offset = s.get_offset();
+
+ if (ca.is_null())
return NULL;
- LLNI_field_get_val(s, count, count);
- LLNI_field_get_val(s, offset, offset);
-
/* allocate memory */
stringbuffer = MNEW(u2, count + 1);
/* copy text */
+ // XXX: Fix me!
+ uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
for (i = 0; i < count; i++)
- stringbuffer[i] = LLNI_array_direct(a, offset + i);
+ stringbuffer[i] = ptr[offset + i];
/* terminate string */
void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
{
- java_lang_String *s;
-
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("jni_ReleaseStringChars(env=%p, str=%p, chars=%p)", env, str, chars));
+ // FIXME
if (chars == emptyStringJ)
return;
- s = (java_lang_String *) str;
+ java_lang_String s(str);
+ int32_t count = s.get_count();
- MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
+ MFREE(((jchar*) chars), jchar, count + 1);
}
*******************************************************************************/
-jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
+jstring jni_NewStringUTF(JNIEnv *env, const char *bytes)
{
- java_lang_String *s;
-
- TRACEJNICALLS(("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes));
+ TRACEJNICALLS(("jni_NewStringUTF(env=%p, bytes=%s)", env, bytes));
- s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
+ java_handle_t *h = javastring_safe_new_from_utf8(bytes);
- return (jstring) jni_NewLocalRef(env, (jobject) s);
+ return (jstring) jni_NewLocalRef(env, (jobject) h);
}
/****************** returns the utf8 length in bytes of a string *******************/
-jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
+jsize jni_GetStringUTFLength(JNIEnv *env, jstring string)
{
- java_lang_String *s;
- s4 length;
+ TRACEJNICALLS(("jni_GetStringUTFLength(env=%p, string=%p)", env, string));
- TRACEJNICALLS(("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string));
+ java_lang_String s(string);
+ CharArray ca(s.get_value());
+ int32_t count = s.get_count();
- s = (java_lang_String *) string;
-
- length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
+ // FIXME GC critical section!
+ uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
+ int32_t length = u2_utflength(ptr, count);
return length;
}
jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
{
- java_handle_t *a;
- jsize size;
-
TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
- a = (java_handle_t *) array;
+ Array a(array);
- size = LLNI_array_size(a);
+ jsize size = a.get_length();
return size;
}
jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
jclass elementClass, jobject initialElement)
{
- classinfo *c;
- java_handle_t *o;
- java_handle_objectarray_t *oa;
- s4 i;
+ classinfo* c;
+ java_handle_t* o;
+ s4 i;
STATISTICS(jniinvokation());
return NULL;
}
- oa = builtin_anewarray(length, c);
+ ObjectArray oa(length, c);
- if (oa == NULL)
+ if (oa.is_null())
return NULL;
/* set all elements to initialElement */
for (i = 0; i < length; i++)
- array_objectarray_element_set(oa, i, o);
+ oa.set_element(i, o);
- return (jobjectArray) jni_NewLocalRef(env, (jobject) oa);
+ return (jobjectArray) jni_NewLocalRef(env, (jobject) oa.get_handle());
}
jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
jsize index)
{
- java_handle_objectarray_t *oa;
- java_handle_t *o;
-
STATISTICS(jniinvokation());
- oa = (java_handle_objectarray_t *) array;
+ ObjectArray oa(array);
- if (index >= LLNI_array_size(oa)) {
+ if (index >= oa.get_length()) {
exceptions_throw_arrayindexoutofboundsexception();
return NULL;
}
- o = array_objectarray_element_get(oa, index);
+ java_handle_t* o = oa.get_element(index);
return jni_NewLocalRef(env, (jobject) o);
}
void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
jsize index, jobject val)
{
- java_handle_objectarray_t *oa;
- java_handle_t *o;
-
STATISTICS(jniinvokation());
- oa = (java_handle_objectarray_t *) array;
- o = (java_handle_t *) val;
+ ObjectArray oa(array);
- if (index >= LLNI_array_size(oa)) {
+ if (index >= oa.get_length()) {
exceptions_throw_arrayindexoutofboundsexception();
return;
}
/* check if the class of value is a subclass of the element class
of the array */
- if (!builtin_canstore(oa, o))
+ java_handle_t* o = (java_handle_t *) val;
+
+ if (!builtin_canstore(oa.get_handle(), o))
return;
- array_objectarray_element_set(oa, index, o);
+ oa.set_element(index, o);
}
-#define JNI_NEW_ARRAY(name, type, intern) \
+#define JNI_NEW_ARRAY(name, type) \
type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
{ \
- java_handle_##intern##array_t *a; \
- \
STATISTICS(jniinvokation()); \
\
if (len < 0) { \
return NULL; \
} \
\
- a = builtin_newarray_##intern(len); \
+ name##Array a(len); \
\
- return (type) jni_NewLocalRef(env, (jobject) a); \
+ return (type) jni_NewLocalRef(env, \
+ (jobject) a.get_handle()); \
}
-JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
-JNI_NEW_ARRAY(Byte, jbyteArray, byte)
-JNI_NEW_ARRAY(Char, jcharArray, char)
-JNI_NEW_ARRAY(Short, jshortArray, short)
-JNI_NEW_ARRAY(Int, jintArray, int)
-JNI_NEW_ARRAY(Long, jlongArray, long)
-JNI_NEW_ARRAY(Float, jfloatArray, float)
-JNI_NEW_ARRAY(Double, jdoubleArray, double)
+JNI_NEW_ARRAY(Boolean, jbooleanArray)
+JNI_NEW_ARRAY(Byte, jbyteArray)
+JNI_NEW_ARRAY(Char, jcharArray)
+JNI_NEW_ARRAY(Short, jshortArray)
+JNI_NEW_ARRAY(Int, jintArray)
+JNI_NEW_ARRAY(Long, jlongArray)
+JNI_NEW_ARRAY(Float, jfloatArray)
+JNI_NEW_ARRAY(Double, jdoubleArray)
/* Get<PrimitiveType>ArrayElements *********************************************
type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
jboolean *isCopy) \
{ \
- java_handle_##intern##array_t *a; \
- \
TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
\
- a = (java_handle_##intern##array_t *) array; \
+ name##Array a(array); \
\
if (isCopy) \
*isCopy = JNI_FALSE; \
\
- return (type *) LLNI_array_data(a); \
+ return (type *) a.get_raw_data_ptr(); \
}
JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
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; \
+ name##Array a(array); \
\
- if (elems != (type *) LLNI_array_data(a)) { \
+ if (elems != (type *) a.get_raw_data_ptr()) { \
switch (mode) { \
case JNI_COMMIT: \
- MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
+ a.set_region(0, a.get_length(), (intern2 *) elems); \
break; \
case 0: \
- MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
+ a.set_region(0, a.get_length(), (intern2 *) elems); \
/* XXX TWISTI how should it be freed? */ \
break; \
case JNI_ABORT: \
void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
jsize start, jsize len, type *buf) \
{ \
- java_handle_##intern##array_t *a; \
- \
TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
\
- a = (java_handle_##intern##array_t *) array; \
+ name##Array a(array); \
\
- if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
+ if ((start < 0) || (len < 0) || (start + len > a.get_length())) \
exceptions_throw_arrayindexoutofboundsexception(); \
else \
- MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
+ a.get_region(start, len, (intern2 *) buf); \
}
JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
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; \
+ name##Array a(array); \
\
- if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
+ if ((start < 0) || (len < 0) || (start + len > a.get_length())) \
exceptions_throw_arrayindexoutofboundsexception(); \
else \
- MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
+ a.set_region(start, len, (intern2 *) buf); \
}
JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
*******************************************************************************/
-jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
- const JNINativeMethod *methods, jint nMethods)
+jint jni_RegisterNatives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods)
{
- classinfo *c;
+ TRACEJNICALLS(("jni_RegisterNatives(env=%p, clazz=%p, methods=%p, nMethods=%d)", env, clazz, methods, nMethods));
- STATISTICS(jniinvokation());
-
- c = LLNI_classinfo_unwrap(clazz);
+ classinfo* c = LLNI_classinfo_unwrap(clazz);
- /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
- if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
- */
+ NativeMethods& nm = VM::get_current()->get_nativemethods();
+ nm.register_methods(c->name, methods, nMethods);
- native_method_register(c->name, methods, nMethods);
-
- return 0;
+ return 0;
}
{
STATISTICS(jniinvokation());
- *javavm = vm->get_javavm();
+ *javavm = VM::get_current()->get_javavm();
return 0;
}
*******************************************************************************/
-void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
- jchar *buf)
+void jni_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
{
- java_lang_String *s;
- java_handle_chararray_t *ca;
-
- STATISTICS(jniinvokation());
+ java_lang_String s(str);
+ CharArray ca(s.get_value());
+ int32_t count = s.get_count();
- s = (java_lang_String *) str;
- LLNI_field_get_ref(s, value, ca);
-
- if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
- (start + len > LLNI_field_direct(s, count))) {
+ if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
exceptions_throw_stringindexoutofboundsexception();
return;
}
- MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
+ ca.get_region(start, len, buf);
}
*******************************************************************************/
-void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
- jsize len, char *buf)
+void jni_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
{
- java_lang_String *s;
- java_handle_chararray_t *ca;
- s4 i;
- int32_t count;
- int32_t offset;
+ TRACEJNICALLS(("jni_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
- TRACEJNICALLS(("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
+ java_lang_String s(str);
- 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);
+ CharArray ca(s.get_value());
+
+ int32_t count = s.get_count();
+ int32_t offset = s.get_offset();
if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
exceptions_throw_stringindexoutofboundsexception();
return;
}
+ int32_t i;
+
+ // XXX: Fix me!
+ uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
for (i = 0; i < len; i++)
- buf[i] = LLNI_array_direct(ca, offset + start + i);
+ buf[i] = ptr[offset + start + i];
buf[i] = '\0';
}
argument.
*******************************************************************************/
-
+
jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
{
hashtable_global_ref_entry *gre;
o = (java_handle_t *) obj;
- LOCK_MONITOR_ENTER(hashtable_global_ref->header);
+ hashtable_global_ref->mutex->lock();
LLNI_CRITICAL_START;
hashtable_global_ref->entries++;
}
- LOCK_MONITOR_EXIT(hashtable_global_ref->header);
+ hashtable_global_ref->mutex->unlock();
#if defined(ENABLE_HANDLES)
return gre;
o = (java_handle_t *) globalRef;
- LOCK_MONITOR_ENTER(hashtable_global_ref->header);
+ hashtable_global_ref->mutex->lock();
LLNI_CRITICAL_START;
LLNI_CRITICAL_END;
- LOCK_MONITOR_EXIT(hashtable_global_ref->header);
+ hashtable_global_ref->mutex->unlock();
return;
}
LLNI_CRITICAL_END;
- LOCK_MONITOR_EXIT(hashtable_global_ref->header);
+ hashtable_global_ref->mutex->unlock();
}
{
#if defined(ENABLE_JAVASE)
# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
- java_handle_t *nbuf;
-
-# if SIZEOF_VOID_P == 8
- gnu_classpath_Pointer64 *paddress;
-# else
- gnu_classpath_Pointer32 *paddress;
-# endif
-
TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
- /* alocate a gnu.classpath.Pointer{32,64} object */
+ // Allocate a gnu.classpath.Pointer{32,64} object.
# if SIZEOF_VOID_P == 8
- if (!(paddress = (gnu_classpath_Pointer64 *)
- builtin_new(class_gnu_classpath_Pointer64)))
+ java_handle_t* h = builtin_new(class_gnu_classpath_Pointer64);
# else
- if (!(paddress = (gnu_classpath_Pointer32 *)
- builtin_new(class_gnu_classpath_Pointer32)))
+ java_handle_t* h = builtin_new(class_gnu_classpath_Pointer32);
# endif
- return NULL;
- /* fill gnu.classpath.Pointer{32,64} with address */
+ if (h == NULL)
+ return NULL;
- LLNI_field_set_val(paddress, data, (ptrint) address);
+ gnu_classpath_Pointer p(h, address);
- /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
+ // Create a java.nio.DirectByteBufferImpl$ReadWrite object.
- nbuf = (java_handle_t*) jni_NewObject(env, (jclass) class_java_nio_DirectByteBufferImpl_ReadWrite,
- (jmethodID) dbbirw_init, NULL, paddress,
- (jint) capacity, (jint) capacity, (jint) 0);
+ java_handle_t* nbuf =
+ (java_handle_t*) jni_NewObject(env, (jclass) class_java_nio_DirectByteBufferImpl_ReadWrite,
+ (jmethodID) dbbirw_init, NULL, p.get_handle(),
+ (jint) capacity, (jint) capacity, (jint) 0);
- /* add local reference and return the value */
+ // Add a local reference and return the value.
TRACEJNICALLSEXIT(("->%p", nbuf));
*******************************************************************************/
-void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
+void* jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
{
#if defined(ENABLE_JAVASE)
- java_handle_t *h;
-
# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
- java_nio_DirectByteBufferImpl *nbuf;
- gnu_classpath_Pointer *po;
-# if SIZEOF_VOID_P == 8
- gnu_classpath_Pointer64 *paddress;
- int64_t address;
-# else
- gnu_classpath_Pointer32 *paddress;
- int32_t address;
-# endif
- void *p;
-
- TRACEJNICALLSENTER(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
+ TRACEJNICALLSENTER(("jni_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
/* Prevent compiler warning. */
- h = (java_handle_t *) buf;
+ java_handle_t* h = (java_handle_t *) buf;
if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
return NULL;
- nbuf = (java_nio_DirectByteBufferImpl *) buf;
-
- LLNI_field_get_ref(nbuf, address, po);
+ java_nio_DirectByteBufferImpl dbb(buf);
+ java_handle_t* address = dbb.get_address();
-# if SIZEOF_VOID_P == 8
- paddress = (gnu_classpath_Pointer64 *) po;
-# else
- paddress = (gnu_classpath_Pointer32 *) po;
-# endif
-
- if (paddress == NULL) {
+ if (address == NULL) {
TRACEJNICALLSEXIT(("->%p", NULL));
return NULL;
}
- LLNI_field_get_val(paddress, data, address);
-
- p = (void *) (intptr_t) address;
+ gnu_classpath_Pointer p(address);
+ void* data = p.get_data();
- TRACEJNICALLSEXIT(("->%p", p));
+ TRACEJNICALLSEXIT(("->%p", data));
- return p;
+ return data;
# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
- java_nio_Buffer *o;
- int64_t address;
- void *p;
+ TRACEJNICALLS(("jni_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
- TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
+ java_nio_Buffer jnb(buf);
- /* Prevent compiler warning. */
-
- h = (java_handle_t *) buf;
-
- if ((h != NULL) && !builtin_instanceof(h, class_sun_nio_ch_DirectBuffer))
+ if (jnb.is_non_null() && !builtin_instanceof(jnb.get_handle(), class_sun_nio_ch_DirectBuffer))
return NULL;
- o = (java_nio_Buffer *) buf;
-
- LLNI_field_get_val(o, address, address);
-
- p = (void *) (intptr_t) address;
+ void* address = jnb.get_address();
- return p;
+ return address;
# else
# error unknown classpath configuration
#else
- vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
-
- /* keep compiler happy */
+ vm_abort("jni_GetDirectBufferAddress: Not implemented in this configuration.");
+ // Keep compiler happy.
return NULL;
#endif
*******************************************************************************/
-jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
+jlong jni_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
{
#if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
- java_handle_t *o;
- java_nio_Buffer *nbuf;
- jlong capacity;
+ TRACEJNICALLS(("jni_GetDirectBufferCapacity(env=%p, buf=%p)", env, buf));
- STATISTICS(jniinvokation());
+ java_handle_t* h = (java_handle_t *) buf;
- o = (java_handle_t *) buf;
-
- if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
+ if (!builtin_instanceof(h, class_java_nio_DirectByteBufferImpl))
return -1;
- nbuf = (java_nio_Buffer *) o;
-
- LLNI_field_get_val(nbuf, cap, capacity);
+ java_nio_Buffer b(h);
+ jlong capacity = b.get_cap();
return capacity;
#else
- vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
+ vm_abort("jni_GetDirectBufferCapacity: not implemented in this configuration");
- /* keep compiler happy */
+ // Keep compiler happy.
return 0;
#endif
TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(javavm=%p)", javavm));
- if (vm->is_created() == false)
+ if (VM::get_current()->is_created() == false)
return JNI_ERR;
status = vm_destroy(javavm);
result = thread_current_is_attached();
if (result == true) {
- *p_env = vm->get_jnienv();
+ *p_env = VM::get_current()->get_jnienv();
return JNI_OK;
}
return JNI_ERR;
#endif
- *p_env = vm->get_jnienv();
+ *p_env = VM::get_current()->get_jnienv();
return JNI_OK;
}
TRACEJNICALLS(("jni_AttachCurrentThread(javavm=%p, p_env=%p, thr_args=%p)", javavm, p_env, thr_args));
- if (vm->is_created() == false)
+ if (VM::get_current()->is_created() == false)
return JNI_ERR;
result = jni_attach_current_thread(p_env, thr_args, false);
{
TRACEJNICALLS(("jni_GetEnv(javavm=%p, env=%p, version=%d)", javavm, env, version));
- if (vm->is_created() == false) {
+ if (VM::get_current()->is_created() == false) {
*env = NULL;
return JNI_EDETACHED;
}
/* Check the JNI version. */
if (jni_version_check(version) == true) {
- *env = vm->get_jnienv();
+ *env = VM::get_current()->get_jnienv();
return JNI_OK;
}
TRACEJNICALLS(("jni_AttachCurrentThreadAsDaemon(javavm=%p, penv=%p, args=%p)", javavm, penv, args));
- if (vm->is_created() == false)
+ if (VM::get_current()->is_created() == false)
return JNI_ERR;
result = jni_attach_current_thread(penv, args, true);
NULL,
_Jv_JNI_GetVersion,
- _Jv_JNI_DefineClass,
+ jni_DefineClass,
jni_FindClass,
jni_FromReflectedMethod,
jni_FromReflectedField,
- _Jv_JNI_ToReflectedMethod,
- _Jv_JNI_GetSuperclass,
+ jni_ToReflectedMethod,
+ jni_GetSuperclass,
_Jv_JNI_IsAssignableFrom,
_Jv_JNI_ToReflectedField,
_Jv_JNI_NewObjectV,
_Jv_JNI_NewObjectA,
- _Jv_JNI_GetObjectClass,
+ jni_GetObjectClass,
_Jv_JNI_IsInstanceOf,
_Jv_JNI_GetMethodID,
_Jv_JNI_SetStaticFloatField,
_Jv_JNI_SetStaticDoubleField,
- _Jv_JNI_NewString,
- _Jv_JNI_GetStringLength,
+ jni_NewString,
+ jni_GetStringLength,
jni_GetStringChars,
_Jv_JNI_ReleaseStringChars,
- _Jv_JNI_NewStringUTF,
- _Jv_JNI_GetStringUTFLength,
+ jni_NewStringUTF,
+ jni_GetStringUTFLength,
_Jv_JNI_GetStringUTFChars,
_Jv_JNI_ReleaseStringUTFChars,
_Jv_JNI_SetFloatArrayRegion,
_Jv_JNI_SetDoubleArrayRegion,
- _Jv_JNI_RegisterNatives,
+ jni_RegisterNatives,
_Jv_JNI_UnregisterNatives,
_Jv_JNI_MonitorEnter,
/* New JNI 1.2 functions. */
- _Jv_JNI_GetStringRegion,
- _Jv_JNI_GetStringUTFRegion,
+ jni_GetStringRegion,
+ jni_GetStringUTFRegion,
jni_GetPrimitiveArrayCritical,
jni_ReleasePrimitiveArrayCritical,
/* New JNI 1.4 functions. */
jni_NewDirectByteBuffer,
- _Jv_JNI_GetDirectBufferAddress,
- _Jv_JNI_GetDirectBufferCapacity,
+ jni_GetDirectBufferAddress,
+ jni_GetDirectBufferCapacity,
/* New JNI 1.6 functions. */
/* GNU classpath currently supports JNI 1.2 */
switch (_vm_args->version) {
- case JNI_VERSION_1_1:
+ case JNI_VERSION_1_1:
_vm_args->version = JNI_VERSION_1_1;
break;
- case JNI_VERSION_1_2:
- case JNI_VERSION_1_4:
+ 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;
+ case JNI_VERSION_CACAO:
+ // We reveal ourselves by accepting this version number,
+ // this actually means we are using the supported JNI version.
+ _vm_args->version = JNI_VERSION_SUPPORTED;
+ break;
+
+ default:
+ return JNI_ERR;
}
-
- return 0;
+
+ return JNI_OK;
}
// We currently only support 1 VM running.
- vmBuf[0] = vm->get_javavm();
+ vmBuf[0] = VM::get_current()->get_javavm();
*nVMs = 1;
return JNI_OK;
* Emacs will automagically detect them.
* ---------------------------------------------------------------------
* Local variables:
- * mode: c
+ * mode: c++
* indent-tabs-mode: t
* c-basic-offset: 4
* tab-width: 4