* src/native/jni.cpp: [OPENJDK] Implemented jni_GetDirectBufferCapacity.
[cacao.git] / src / native / jni.cpp
index 41aad483e0d5bd74ebb6ef6439a70b6d33013b2c..661780662a239c07a46fd157f4ccce0377900621 100644 (file)
@@ -1,6 +1,6 @@
 /* src/native/jni.cpp - implementation of the Java Native Interface functions
 
-   Copyright (C) 1996-2005, 2006, 2007, 2008
+   Copyright (C) 1996-2011
    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.hpp"
 #include "native/llni.h"
-#include "native/localref.h"
+#include "native/localref.hpp"
 #include "native/native.hpp"
 
 #if defined(ENABLE_JVMTI)
 #include "threads/mutex.hpp"
 #include "threads/thread.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
-#include "vm/array.h"
+#include "vm/array.hpp"
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
-#include "vm/initialize.h"
+#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.hpp"
 #include "vm/jit/stacktrace.hpp"
@@ -794,9 +793,7 @@ jint _Jv_JNI_GetVersion(JNIEnv *env)
 {
        TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
 
-       /* We support JNI 1.6. */
-
-       return JNI_VERSION_1_6;
+       return JNI_VERSION_SUPPORTED;
 }
 
 
@@ -2072,6 +2069,8 @@ jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
 #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)                                  \
@@ -2082,7 +2081,10 @@ void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID,  \
                                                                            \
        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)
@@ -2105,6 +2107,9 @@ void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
        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();
 }
 
 
@@ -2256,7 +2261,7 @@ jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
        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;
 
@@ -2303,7 +2308,7 @@ void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
 {
        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;
 
@@ -2442,6 +2447,9 @@ void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
                        return;                                            \
                                                                \
        f->value->field = value;                                   \
+                                                                                                                          \
+       if (f->flags & ACC_VOLATILE)                               \
+               Atomic::memory_barrier();                              \
 }
 
 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
@@ -2470,6 +2478,9 @@ void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
                        return;
 
        f->value->a = LLNI_UNWRAP((java_handle_t *) value);
+
+       if (f->flags & ACC_VOLATILE)
+               Atomic::memory_barrier();
 }
 
 
@@ -2485,22 +2496,25 @@ void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
 jstring jni_NewString(JNIEnv *env, const jchar *buf, jsize len)
 {
        TRACEJNICALLS(("jni_NewString(env=%p, buf=%p, len=%d)", env, buf, len));
-       
-       java_handle_chararray_t* a = builtin_newarray_char(len);
 
-       if (a == NULL)
+       CharArray ca(len);
+
+       if (ca.is_null())
                return NULL;
 
        /* copy text */
+
+       // XXX: Fix me!
+       uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
        for (jsize i = 0; i < len; i++)
-               LLNI_array_direct(a, i) = buf[i];
+               ptr[i] = buf[i];
 
        java_handle_t* h = builtin_new(class_java_lang_String);
 
        if (h == NULL)
                return NULL;
 
-       java_lang_String s(h, a, len, 0);
+       java_lang_String s(h, ca.get_handle(), len, 0);
 
        return (jstring) jni_NewLocalRef(env, (jobject) s.get_handle());
 }
@@ -2548,11 +2562,12 @@ const jchar* jni_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
 
        java_lang_String s(str);
 
-       java_handle_chararray_t* ca     = s.get_value();
-       int32_t                  count  = s.get_count();
-       int32_t                  offset = s.get_offset();
+       CharArray ca(s.get_value());
+
+       int32_t count  = s.get_count();
+       int32_t offset = s.get_offset();
        
-       if (ca == NULL)
+       if (ca.is_null())
                return NULL;
 
        /* allocate memory */
@@ -2561,8 +2576,10 @@ const jchar* jni_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
 
        /* 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(ca, offset + i);
+               stringbuffer[i] = ptr[offset + i];
        
        /* terminate string */
 
@@ -2622,11 +2639,12 @@ jsize jni_GetStringUTFLength(JNIEnv *env, jstring string)
        TRACEJNICALLS(("jni_GetStringUTFLength(env=%p, string=%p)", env, string));
 
        java_lang_String s(string);
-       java_handle_chararray_t* ca     = s.get_value();
-       int32_t                  count  = s.get_count();
+       CharArray        ca(s.get_value());
+       int32_t          count = s.get_count();
 
        // FIXME GC critical section!
-       int32_t length = u2_utflength(ca->data, count);
+       uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
+       int32_t length = u2_utflength(ptr, count);
 
        return length;
 }
@@ -2690,14 +2708,11 @@ void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
 
 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;
 }
@@ -2713,10 +2728,9 @@ jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
 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());
 
@@ -2728,36 +2742,33 @@ jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
                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);
 }
@@ -2766,15 +2777,11 @@ jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
 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;
        }
@@ -2782,18 +2789,18 @@ void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
        /* 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) {                                       \
@@ -2801,19 +2808,20 @@ type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len)    \
                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 *********************************************
@@ -2826,16 +2834,14 @@ JNI_NEW_ARRAY(Double,  jdoubleArray,  double)
 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)
@@ -2863,19 +2869,17 @@ JNI_GET_ARRAY_ELEMENTS(Double,  jdouble,  double)
 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:                                                    \
@@ -2906,16 +2910,14 @@ JNI_RELEASE_ARRAY_ELEMENTS(Double,  jdouble,  double,  double)
 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)
@@ -2939,16 +2941,14 @@ JNI_GET_ARRAY_REGION(Double,  jdouble,  double,  double)
 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)
@@ -2973,22 +2973,16 @@ JNI_SET_ARRAY_REGION(Double,  jdouble,  double,  double)
 
 *******************************************************************************/
 
-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;
-
-       STATISTICS(jniinvokation());
-
-       c = LLNI_classinfo_unwrap(clazz);
+       TRACEJNICALLS(("jni_RegisterNatives(env=%p, clazz=%p, methods=%p, nMethods=%d)", env, clazz, methods, nMethods));
 
-       /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
-       if (jvmti) jvmti_NativeMethodBind(method, address,  new_address_ptr);
-       */
+       classinfo* c = LLNI_classinfo_unwrap(clazz);
 
-       native_method_register(c->name, methods, nMethods);
+       NativeMethods& nm = VM::get_current()->get_nativemethods();
+       nm.register_methods(c->name, methods, nMethods);
 
-    return 0;
+       return 0;
 }
 
 
@@ -3097,15 +3091,15 @@ jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **javavm)
 void jni_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
 {
        java_lang_String s(str);
-       java_handle_chararray_t* ca    = s.get_value();
-       int32_t                  count = s.get_count();
+       CharArray        ca(s.get_value());
+       int32_t          count = s.get_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);
 }
 
 
@@ -3124,9 +3118,11 @@ void jni_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, ch
        TRACEJNICALLS(("jni_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
 
        java_lang_String s(str);
-       java_handle_chararray_t* ca     = s.get_value();
-       int32_t                  count  = s.get_count();
-       int32_t                  offset = s.get_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();
@@ -3135,8 +3131,10 @@ void jni_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, ch
 
        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';
 }
@@ -3567,7 +3565,8 @@ void* jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
 
 jlong jni_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
 {
-#if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
        TRACEJNICALLS(("jni_GetDirectBufferCapacity(env=%p, buf=%p)", env, buf));
 
        java_handle_t* h = (java_handle_t *) buf;
@@ -3579,6 +3578,23 @@ jlong jni_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
        jlong capacity = b.get_cap();
 
        return capacity;
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       TRACEJNICALLS(("jni_GetDirectBufferCapacity(env=%p, buf=%p)", env, buf));
+
+       java_nio_Buffer jnb(buf);
+
+       if (!builtin_instanceof(jnb.get_handle(), class_sun_nio_ch_DirectBuffer))
+               return -1;
+
+       jlong capacity = jnb.get_capacity();
+
+       return capacity;
+
+# else
+#  error unknown classpath configuration
+# endif
+
 #else
        vm_abort("jni_GetDirectBufferCapacity: not implemented in this configuration");
 
@@ -4075,7 +4091,7 @@ struct JNINativeInterface_ _Jv_JNINativeInterface = {
        _Jv_JNI_SetFloatArrayRegion,
        _Jv_JNI_SetDoubleArrayRegion,
 
-       _Jv_JNI_RegisterNatives,
+       jni_RegisterNatives,
        _Jv_JNI_UnregisterNatives,
 
        _Jv_JNI_MonitorEnter,
@@ -4128,22 +4144,28 @@ jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
        /* 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;
 }