Merged with new-trap-decoding branch at rev a792088a3f04 (branch closed).
authorMichael Starzinger <michi@complang.tuwien.ac.at>
Wed, 15 Apr 2009 15:04:15 +0000 (17:04 +0200)
committerMichael Starzinger <michi@complang.tuwien.ac.at>
Wed, 15 Apr 2009 15:04:15 +0000 (17:04 +0200)
38 files changed:
src/mm/boehm-gc/os_dep.c
src/native/jni.cpp
src/native/llni.h
src/native/vm/cldc1.1/com_sun_cldc_io_ResourceInputStream.cpp
src/native/vm/cldc1.1/com_sun_cldc_io_j2me_socket_Protocol.cpp
src/native/vm/cldc1.1/java_lang_String.cpp
src/native/vm/gnuclasspath/gnu_java_lang_VMCPStringBuilder.cpp
src/native/vm/gnuclasspath/gnu_java_lang_management_VMRuntimeMXBeanImpl.cpp
src/native/vm/gnuclasspath/java_lang_VMClassLoader.cpp
src/native/vm/gnuclasspath/java_lang_VMThrowable.cpp
src/native/vm/gnuclasspath/java_lang_management_VMManagementFactory.cpp
src/native/vm/openjdk/jvm.cpp
src/native/vm/reflection.cpp
src/native/vm/sun_misc_Unsafe.cpp
src/vm/annotation.cpp
src/vm/array.cpp
src/vm/array.hpp
src/vm/class.cpp
src/vm/field.cpp
src/vm/global.h
src/vm/javaobjects.cpp
src/vm/javaobjects.hpp
src/vm/jit/argument.cpp
src/vm/jit/builtin.cpp
src/vm/jit/builtin.hpp
src/vm/jit/stacktrace.cpp
src/vm/jit/stacktrace.hpp
src/vm/jit/trace.cpp
src/vm/loader.cpp
src/vm/method.cpp
src/vm/options.c
src/vm/options.h
src/vm/primitive.cpp
src/vm/primitive.hpp
src/vm/string.cpp
src/vm/vm.cpp
tests/regression/bugzilla/All.java
tests/regression/bugzilla/PR125.java [new file with mode: 0644]

index 5aa41f3e7186e44fab9e249b976c1a5dbc4c5852..321aba94bbfdd910039fb12122d858a58d037593 100644 (file)
@@ -1077,7 +1077,7 @@ ptr_t GC_get_main_stack_base(void)
       c = stat_buf[buf_offset++];
     }
     close(f);
-    if (result < 0x10000000) ABORT("Absurd stack bottom value");
+    if (result < 0x100000) ABORT("Absurd stack bottom value");
     return (ptr_t)result;
   }
 
index e048a216df072e34bd3da2af611217667a7a8180..d33892469c10a7621c96efdc14b6e8dd2a921708 100644 (file)
@@ -2482,22 +2482,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());
 }
@@ -2545,11 +2548,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 */
@@ -2558,8 +2562,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 */
 
@@ -2619,11 +2625,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;
 }
@@ -2687,14 +2694,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;
 }
@@ -2710,10 +2714,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());
 
@@ -2725,36 +2728,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);
 }
@@ -2763,15 +2763,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;
        }
@@ -2779,18 +2775,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) {                                       \
@@ -2798,19 +2794,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 *********************************************
@@ -2823,16 +2820,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)
@@ -2860,19 +2855,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:                                                    \
@@ -2903,16 +2896,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)
@@ -2936,16 +2927,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)
@@ -3092,15 +3081,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);
 }
 
 
@@ -3119,9 +3108,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();
@@ -3130,8 +3121,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';
 }
index 6112dfbfe4a4b286db7632a7e3430ef3219c7e91..77cb9299b68a2000778c09bc10d8cb0599568513 100644 (file)
 
 #define LLNI_field_direct(obj, field) (LLNI_DIRECT(obj)->field)
 #define LLNI_vftbl_direct(obj)        (LLNI_DIRECT((java_handle_t *) (obj))->vftbl)
-#define LLNI_array_direct(arr, index) (LLNI_DIRECT(arr)->data[(index)])
-#define LLNI_array_data(arr)          (LLNI_DIRECT(arr)->data)
-#define LLNI_array_size(arr)          (LLNI_DIRECT((java_handle_objectarray_t *) (arr))->header.size)
 
 
 /* LLNI critical sections ******************************************************
index ac12cc83523f303ebfcba585c6ff676be6d4c272..30efeaa2cc45d069883695cc8182088208cc76f6 100644 (file)
@@ -34,7 +34,6 @@
 #include "mm/memory.hpp"
 
 #include "native/jni.hpp"
-#include "native/llni.h"
 #include "native/native.hpp"
 
 #if defined(ENABLE_JNI_HEADERS)
@@ -43,7 +42,7 @@
 
 #include "threads/mutex.hpp"
 
-#include "vm/jit/builtin.hpp"
+#include "vm/array.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/javaobjects.hpp"
 #include "vm/string.hpp"
@@ -305,8 +304,9 @@ JNIEXPORT jint JNICALL Java_com_sun_cldc_io_ResourceInputStream_readBytes(JNIEnv
 {
        /* get pointer to the buffer */
        // XXX Not GC safe.
-       void* buf = &(LLNI_array_direct((java_handle_bytearray_t*) byteArray, off));
-       
+       ByteArray ba(byteArray);
+       void* buf = (void*) (((int8_t*) ba.get_raw_data_ptr()) + off);
+
        com_sun_cldchi_jvm_FileDescriptor fd(jobj);
 
        int64_t filep      = fd.get_pointer();
index 860d88d5db12af0a314284eaac379749b583af06..cf99a13a98df8356fd8e6cb9236e796782aa4cb7 100644 (file)
 #include "mm/memory.hpp"
 
 #include "native/jni.hpp"
-#include "native/llni.h"
 #include "native/native.hpp"
 
 #if defined(ENABLE_JNI_HEADERS)
 # include "native/include/com_sun_cldc_io_j2me_socket_Protocol.h"
 #endif
 
+#include "vm/array.hpp"
 #include "vm/global.h"
 #include "vm/os.hpp"
 #include "vm/vm.hpp" /* REMOVE ME: temporarily */
@@ -64,7 +64,8 @@ JNIEXPORT jint JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_open0(JNIEnv *e
 
        // The hostname byte-array is a NULL terminated C-string.
        // XXX Not GC safe.
-       char* name = (char*) &(LLNI_array_data((java_handle_bytearray_t*) hostname));
+       ByteArray ba(hostname);
+       char* name = (char*) ba.get_raw_data_ptr();
 
        /* get the host */
 
@@ -107,7 +108,8 @@ JNIEXPORT jint JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_readBuf(JNIEnv
 {
        // Get pointer to the buffer.
        // XXX Not GC safe.
-       void* buf = &(LLNI_array_direct((java_handle_bytearray_t*) b, off));
+       ByteArray ba(b);
+       void* buf = (void*) (((int8_t*) ba.get_raw_data_ptr()) + off);
 
        // Receive from the socket.
        ssize_t result = recv(handle, buf, len, 0);
@@ -158,7 +160,8 @@ JNIEXPORT jint JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_writeBuf(JNIEnv
 {
        // Get pointer to the buffer.
        // XXX Not GC safe.
-       void* buf = &(LLNI_array_direct((java_handle_bytearray_t*) b, off));
+       ByteArray ba(b);
+       void* buf = (void*) (((int8_t*) ba.get_raw_data_ptr()) + off);
        
        // Send the given byte to the socket.
        ssize_t result = send(handle, buf, len, 0);
index b86e539d45c22aa35cd12947f3c0ab84984a0633..a4614908193304569f0a3cfd9d586148ae5c49f3 100644 (file)
 #include <string.h>
 
 #include "native/jni.hpp"
-#include "native/llni.h"
 #include "native/native.hpp"
 
 #if defined(ENABLE_JNI_HEADERS)
 # include "native/include/java_lang_String.h"
 #endif
 
+#include "vm/array.hpp"
 #include "vm/javaobjects.hpp"
 #include "vm/string.hpp"
 
@@ -53,14 +53,15 @@ JNIEXPORT jint JNICALL Java_java_lang_String_hashCode(JNIEnv *env, jstring _this
 {
        java_lang_String jls(_this);
 
-       java_handle_chararray_t* value = jls.get_value();
+       CharArray value(jls.get_value());
+
        int32_t offset = jls.get_offset();
        int32_t count  = jls.get_count();
 
        int32_t hash = 0;
 
        for (int32_t i = 0; i < count; i++) {
-               hash = (31 * hash) + LLNI_array_direct(value, offset + i);
+               hash = (31 * hash) + value.get_element(offset + i);
        }
 
        return hash;
@@ -76,12 +77,13 @@ JNIEXPORT jint JNICALL Java_java_lang_String_indexOf__I(JNIEnv *env, jstring _th
 {
        java_lang_String jls(_this);
 
-       java_handle_chararray_t* value = jls.get_value();
+       CharArray value(jls.get_value());
+
        int32_t offset = jls.get_offset();
        int32_t count  = jls.get_count();
 
        for (int32_t i = 0; i < count; i++) {
-               if (LLNI_array_direct(value, offset + i) == ch) {
+               if (value.get_element(offset + i) == ch) {
                        return i;
                }
        }
@@ -99,7 +101,8 @@ JNIEXPORT jint JNICALL Java_java_lang_String_indexOf__II(JNIEnv *env, jstring _t
 {
        java_lang_String jls(_this);
 
-       java_handle_chararray_t* value = jls.get_value();
+       CharArray value(jls.get_value());
+
        int32_t offset = jls.get_offset();
        int32_t count  = jls.get_count();
 
@@ -112,7 +115,7 @@ JNIEXPORT jint JNICALL Java_java_lang_String_indexOf__II(JNIEnv *env, jstring _t
        }
 
        for (int32_t i = fromIndex ; i < count ; i++) {
-               if (LLNI_array_direct(value, offset + i) == ch) {
+               if (value.get_element(offset + i) == ch) {
                        return i;
                }
        }
@@ -130,14 +133,15 @@ JNIEXPORT jint JNICALL Java_java_lang_String_lastIndexOf__II(JNIEnv *env, jstrin
 {
        java_lang_String jls(_this);
 
-       java_handle_chararray_t* value = jls.get_value();
+       CharArray value(jls.get_value());
+
        int32_t offset = jls.get_offset();
        int32_t count  = jls.get_count();
 
        int32_t start = ((fromIndex >= count) ? count - 1 : fromIndex);
 
        for (int32_t i = start; i >= 0; i--) {
-               if (LLNI_array_direct(value, offset + i) == ch) {
+               if (value.get_element(offset + i) == ch) {
                        return i;
                }
        }
index c0b34194224d2ec9d1ca69d1f0cc0a39e054b6fc..59ba4e704b624b562e2ac446d08faab33f08655d 100644 (file)
@@ -35,6 +35,7 @@
 # include "native/vm/include/gnu_java_lang_VMCPStringBuilder.h"
 #endif
 
+#include "vm/array.hpp"
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/globals.hpp"
@@ -51,13 +52,13 @@ JNIEXPORT jstring JNICALL Java_gnu_java_lang_VMCPStringBuilder_toString(JNIEnv *
        /* This is a native version of
           java.lang.String.<init>([CIIZ)Ljava/lang/String; */
 
-    if (startIndex < 0) {
+       if (startIndex < 0) {
 /*             exceptions_throw_stringindexoutofboundsexception("offset: " + offset); */
                exceptions_throw_stringindexoutofboundsexception();
                return NULL;
        }
 
-    if (count < 0) {
+       if (count < 0) {
 /*             exceptions_throw_stringindexoutofboundsexception("count: " + count); */
                exceptions_throw_stringindexoutofboundsexception();
                return NULL;
@@ -65,13 +66,9 @@ JNIEXPORT jstring JNICALL Java_gnu_java_lang_VMCPStringBuilder_toString(JNIEnv *
 
     /* equivalent to: offset + count < 0 || offset + count > data.length */
 
-       java_handle_chararray_t* ca = (java_handle_chararray_t*) value;
+       CharArray ca(value);
 
-       LLNI_CRITICAL_START;
-       int32_t length = LLNI_array_size(ca);
-       LLNI_CRITICAL_END;
-
-    if (length - startIndex < count) {
+       if (ca.get_length() - startIndex < count) {
 /*             exceptions_throw_stringindexoutofboundsexception("offset + count: " + (offset + count)); */
                exceptions_throw_stringindexoutofboundsexception();
                return NULL;
@@ -82,7 +79,7 @@ JNIEXPORT jstring JNICALL Java_gnu_java_lang_VMCPStringBuilder_toString(JNIEnv *
        if (h == NULL)
                return NULL;
 
-       java_lang_String s(h, ca, (int32_t) count, (int32_t) startIndex);
+       java_lang_String s(h, ca.get_handle(), (int32_t) count, (int32_t) startIndex);
 
        return (jstring) s.get_handle();
 }
index c17382a54fc729faca297936393680a2bd4f5e11..0bca5347cd76f41d99cc84602649db58b460f4eb 100644 (file)
@@ -34,6 +34,7 @@
 # include "native/vm/include/gnu_java_lang_management_VMRuntimeMXBeanImpl.h"
 #endif
 
+#include "vm/array.hpp"
 #include "vm/jit/builtin.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
@@ -53,7 +54,9 @@ JNIEXPORT java_handle_objectarray_t* JNICALL Java_gnu_java_lang_management_VMRun
 {
        log_println("Java_gnu_java_lang_management_VMRuntimeMXBeanImpl_getInputArguments: IMPLEMENT ME!");
 
-       return builtin_anewarray(0, class_java_lang_String);
+       ObjectArray oa(0, class_java_lang_String);
+
+       return oa.get_handle();
 }
 
 
index 2c3bc512514d50ee42849f6f56e18fad7021da0f..10e2d63eba6ba5e0b4a192d502e18488107e764e 100644 (file)
@@ -46,6 +46,7 @@
 #include "vm/assertion.hpp"
 #endif
 
+#include "vm/array.hpp"
 #include "vm/jit/builtin.hpp"
 #include "vm/class.hpp"
 #include "vm/classcache.hpp"
@@ -79,11 +80,10 @@ extern "C" {
  */
 JNIEXPORT jclass JNICALL Java_java_lang_VMClassLoader_defineClass(JNIEnv *env, jclass clazz, jobject cl, jstring name, jbyteArray data, jint offset, jint len, jobject pd)
 {
-       utf             *utfname;
-       classinfo       *c;
-       classloader_t   *loader;
-       java_handle_bytearray_t* ba;
-       uint8_t*                 stream;
+       utf*           utfname;
+       classinfo*     c;
+       classloader_t* loader;
+       uint8_t*       stream;
 
 #if defined(ENABLE_JVMTI)
        jint new_class_data_len = 0;
@@ -99,7 +99,9 @@ JNIEXPORT jclass JNICALL Java_java_lang_VMClassLoader_defineClass(JNIEnv *env, j
 
        /* check the indexes passed */
 
-       if ((offset < 0) || (len < 0) || ((offset + len) > LLNI_array_size(data))) {
+       ByteArray ba(data);
+
+       if ((offset < 0) || (len < 0) || ((offset + len) > ba.get_length())) {
                exceptions_throw_arrayindexoutofboundsexception();
                return NULL;
        }
@@ -138,8 +140,7 @@ JNIEXPORT jclass JNICALL Java_java_lang_VMClassLoader_defineClass(JNIEnv *env, j
        else
 #endif
        {
-               ba = (java_handle_bytearray_t*) data;
-               stream = (uint8_t *) &LLNI_array_direct(ba, offset);
+               stream = ((uint8_t *) ba.get_raw_data_ptr()) + offset;
                c = class_define(utfname, loader, len, stream, (java_handle_t *) pd);
        }
 
index fca7f8d1d783d0b9396f820adfe3ddeac5983569..2e2bae3664cf9e9ef49f944af0d3fa5719ec7894 100644 (file)
@@ -94,10 +94,10 @@ JNIEXPORT jobjectArray JNICALL Java_java_lang_VMThrowable_getStackTrace(JNIEnv *
 
        // Get the stacktrace from the VMThrowable object.
 
-       java_handle_bytearray_t* ba = vmt.get_vmdata();
+       ByteArray ba(vmt.get_vmdata());
 
        // XXX Critical GC section?
-       stacktrace_t* st = (stacktrace_t*) LLNI_array_data(ba);
+       stacktrace_t* st = (stacktrace_t*) ba.get_raw_data_ptr();
 
        assert(st != NULL);
 
index 23400775965991fd8ab821e8198ef71ecb437a75..48b7770866bea2cfbcc2621177a77357b1c53922 100644 (file)
@@ -38,6 +38,7 @@
 
 #include "toolbox/logging.hpp"
 
+#include "vm/array.hpp"
 #include "vm/globals.hpp"
 #include "vm/vm.hpp"
 
@@ -54,13 +55,11 @@ extern "C" {
  */
 JNIEXPORT jobjectArray JNICALL Java_java_lang_management_VMManagementFactory_getMemoryPoolNames(JNIEnv *env, jclass clazz)
 {
-       java_handle_objectarray_t *oa;
-
        log_println("Java_java_lang_management_VMManagementFactory_getMemoryPoolNames: IMPLEMENT ME!");
 
-       oa = builtin_anewarray(0, class_java_lang_String);
+       ObjectArray oa(0, class_java_lang_String);
 
-       return oa;
+       return oa.get_handle();
 }
 
 
@@ -71,13 +70,11 @@ JNIEXPORT jobjectArray JNICALL Java_java_lang_management_VMManagementFactory_get
  */
 JNIEXPORT jobjectArray JNICALL Java_java_lang_management_VMManagementFactory_getMemoryManagerNames(JNIEnv *env, jclass clazz)
 {
-       java_handle_objectarray_t *oa;
-
        log_println("Java_java_lang_management_VMManagementFactory_getMemoryManagerNames: IMPLEMENT ME!");
 
-       oa = builtin_anewarray(0, class_java_lang_String);
+       ObjectArray oa(0, class_java_lang_String);
 
-       return oa;
+       return oa.get_handle();
 }
 
 
@@ -88,13 +85,11 @@ JNIEXPORT jobjectArray JNICALL Java_java_lang_management_VMManagementFactory_get
  */
 JNIEXPORT jobjectArray JNICALL Java_java_lang_management_VMManagementFactory_getGarbageCollectorNames(JNIEnv *env, jclass clazz)
 {
-       java_handle_objectarray_t *oa;
-
        log_println("Java_java_lang_management_VMManagementFactory_getGarbageCollectorNames: IMPLEMENT ME!");
 
-       oa = builtin_anewarray(0, class_java_lang_String);
+       ObjectArray oa(0, class_java_lang_String);
 
-       return oa;
+       return oa.get_handle();
 }
 
 } // extern "C"
index cc431263185f5366f223875e3ac581068eef4c7a..596b3df83a79471947865036e66b7c0727768683 100644 (file)
@@ -2,6 +2,7 @@
 
    Copyright (C) 2007, 2008
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+   Copyright (C) 2009 Theobroma Systems Ltd.
 
    This file is part of CACAO.
 
         }                                                                              \
     } while (0)
 
-# define PRINTJVMWARNINGS(x)
-/*     do { \ */
-/*         if (opt_PrintJVMWarnings) { \ */
-/*             log_println x; \ */
-/*         } \ */
-/*     } while (0) */
+# define PRINTJVMWARNINGS(x)                                   \
+    do {                                                                               \
+        if (opt_PrintWarnings) {                               \
+            log_println x;                                             \
+        }                                                                              \
+    } while (0)
 
 #else
 
@@ -409,9 +410,9 @@ jint JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable)
                return 0;
        }
 
-       java_handle_bytearray_t* ba = jlt.get_backtrace();
+       ByteArray ba(jlt.get_backtrace());
 
-       if (ba == NULL)
+       if (ba.is_null())
                return 0;
 
        // We need a critical section here as the stacktrace structure is
@@ -419,7 +420,7 @@ jint JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable)
 
        LLNI_CRITICAL_START;
 
-       stacktrace_t* st = (stacktrace_t *) LLNI_array_data(ba);
+       stacktrace_t* st = (stacktrace_t *) ba.get_raw_data_ptr();
 
        int32_t depth = st->length;
 
@@ -436,11 +437,11 @@ jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
        TRACEJVMCALLS(("JVM_GetStackTraceElement(env=%p, throwable=%p, index=%d)", env, throwable, index));
 
        java_lang_Throwable jlt(throwable);
-       java_handle_bytearray_t* ba = jlt.get_backtrace();
+       ByteArray ba(jlt.get_backtrace());
 
        // XXX We need a critical section here as the stacktrace structure is
        // mapped onto a Java byte-array.
-       stacktrace_t* st = (stacktrace_t *) LLNI_array_data(ba);
+       stacktrace_t* st = (stacktrace_t *) ba.get_raw_data_ptr();
 
        return stacktrace_get_StackTraceElement(st, index);
 }
@@ -777,7 +778,7 @@ jobjectArray JVM_GetClassInterfaces(JNIEnv *env, jclass cls)
 
        oa = class_get_interfaces(c);
 
-       return (jobjectArray) oa;
+       return oa;
 }
 
 
@@ -827,14 +828,11 @@ jobjectArray JVM_GetClassSigners(JNIEnv *env, jclass cls)
 
 void JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers)
 {
-       classinfo                 *c;
-       java_handle_objectarray_t *hoa;
-
        TRACEJVMCALLS(("JVM_SetClassSigners(env=%p, cls=%p, signers=%p)", env, cls, signers));
 
-       c = LLNI_classinfo_unwrap(cls);
+       classinfo* c = LLNI_classinfo_unwrap(cls);
 
-       hoa = (java_handle_objectarray_t *) signers;
+       ObjectArray oa(signers);
 
     /* This call is ignored for primitive types and arrays.  Signers
           are only set once, ClassLoader.java, and thus shouldn't be
@@ -844,7 +842,8 @@ void JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers)
        if (class_is_primitive(c) || class_is_array(c))
                return;
 
-       LLNI_classinfo_field_set(c, signers, hoa);
+       // XXX: Fix this!
+       LLNI_classinfo_field_set(c, signers, (java_objectarray_t*) oa.get_handle());
 }
 
 
@@ -1030,7 +1029,7 @@ jobjectArray JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass)
 
        oa = class_get_declaredclasses(c, false);
 
-       return (jobjectArray) oa;
+       return oa;
 }
 
 
@@ -1179,7 +1178,7 @@ jobjectArray JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean pu
 
        oa = class_get_declaredfields(c, publicOnly);
 
-       return (jobjectArray) oa;
+       return oa;
 }
 
 
@@ -1193,7 +1192,7 @@ jobjectArray JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean p
 
        java_handle_objectarray_t* oa = class_get_declaredmethods(c, publicOnly);
 
-       return (jobjectArray) oa;
+       return oa;
 }
 
 
@@ -1210,7 +1209,7 @@ jobjectArray JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jbool
 
        oa = class_get_declaredconstructors(c, publicOnly);
 
-       return (jobjectArray) oa;
+       return oa;
 }
 
 
@@ -1623,47 +1622,43 @@ jboolean JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls)
 
 jobject JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused)
 {
-       java_handle_objectarray_t             *classes;
-       java_handle_objectarray_t             *packages;
-       java_booleanarray_t                   *classEnabled;
-       java_booleanarray_t                   *packageEnabled;
 #if defined(ENABLE_ASSERTION)
-       java_handle_t                         *js;
-       s4                                     i, j;
+       java_handle_tjs;
+       s4             i, j;
 #endif
 
        TRACEJVMCALLS(("JVM_AssertionStatusDirectives(env=%p, unused=%p)", env, unused));
 
 #if defined(ENABLE_ASSERTION)
-       classes = builtin_anewarray(assertion_class_count, class_java_lang_Object);
+       ObjectArray classes(assertion_class_count, class_java_lang_Object);
 #else
-       classes = builtin_anewarray(0, class_java_lang_Object);
+       ObjectArray classes(0, class_java_lang_Object);
 #endif
-       if (classes == NULL)
+       if (classes.is_null())
                return NULL;
 
 #if defined(ENABLE_ASSERTION)
-       packages = builtin_anewarray(assertion_package_count, class_java_lang_Object);
+       ObjectArray packages(assertion_package_count, class_java_lang_Object);
 #else
-       packages = builtin_anewarray(0, class_java_lang_Object);
+       ObjectArray packages(0, class_java_lang_Object);
 #endif
-       if (packages == NULL)
+       if (packages.is_null())
                return NULL;
        
 #if defined(ENABLE_ASSERTION)
-       classEnabled = builtin_newarray_boolean(assertion_class_count);
+       BooleanArray classEnabled(assertion_class_count);
 #else
-       classEnabled = builtin_newarray_boolean(0);
+       BooleanArray classEnabled(0);
 #endif
-       if (classEnabled == NULL)
+       if (classEnabled.is_null())
                return NULL;
 
 #if defined(ENABLE_ASSERTION)
-       packageEnabled = builtin_newarray_boolean(assertion_package_count);
+       BooleanArray packageEnabled(assertion_package_count);
 #else
-       packageEnabled = builtin_newarray_boolean(0);
+       BooleanArray packageEnabled(0);
 #endif
-       if (packageEnabled == NULL)
+       if (packageEnabled.is_null())
                return NULL;
 
 #if defined(ENABLE_ASSERTION)
@@ -1682,13 +1677,13 @@ jobject JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused)
                        }
 
                        if (item->package == false) {
-                               classes->data[i] = js;
-                               classEnabled->data[i] = (jboolean) item->enabled;
+                               classes.set_element(i, js);
+                               classEnabled.set_element(i, (jboolean) item->enabled);
                                i += 1;
                        }
                        else {
-                               packages->data[j] = js;
-                               packageEnabled->data[j] = (jboolean) item->enabled;
+                               packages.set_element(j, js);
+                               packageEnabled.set_element(j, (jboolean) item->enabled);
                                j += 1;
                        }
                }
@@ -1697,7 +1692,11 @@ jobject JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused)
 
        /* set instance fields */
 
-       java_lang_AssertionStatusDirectives jlasd(classes, classEnabled, packages, packageEnabled);
+       java_lang_AssertionStatusDirectives jlasd(
+                       classes.get_handle(),
+                       classEnabled.get_handle(),
+                       packages.get_handle(),
+                       packageEnabled.get_handle());
 
        return (jobject) jlasd.get_handle();
 }
@@ -2318,12 +2317,10 @@ jclass JVM_CurrentLoadedClass(JNIEnv *env)
 
 jobject JVM_CurrentClassLoader(JNIEnv *env)
 {
-    /* XXX if a method in a class in a trusted loader is in a
-          doPrivileged, return NULL */
+       TRACEJVMCALLS(("JVM_CurrentClassLoader(env=%p)", env));
+       PRINTJVMWARNINGS(("JVM_CurrentClassLoader is deprecated, do not use it."));
 
-       log_println("JVM_CurrentClassLoader: IMPLEMENT ME!");
-
-       return NULL;
+       return stacktrace_first_nonsystem_classloader();
 }
 
 
@@ -2333,7 +2330,7 @@ jobjectArray JVM_GetClassContext(JNIEnv *env)
 {
        TRACEJVMCALLS(("JVM_GetClassContext(env=%p)", env));
 
-       return (jobjectArray) stacktrace_getClassContext();
+       return stacktrace_getClassContext();
 }
 
 
@@ -2415,13 +2412,9 @@ jobject JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currClass, jint le
 
 jobject JVM_LatestUserDefinedLoader(JNIEnv *env)
 {
-       classloader_t *cl;
-
        TRACEJVMCALLS(("JVM_LatestUserDefinedLoader(env=%p)", env));
 
-       cl = stacktrace_first_nonnull_classloader();
-
-       return (jobject) cl;
+       return stacktrace_first_nonnull_classloader();
 }
 
 
@@ -2439,13 +2432,21 @@ jclass JVM_LoadClass0(JNIEnv *env, jobject receiver, jclass currClass, jstring c
 
 jint JVM_GetArrayLength(JNIEnv *env, jobject arr)
 {
-       java_handle_t *a;
-
        TRACEJVMCALLS(("JVM_GetArrayLength(arr=%p)", arr));
 
-       a = (java_handle_t *) arr;
+       if (arr == NULL) {
+               exceptions_throw_nullpointerexception();
+               return -1;
+       }
+
+       Array a(arr);
 
-       return array_length_get(a);
+       // Check for exception in constructor.
+       if (a.is_null()) {
+               return -1;
+       }
+
+       return a.get_length();
 }
 
 
@@ -2453,21 +2454,16 @@ jint JVM_GetArrayLength(JNIEnv *env, jobject arr)
 
 jobject JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index)
 {
-       java_handle_t *a;
-       java_handle_t *o;
-
        TRACEJVMCALLS(("JVM_GetArrayElement(env=%p, arr=%p, index=%d)", env, arr, index));
 
-       a = (java_handle_t *) arr;
+       Array a(arr);
 
 /*     if (!class_is_array(a->objheader.vftbl->class)) { */
 /*             exceptions_throw_illegalargumentexception(); */
 /*             return NULL; */
 /*     } */
 
-       o = array_element_get(a, index);
-
-       return (jobject) o;
+       return a.get_boxed_element(index);
 }
 
 
@@ -2489,15 +2485,11 @@ jvalue JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint w
 
 void JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val)
 {
-       java_handle_t *a;
-       java_handle_t *value;
-
        TRACEJVMCALLS(("JVM_SetArrayElement(env=%p, arr=%p, index=%d, val=%p)", env, arr, index, val));
 
-       a     = (java_handle_t *) arr;
-       value = (java_handle_t *) val;
+       Array a(arr);
 
-       array_element_set(a, index, value);
+       a.set_boxed_element(index, val);
 }
 
 
@@ -2513,11 +2505,6 @@ void JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v
 
 jobject JVM_NewArray(JNIEnv *env, jclass eltClass, jint length)
 {
-       classinfo                 *c;
-       classinfo                 *pc;
-       java_handle_t             *a;
-       java_handle_objectarray_t *oa;
-
        TRACEJVMCALLS(("JVM_NewArray(env=%p, eltClass=%p, length=%d)", env, eltClass, length));
 
        if (eltClass == NULL) {
@@ -2525,14 +2512,14 @@ jobject JVM_NewArray(JNIEnv *env, jclass eltClass, jint length)
                return NULL;
        }
 
-       /* NegativeArraySizeException is checked in builtin_newarray. */
+       /* NegativeArraySizeException is checked by array constructor. */
 
-       c = LLNI_classinfo_unwrap(eltClass);
+       classinfo* c = LLNI_classinfo_unwrap(eltClass);
 
        /* Create primitive or object array. */
 
        if (class_is_primitive(c)) {
-               pc = Primitive::get_arrayclass_by_name(c->name);
+               classinfo* pc = Primitive::get_arrayclass_by_name(c->name);
 
                /* void arrays are not allowed. */
 
@@ -2541,14 +2528,14 @@ jobject JVM_NewArray(JNIEnv *env, jclass eltClass, jint length)
                        return NULL;
                }
 
-               a = builtin_newarray(length, pc);
+               Array a(length, pc);
 
-               return (jobject) a;
+               return (jobject) a.get_handle();
        }
        else {
-               oa = builtin_anewarray(length, c);
+               ObjectArray oa(length, c);
 
-               return (jobject) oa;
+               return (jobject) oa.get_handle();
        }
 }
 
@@ -2558,7 +2545,6 @@ jobject JVM_NewArray(JNIEnv *env, jclass eltClass, jint length)
 jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)
 {
        classinfo                 *c;
-       java_handle_intarray_t    *ia;
        int32_t                    length;
        long                      *dims;
        int32_t                    value;
@@ -2577,17 +2563,17 @@ jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)
 
        c = LLNI_classinfo_unwrap(eltClass);
 
-       ia = (java_handle_intarray_t *) dim;
-
-       length = array_length_get((java_handle_t *) ia);
+       IntArray ia(dim);
 
        /* We check here for exceptions thrown in array_length_get,
           otherwise these exceptions get overwritten by the following
           IllegalArgumentException. */
 
-       if (length < 0)
+       if (ia.is_null())
                return NULL;
 
+       length = ia.get_length();
+
        if ((length <= 0) || (length > /* MAX_DIM */ 255)) {
                exceptions_throw_illegalargumentexception();
                return NULL;
@@ -2598,7 +2584,7 @@ jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)
        dims = MNEW(long, length);
 
        for (i = 0; i < length; i++) {
-               value = LLNI_array_direct(ia, i);
+               value = ia.get_element(i);
                dims[i] = (long) value;
        }
 
@@ -3205,9 +3191,9 @@ jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
 
        // Allocate array to hold the java.lang.Thread objects.
        int32_t length = active_threads.size();
-       java_handle_objectarray_t* oa = builtin_anewarray(length, class_java_lang_Thread);
+       ObjectArray oa(length, class_java_lang_Thread);
 
-       if (oa == NULL)
+       if (oa.is_null())
                return NULL;
 
        // Iterate over all threads (which were active just a second ago).
@@ -3218,12 +3204,12 @@ jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
                java_handle_t* h = thread_get_object(t);
                assert(h != NULL);
 
-               array_objectarray_element_set(oa, index, h);
+               oa.set_element(index, h);
 
                index++;
        }
 
-       return oa;
+       return oa.get_handle();
 }
 
 
@@ -3240,8 +3226,10 @@ jobjectArray JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threa
                return NULL;
        }
 
+       ObjectArray oa(threads);
+
        // Get length of the threads array.
-       int32_t length = array_length_get((java_handle_t*) threads);
+       int32_t length = oa.get_length();
 
        if (length <= 0) {
                exceptions_throw_illegalargumentexception();
@@ -3250,15 +3238,15 @@ jobjectArray JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threa
 
        // Allocate array to hold stacktraces.
        classinfo* arrayclass = class_array_of(class_java_lang_StackTraceElement, true);
-       java_handle_objectarray_t* oas = builtin_anewarray(length, arrayclass);
+       ObjectArray oaresult(length, arrayclass);
 
-       if (oas == NULL) {
+       if (oaresult.is_null()) {
                return NULL;
        }
 
        // Iterate over all passed thread objects.
        for (i = 0; i < length; i++) {
-               java_handle_t* thread = array_objectarray_element_get(threads, i);
+               java_handle_t* thread = oa.get_element(i);
 
                // Get thread for the given thread object.
                threadobject* t = thread_get_thread(thread);
@@ -3271,15 +3259,15 @@ jobjectArray JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threa
                stacktrace_t* st = stacktrace_get_of_thread(t);
 
                // Convert stacktrace into array of StackTraceElements.
-               java_handle_objectarray_t* oa = stacktrace_get_StackTraceElements(st);
+               java_handle_objectarray_t* oaste = stacktrace_get_StackTraceElements(st);
 
-               if (oa == NULL)
+               if (oaste == NULL)
                        return NULL;
 
-               array_objectarray_element_set(oas, i, (java_handle_t*) oa);
+               oaresult.set_element(i, oaste);
        }
 
-       return oas;
+       return oaresult.get_handle();
 }
 
 
@@ -3307,32 +3295,28 @@ jobject JVM_InitAgentProperties(JNIEnv *env, jobject properties)
 
 jobjectArray JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass ofClass)
 {
-       classinfo                 *c;
-       methodinfo                *m;
-       java_handle_objectarray_t *oa;
-
        TRACEJVMCALLS(("JVM_GetEnclosingMethodInfo(env=%p, ofClass=%p)", env, ofClass));
 
-       c = LLNI_classinfo_unwrap(ofClass);
+       classinfo* c = LLNI_classinfo_unwrap(ofClass);
 
        if ((c == NULL) || class_is_primitive(c))
                return NULL;
 
-       m = class_get_enclosingmethod_raw(c);
+       methodinfo* m = class_get_enclosingmethod_raw(c);
 
        if (m == NULL)
                return NULL;
 
-       oa = builtin_anewarray(3, class_java_lang_Object);
+       ObjectArray oa(3, class_java_lang_Object);
 
-       if (oa == NULL)
+       if (oa.is_null())
                return NULL;
 
-       array_objectarray_element_set(oa, 0, (java_handle_t *) LLNI_classinfo_wrap(m->clazz));
-       array_objectarray_element_set(oa, 1, javastring_new(m->name));
-       array_objectarray_element_set(oa, 2, javastring_new(m->descriptor));
+       oa.set_element(0, (java_handle_t *) LLNI_classinfo_wrap(m->clazz));
+       oa.set_element(1, javastring_new(m->name));
+       oa.set_element(2, javastring_new(m->descriptor));
 
-       return (jobjectArray) oa;
+       return oa.get_handle();
 }
 
 
@@ -3340,8 +3324,6 @@ jobjectArray JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass ofClass)
 
 jintArray JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState)
 {
-       java_handle_intarray_t *ia;
-
        TRACEJVMCALLS(("JVM_GetThreadStateValues(env=%p, javaThreadState=%d)",
                                  env, javaThreadState));
 
@@ -3354,69 +3336,79 @@ jintArray JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState)
 
        switch (javaThreadState) {
     case THREAD_STATE_NEW:
-               ia = builtin_newarray_int(1);
+               {
+                       IntArray ia(1);
 
-               if (ia == NULL)
-                       return NULL;
+                       if (ia.is_null())
+                               return NULL;
 
-               array_intarray_element_set(ia, 0, THREAD_STATE_NEW);
-               break; 
+                       ia.set_element(0, THREAD_STATE_NEW);
+                       return ia.get_handle();
+               }
 
     case THREAD_STATE_RUNNABLE:
-               ia = builtin_newarray_int(1);
+               {
+                       IntArray ia(1);
 
-               if (ia == NULL)
-                       return NULL;
+                       if (ia.is_null())
+                               return NULL;
 
-               array_intarray_element_set(ia, 0, THREAD_STATE_RUNNABLE);
-               break; 
+                       ia.set_element(0, THREAD_STATE_RUNNABLE);
+                       return ia.get_handle();
+               }
 
     case THREAD_STATE_BLOCKED:
-               ia = builtin_newarray_int(1);
+               {
+                       IntArray ia(1);
 
-               if (ia == NULL)
-                       return NULL;
+                       if (ia.is_null())
+                               return NULL;
 
-               array_intarray_element_set(ia, 0, THREAD_STATE_BLOCKED);
-               break; 
+                       ia.set_element(0, THREAD_STATE_BLOCKED);
+                       return ia.get_handle();
+               }
 
     case THREAD_STATE_WAITING:
-               ia = builtin_newarray_int(2);
+               {
+                       IntArray ia(2);
 
-               if (ia == NULL)
-                       return NULL;
+                       if (ia.is_null())
+                               return NULL;
 
-               array_intarray_element_set(ia, 0, THREAD_STATE_WAITING);
-               array_intarray_element_set(ia, 1, THREAD_STATE_PARKED);
-               break; 
+                       ia.set_element(0, THREAD_STATE_WAITING);
+                       ia.set_element(1, THREAD_STATE_PARKED);
+                       return ia.get_handle();
+               }
 
     case THREAD_STATE_TIMED_WAITING:
-               ia = builtin_newarray_int(2);
+               {
+                       IntArray ia(2);
 
-               if (ia == NULL)
-                       return NULL;
+                       if (ia.is_null())
+                               return NULL;
 
-               /* XXX Not sure about that one. */
-/*             array_intarray_element_set(ia, 0, SLEEPING); */
-               array_intarray_element_set(ia, 0, THREAD_STATE_TIMED_WAITING);
-               array_intarray_element_set(ia, 1, THREAD_STATE_TIMED_PARKED);
-               break; 
+                       /* XXX Not sure about that one. */
+/*                     ia.set_element(0, SLEEPING); */
+                       ia.set_element(0, THREAD_STATE_TIMED_WAITING);
+                       ia.set_element(1, THREAD_STATE_TIMED_PARKED);
+                       return ia.get_handle();
+               }
 
     case THREAD_STATE_TERMINATED:
-               ia = builtin_newarray_int(1);
+               {
+                       IntArray ia(1);
 
-               if (ia == NULL)
-                       return NULL;
+                       if (ia.is_null())
+                               return NULL;
 
-               array_intarray_element_set(ia, 0, THREAD_STATE_TERMINATED);
-               break; 
+                       ia.set_element(0, THREAD_STATE_TERMINATED);
+                       return ia.get_handle();
+               }
 
     default:
                /* Unknown state - probably incompatible JDK version */
                return NULL;
        }
-
-       return (jintArray) ia;
 }
 
 
@@ -3424,14 +3416,12 @@ jintArray JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState)
 
 jobjectArray JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArray values)
 {
-       java_handle_intarray_t    *ia;
-       java_handle_objectarray_t *oa;
-       java_object_t             *s;
+       java_object_t* s;
 
        TRACEJVMCALLS(("JVM_GetThreadStateNames(env=%p, javaThreadState=%d, values=%p)",
                                  env, javaThreadState, values));
 
-       ia = (java_handle_intarray_t *) values;
+       IntArray ia(values);
 
        /* If new thread states are added in future JDK and VM versions,
           this should check if the JDK version is compatible with thread
@@ -3447,112 +3437,122 @@ jobjectArray JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArra
 
        switch (javaThreadState) {
     case THREAD_STATE_NEW:
-               assert(ia->header.size == 1 && ia->data[0] == THREAD_STATE_NEW);
+               {
+                       assert(ia.get_length() == 1 && ia.get_element(0) == THREAD_STATE_NEW);
 
-               oa = builtin_anewarray(1, class_java_lang_String);
+                       ObjectArray oa(1, class_java_lang_String);
 
-               if (oa == NULL)
-                       return NULL;
+                       if (oa.is_null())
+                               return NULL;
 
-               s = javastring_new(utf_new_char("NEW"));
+                       s = javastring_new(utf_new_char("NEW"));
 
-               if (s == NULL)
-                       return NULL;
+                       if (s == NULL)
+                               return NULL;
 
-               array_objectarray_element_set(oa, 0, s);
-               break; 
+                       oa.set_element(0, s);
+                       return oa.get_handle();
+               }
 
     case THREAD_STATE_RUNNABLE:
-               oa = builtin_anewarray(1, class_java_lang_String);
+               {
+                       ObjectArray oa(1, class_java_lang_String);
 
-               if (oa == NULL)
-                       return NULL;
+                       if (oa.is_null())
+                               return NULL;
 
-               s = javastring_new(utf_new_char("RUNNABLE"));
+                       s = javastring_new(utf_new_char("RUNNABLE"));
 
-               if (s == NULL)
-                       return NULL;
+                       if (s == NULL)
+                               return NULL;
 
-               array_objectarray_element_set(oa, 0, s);
-               break; 
+                       oa.set_element(0, s);
+                       return oa.get_handle();
+               }
 
     case THREAD_STATE_BLOCKED:
-               oa = builtin_anewarray(1, class_java_lang_String);
+               {
+                       ObjectArray oa(1, class_java_lang_String);
 
-               if (oa == NULL)
-                       return NULL;
+                       if (oa.is_null())
+                               return NULL;
 
-               s = javastring_new(utf_new_char("BLOCKED"));
+                       s = javastring_new(utf_new_char("BLOCKED"));
 
-               if (s == NULL)
-                       return NULL;
+                       if (s == NULL)
+                               return NULL;
 
-               array_objectarray_element_set(oa, 0, s);
-               break; 
+                       oa.set_element(0, s);
+                       return oa.get_handle();
+               }
 
     case THREAD_STATE_WAITING:
-               oa = builtin_anewarray(2, class_java_lang_String);
+               {
+                       ObjectArray oa(2, class_java_lang_String);
 
-               if (oa == NULL)
-                       return NULL;
+                       if (oa.is_null())
+                               return NULL;
 
-               s = javastring_new(utf_new_char("WAITING.OBJECT_WAIT"));
+                       s = javastring_new(utf_new_char("WAITING.OBJECT_WAIT"));
 
-               if (s == NULL)
-                       return NULL;
+                       if (s == NULL)
+                               return NULL;
 
-               array_objectarray_element_set(oa, 0, s);
+                       oa.set_element(0, s);
 
-               s = javastring_new(utf_new_char("WAITING.PARKED"));
+                       s = javastring_new(utf_new_char("WAITING.PARKED"));
 
-               if (s == NULL)
-                       return NULL;
+                       if (s == NULL)
+                               return NULL;
 
-               array_objectarray_element_set(oa, 1, s);
-               break; 
+                       oa.set_element(1, s);
+                       return oa.get_handle();
+               }
 
     case THREAD_STATE_TIMED_WAITING:
-               oa = builtin_anewarray(2, class_java_lang_String);
+               {
+                       ObjectArray oa(2, class_java_lang_String);
 
-               if (oa == NULL)
-                       return NULL;
+                       if (oa.is_null())
+                               return NULL;
 
-/*             s = javastring_new(utf_new_char("TIMED_WAITING.SLEEPING")); */
-               s = javastring_new(utf_new_char("TIMED_WAITING.OBJECT_WAIT"));
+/*                     s = javastring_new(utf_new_char("TIMED_WAITING.SLEEPING")); */
+                       s = javastring_new(utf_new_char("TIMED_WAITING.OBJECT_WAIT"));
 
-               if (s == NULL)
-                       return NULL;
+                       if (s == NULL)
+                               return NULL;
 
-               array_objectarray_element_set(oa, 0, s);
+                       oa.set_element(0, s);
 
-               s = javastring_new(utf_new_char("TIMED_WAITING.PARKED"));
+                       s = javastring_new(utf_new_char("TIMED_WAITING.PARKED"));
 
-               if (s == NULL)
-                       return NULL;
+                       if (s == NULL)
+                               return NULL;
 
-               array_objectarray_element_set(oa, 1, s);
-               break; 
+                       oa.set_element(1, s);
+                       return oa.get_handle();
+               }
 
     case THREAD_STATE_TERMINATED:
-               oa = builtin_anewarray(1, class_java_lang_String);
+               {
+                       ObjectArray oa(1, class_java_lang_String);
 
-               if (oa == NULL)
-                       return NULL;
+                       if (oa.is_null())
+                               return NULL;
 
-               s = javastring_new(utf_new_char("TERMINATED"));
+                       s = javastring_new(utf_new_char("TERMINATED"));
 
-               if (s == NULL)
-                       return NULL;
+                       if (s == NULL)
+                               return NULL;
 
-               array_objectarray_element_set(oa, 0, s);
-               break; 
+                       oa.set_element(0, s);
+                       return oa.get_handle();
+               }
 
        default:
                /* Unknown state - probably incompatible JDK version */
                return NULL;
        }
-
-       return (jobjectArray) oa;
 }
 
 
index 73a8545b8afef1b164d7e7987378f5782e0b7db4..0cc2d414450078414f4fb678b926fa4a792300f5 100644 (file)
@@ -37,6 +37,7 @@
 #include "native/vm/reflection.hpp"
 
 #include "vm/access.hpp"
+#include "vm/array.hpp"
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
@@ -85,8 +86,10 @@ java_handle_t* Reflection::invoke(methodinfo *m, java_handle_t *o, java_handle_o
 
        /* check if we got the right number of arguments */
 
+       ObjectArray oa(params);
+
        if (((params == NULL) && (paramcount != 0)) ||
-               (params && (LLNI_array_size(params) != paramcount))) 
+               (params && (oa.get_length() != paramcount))) 
        {
                exceptions_throw_illegalargumentexception();
                return NULL;
index 63ec0c201708bb0a05f8e4476438cedf444b0a81..bcbfe0feceb955cc6b29e16bf83e8e49f34a5f0d 100644 (file)
@@ -40,6 +40,7 @@
 # include "native/include/sun_misc_Unsafe.h"
 #endif
 
+#include "vm/array.hpp"
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/initialize.hpp"
@@ -825,7 +826,9 @@ JNIEXPORT jclass JNICALL Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3
 
        /* check the indexes passed */
 
-       if ((off < 0) || (len < 0) || ((off + len) > LLNI_array_size(b))) {
+       ByteArray ba(b);
+
+       if ((off < 0) || (len < 0) || ((off + len) > ba.get_length())) {
                exceptions_throw_arrayindexoutofboundsexception();
                return NULL;
        }
@@ -841,7 +844,8 @@ JNIEXPORT jclass JNICALL Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3
 
        /* define the class */
 
-       c = class_define(utfname, cl, len, (uint8_t *) &(LLNI_array_direct((java_handle_bytearray_t*) b, off)),
+       uint8_t* ptr = ((uint8_t*) ba.get_raw_data_ptr()) + off;
+       c = class_define(utfname, cl, len, ptr,
                                         (java_handle_t *) protectionDomain);
 
        if (c == NULL)
index 2a5fafdffb81dc6a4e83808f8efb8c48c3c50200..7e930ab053a681084f821774eaaf36e1667cbc48 100644 (file)
 static java_handle_objectarray_t *annotation_bytearrays_resize(
        java_handle_objectarray_t *bytearrays, uint32_t size)
 {
-       java_handle_objectarray_t *newbas = NULL; /* new array     */
        uint32_t minsize = 0;      /* count of object refs to copy */
        uint32_t oldsize = 0;      /* size of old array            */
 
+       ObjectArray bas(bytearrays);
+
        if (bytearrays != NULL) {
-               oldsize = array_length_get((java_handle_t*)bytearrays);
+               oldsize = bas.get_length();
                
                /* if the size already fits do nothing */
                if (size == oldsize) {
                        return bytearrays;
                }
        }
-       
-       newbas = builtin_anewarray(size,
+
+       // Allocate new array on the heap.
+
+       ObjectArray newbas(size,
                Primitive::get_arrayclass_by_type(PRIMITIVETYPE_BYTE));
-       
+
        /* is there a old byte array array? */
-       if (newbas != NULL && bytearrays != NULL) {
+       if (newbas.is_non_null() && bytearrays != NULL) {
                minsize = size < oldsize ? size : oldsize;
 
                LLNI_CRITICAL_START;
                MCOPY(
-                       LLNI_array_data(newbas), LLNI_array_data(bytearrays),
+                       newbas.get_raw_data_ptr(), bas.get_raw_data_ptr(),
                        java_object_t*, minsize);
                LLNI_CRITICAL_END;
        }
 
-       return newbas;
+       return newbas.get_handle();
 }
 
 
@@ -118,7 +121,6 @@ static java_handle_t *annotation_bytearrays_insert(
        java_handle_t *bytearrays, uint32_t index,
        java_handle_bytearray_t *bytearray)
 {
-       java_handle_objectarray_t *bas; /* bytearrays                */
        uint32_t size = 0;              /* current size of the array */
 
        /* do nothing if NULL is inserted but no array exists */
@@ -126,34 +128,35 @@ static java_handle_t *annotation_bytearrays_insert(
                return NULL;
        }
 
+       ObjectArray bas(bytearrays);
+
        /* get lengths if array exists */
        if (bytearrays != NULL) {
-               size = array_length_get(bytearrays);
+               size = bas.get_length();
        }
 
-       bas = (java_handle_objectarray_t*)bytearrays;
-
        if (bytearray == NULL) {
                /* insert NULL only if array is big enough */
                if (size > index) {
-                       array_objectarray_element_set(bas, index, NULL);
+                       bas.set_element(index, NULL);
                }
        }
        else {
+               // XXX: We should use a clone function here!!!
                /* resize array if it's not enough for inserted value */
                if (size <= index) {
-                       bas = annotation_bytearrays_resize(bas, index + 1);
+                       bas = annotation_bytearrays_resize(bas.get_handle(), index + 1);
 
-                       if (bas == NULL) {
+                       if (bas.is_null()) {
                                /* out of memory */
                                return NULL;
                        }
                }
 
-               array_objectarray_element_set(bas, index, (java_handle_t*)bytearray);
+               bas.set_element(index, (java_handle_t*) bytearray);
        }
        
-       return (java_handle_t*)bas;
+       return bas.get_handle();
 }
 
 
@@ -186,7 +189,6 @@ static bool annotation_load_attribute_body(classbuffer *cb,
        java_handle_bytearray_t **attribute, const char *errormsg_prefix)
 {
        uint32_t                 size = 0;    /* size of the attribute     */
-       java_handle_bytearray_t *ba   = NULL; /* the raw attributes' bytes */
 
        assert(cb != NULL);
        assert(attribute != NULL);
@@ -207,9 +209,9 @@ static bool annotation_load_attribute_body(classbuffer *cb,
        /* if attribute_length == 0 then NULL is
         * the right value for this attribute */
        if (size > 0) {
-               ba = builtin_newarray_byte(size);
+               ByteArray ba(size);
 
-               if (ba == NULL) {
+               if (ba.is_null()) {
                        /* out of memory */
                        return false;
                }
@@ -217,12 +219,13 @@ static bool annotation_load_attribute_body(classbuffer *cb,
                /* load data */
                LLNI_CRITICAL_START;
 
-               suck_nbytes((uint8_t*)LLNI_array_data(ba), cb, size);
+               uint8_t* ptr = (uint8_t*) ba.get_raw_data_ptr();
+               suck_nbytes(ptr, cb, size);
 
                LLNI_CRITICAL_END;
 
                /* return data */
-               *attribute = ba;
+               *attribute = ba.get_handle();
        }
        
        return true;
index de602db1490a4a2d2d59021fe12d3a4068c4387f..560c400f8117ffde6fd1015cfba35cde3c0fd706 100644 (file)
@@ -2,6 +2,7 @@
 
    Copyright (C) 2007
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+   Copyright (C) 2008 Theobroma Systems Ltd.
 
    This file is part of CACAO.
 
 #include "vm/array.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
+#include "vm/globals.hpp"
 #include "vm/primitive.hpp"
 #include "vm/vm.hpp"
 
 
-/* array_element_get ***********************************************************
-
-   Returns a boxed element of the given Java array.
-
-*******************************************************************************/
-
-java_handle_t *array_element_get(java_handle_t *a, int32_t index)
+/**
+ * Returns a boxed element of the given Java array.
+ */
+java_handle_t* Array::get_boxed_element(int32_t index)
 {
        vftbl_t       *v;
        int            type;
        imm_union      value;
        java_handle_t *o;
 
-       if (a == NULL) {
+       if (is_null()) {
                exceptions_throw_nullpointerexception();
                return NULL;
        }
 
-       v = LLNI_vftbl_direct(a);
+       v = LLNI_vftbl_direct(_handle);
 
        type = v->arraydesc->arraytype;
 
-       value = array_element_primitive_get(a, index);
+       value = get_primitive_element(index);
 
        o = Primitive::box(type, value);
 
@@ -66,82 +65,120 @@ java_handle_t *array_element_get(java_handle_t *a, int32_t index)
 }
 
 
-/* array_element_set ***********************************************************
-
-   Sets a boxed element in the given Java array.
-
-*******************************************************************************/
-
-void array_element_set(java_handle_t *a, int32_t index, java_handle_t *o)
+/**
+ * Sets a boxed element in the given Java array.
+ */
+void Array::set_boxed_element(int32_t index, java_handle_t *o)
 {
+       vftbl_t  *v;
+       int       type;
        imm_union value;
 
-       value = Primitive::unbox(o);
+       if (is_null()) {
+               exceptions_throw_nullpointerexception();
+               return;
+       }
 
-       array_element_primitive_set(a, index, value);
-}
+       v = LLNI_vftbl_direct(_handle);
 
+       type = v->arraydesc->arraytype;
 
-/* array_element_primitive_get *************************************************
+       // Special handling for object arrays.
+       if (type == ARRAYTYPE_OBJECT) {
+               ObjectArray array(_handle);
+               array.set_element(index, o);
+               return;
+       }
 
-   Returns a primitive element of the given Java array.
+       // Check if primitive type can be stored.
+       if (!Primitive::unbox_typed(o, type, &value)) {
+/*             exceptions_throw_illegalargumentexception("argument type mismatch"); */
+               exceptions_throw_illegalargumentexception();
+               return;
+       }
+
+       set_primitive_element(index, value);
+}
 
-*******************************************************************************/
 
-imm_union array_element_primitive_get(java_handle_t *a, int32_t index)
+/**
+ * Returns a primitive element of the given Java array.
+ */
+imm_union Array::get_primitive_element(int32_t index)
 {
        vftbl_t  *v;
        int       type;
        imm_union value;
 
-       if (a == NULL) {
+       if (is_null()) {
                exceptions_throw_nullpointerexception();
                value.a = NULL;
                return value;
        }
 
+       java_handle_array_t* a = _handle;
+
        v = LLNI_vftbl_direct(a);
 
        type = v->arraydesc->arraytype;
 
        switch (type) {
        case ARRAYTYPE_BOOLEAN:
-               value.i = array_booleanarray_element_get((java_handle_booleanarray_t *) a, index);
+               {
+                       BooleanArray array(a);
+                       value.i = array.get_element(index);
+               }
                break;
        case ARRAYTYPE_BYTE:
-               value.i = array_bytearray_element_get((java_handle_bytearray_t *) a,
-                                                                                         index);
+               {
+                       ByteArray array(a);
+                       value.i = array.get_element(index);
+               }
                break;
        case ARRAYTYPE_CHAR:
-               value.i = array_chararray_element_get((java_handle_chararray_t *) a,
-                                                                                         index);
+               {
+                       CharArray array(a);
+                       value.i = array.get_element(index);
+               }
                break;
        case ARRAYTYPE_SHORT:
-               value.i = array_shortarray_element_get((java_handle_shortarray_t *) a,
-                                                                                          index);
+               {
+                       ShortArray array(a);
+                       value.i = array.get_element(index);
+               }
                break;
        case ARRAYTYPE_INT:
-               value.i = array_intarray_element_get((java_handle_intarray_t *) a,
-                                                                                        index);
+               {
+                       IntArray array(a);
+                       value.i = array.get_element(index);
+               }
                break;
        case ARRAYTYPE_LONG:
-               value.l = array_longarray_element_get((java_handle_longarray_t *) a,
-                                                                                         index);
+               {
+                       LongArray array(a);
+                       value.l = array.get_element(index);
+               }
                break;
        case ARRAYTYPE_FLOAT:
-               value.f = array_floatarray_element_get((java_handle_floatarray_t *) a,
-                                                                                          index);
+               {
+                       FloatArray array(a);
+                       value.f = array.get_element(index);
+               }
                break;
        case ARRAYTYPE_DOUBLE:
-               value.d = array_doublearray_element_get((java_handle_doublearray_t *) a,
-                                                                                               index);
+               {
+                       DoubleArray array(a);
+                       value.d = array.get_element(index);
+               }
                break;
        case ARRAYTYPE_OBJECT:
-               value.a = array_objectarray_element_get((java_handle_objectarray_t *) a,
-                                                                                               index);
+               {
+                       ObjectArray array(a);
+                       value.a = array.get_element(index);
+               }
                break;
        default:
-               vm_abort("array_element_primitive_get: invalid array element type %d",
+               vm_abort("Array::primitive_element_get: invalid array element type %d",
                                 type);
        }
 
@@ -149,62 +186,79 @@ imm_union array_element_primitive_get(java_handle_t *a, int32_t index)
 }
 
 
-/* array_element_primitive_set *************************************************
-
-   Sets a primitive element in the given Java array.
-
-*******************************************************************************/
-
-void array_element_primitive_set(java_handle_t *a, int32_t index, imm_union value)
+/**
+ * Sets a primitive element in the given Java array.
+ */
+void Array::set_primitive_element(int32_t index, imm_union value)
 {
        vftbl_t *v;
        int      type;
 
-       if (a == NULL) {
+       if (is_null()) {
                exceptions_throw_nullpointerexception();
                return;
        }
 
+       java_handle_array_t* a = _handle;
+
        v = LLNI_vftbl_direct(a);
 
        type = v->arraydesc->arraytype;
 
        switch (type) {
        case ARRAYTYPE_BOOLEAN:
-               array_booleanarray_element_set((java_handle_booleanarray_t *) a,
-                                                                          index, value.i);
+               {
+                       BooleanArray array(a);
+                       array.set_element(index, value.i);
+               }
                break;
        case ARRAYTYPE_BYTE:
-               array_bytearray_element_set((java_handle_bytearray_t *) a,
-                                                                       index, value.i);
+               {
+                       ByteArray array(a);
+                       array.set_element(index, value.i);
+               }
                break;
        case ARRAYTYPE_CHAR:
-               array_chararray_element_set((java_handle_chararray_t *) a,
-                                                                       index, value.i);
+               {
+                       CharArray array(a);
+                       array.set_element(index, value.i);
+               }
                break;
        case ARRAYTYPE_SHORT:
-               array_shortarray_element_set((java_handle_shortarray_t *) a,
-                                                                        index, value.i);
+               {
+                       ShortArray array(a);
+                       array.set_element(index, value.i);
+               }
                break;
        case ARRAYTYPE_INT:
-               array_intarray_element_set((java_handle_intarray_t *) a,
-                                                                  index, value.i);
+               {
+                       IntArray array(a);
+                       array.set_element(index, value.i);
+               }
                break;
        case ARRAYTYPE_LONG:
-               array_longarray_element_set((java_handle_longarray_t *) a,
-                                                                       index, value.l);
+               {
+                       LongArray array(a);
+                       array.set_element(index, value.l);
+               }
                break;
        case ARRAYTYPE_FLOAT:
-               array_floatarray_element_set((java_handle_floatarray_t *) a,
-                                                                        index, value.f);
+               {
+                       FloatArray array(a);
+                       array.set_element(index, value.f);
+               }
                break;
        case ARRAYTYPE_DOUBLE:
-               array_doublearray_element_set((java_handle_doublearray_t *) a,
-                                                                         index, value.d);
+               {
+                       DoubleArray array(a);
+                       array.set_element(index, value.d);
+               }
                break;
        case ARRAYTYPE_OBJECT:
-               array_objectarray_element_set((java_handle_objectarray_t *) a,
-                                                                         index, static_cast<java_handle_t*>(value.a));
+               {
+                       ObjectArray array(a);
+                       array.set_element(index, static_cast<java_handle_t*>(value.a));
+               }
                break;
        default:
                vm_abort("array_element_primitive_set: invalid array element type %d",
@@ -213,171 +267,48 @@ void array_element_primitive_set(java_handle_t *a, int32_t index, imm_union valu
 }
 
 
-/* array_xxxarray_element_get **************************************************
-
-   Returns a primitive element of the given Java array.
-
-*******************************************************************************/
-
-#define ARRAY_TYPEARRAY_ELEMENT_GET(name, type)                                \
-type array_##name##array_element_get(java_handle_##name##array_t *a, int32_t index) \
-{                                                                              \
-       type    value;                                                             \
-       int32_t size;                                                              \
-                                                                               \
-       if (a == NULL) {                                                           \
-               exceptions_throw_nullpointerexception();                               \
-               return (type) 0;                                                       \
-       }                                                                          \
-                                                                               \
-       size = LLNI_array_size(a);                                                 \
-                                                                               \
-       if ((index < 0) || (index >= size)) {                                      \
-               exceptions_throw_arrayindexoutofboundsexception();                     \
-               return (type) 0;                                                       \
-       }                                                                          \
-                                                                               \
-       value = LLNI_array_direct(a, index);                                       \
-                                                                               \
-       return value;                                                              \
-}
-
-java_handle_t *array_objectarray_element_get(java_handle_objectarray_t *a, int32_t index)
-{
-       java_handle_t *value;
-       int32_t size;
-
-       if (a == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       size = LLNI_array_size(a);
-
-       if ((index < 0) || (index >= size)) {
-               exceptions_throw_arrayindexoutofboundsexception();
-               return NULL;
-       }
-
-       LLNI_CRITICAL_START;
-       value = LLNI_WRAP(LLNI_array_direct(a, index));
-       LLNI_CRITICAL_END;
-
-       return value;
-}
-
-ARRAY_TYPEARRAY_ELEMENT_GET(boolean, uint8_t)
-ARRAY_TYPEARRAY_ELEMENT_GET(byte,    int8_t)
-ARRAY_TYPEARRAY_ELEMENT_GET(char,    uint16_t)
-ARRAY_TYPEARRAY_ELEMENT_GET(short,   int16_t)
-ARRAY_TYPEARRAY_ELEMENT_GET(int,     int32_t)
-ARRAY_TYPEARRAY_ELEMENT_GET(long,    int64_t)
-ARRAY_TYPEARRAY_ELEMENT_GET(float,   float)
-ARRAY_TYPEARRAY_ELEMENT_GET(double,  double)
-
-
-/* array_xxxarray_element_set **************************************************
-
-   Sets a primitive element in the given Java array.
-
-*******************************************************************************/
-
-#define ARRAY_TYPEARRAY_ELEMENT_SET(name, type)                                \
-void array_##name##array_element_set(java_handle_##name##array_t *a, int32_t index, type value) \
-{                                                                              \
-       int32_t size;                                                              \
-                                                                               \
-       if (a == NULL) {                                                           \
-               exceptions_throw_nullpointerexception();                               \
-               return;                                                                \
-       }                                                                          \
-                                                                               \
-       size = LLNI_array_size(a);                                                 \
-                                                                               \
-       if ((index < 0) || (index >= size)) {                                      \
-               exceptions_throw_arrayindexoutofboundsexception();                     \
-               return;                                                                \
-       }                                                                          \
-                                                                               \
-       LLNI_array_direct(a, index) = value;                                       \
-}
-
-void array_objectarray_element_set(java_handle_objectarray_t *a, int32_t index, java_handle_t *value)
+/**
+ * Creates an array of references to the given class type on the heap.
+ * The handle pointer to the array can be NULL in case of an exception.
+ */
+ObjectArray::ObjectArray(int32_t length, classinfo* componentclass)
+               : ArrayTemplate<java_handle_t*>(NULL)
 {
-       int32_t size;
+       // Is class loaded?
+       assert(componentclass->state & CLASS_LOADED);
 
-       if (a == NULL) {
-               exceptions_throw_nullpointerexception();
-               return;
-       }
-
-       /* Sanity check. */
-
-       assert(a->header.objheader.vftbl->arraydesc->arraytype == ARRAYTYPE_OBJECT);
-
-       if (value != NULL) {
-               if (builtin_canstore(a, value) == false) {
-                       exceptions_throw_illegalargumentexception();
+       // Is class linked?
+       if (!(componentclass->state & CLASS_LINKED))
+               if (!link_class(componentclass)) {
+                       _handle = NULL;
                        return;
                }
-       }
 
-       size = LLNI_array_size(a);
+       classinfo* arrayclass = class_array_of(componentclass, true);
 
-       if ((index < 0) || (index >= size)) {
-               exceptions_throw_arrayindexoutofboundsexception();
+       if (arrayclass == NULL) {
+               _handle = NULL;
                return;
        }
 
-       LLNI_CRITICAL_START;
-       LLNI_array_direct(a, index) = LLNI_UNWRAP(value);
-       LLNI_CRITICAL_END;
-}
-
-ARRAY_TYPEARRAY_ELEMENT_SET(boolean, uint8_t)
-ARRAY_TYPEARRAY_ELEMENT_SET(byte,    int8_t)
-ARRAY_TYPEARRAY_ELEMENT_SET(char,    uint16_t)
-ARRAY_TYPEARRAY_ELEMENT_SET(short,   int16_t)
-ARRAY_TYPEARRAY_ELEMENT_SET(int,     int32_t)
-ARRAY_TYPEARRAY_ELEMENT_SET(long,    int64_t)
-ARRAY_TYPEARRAY_ELEMENT_SET(float,   float)
-ARRAY_TYPEARRAY_ELEMENT_SET(double,  double)
-
-
-/* array_length_get ***********************************************************
-
-   Returns a the length of the given Java array.
+       // Delegate allocation to generic array class
+       Array a(length, arrayclass);
 
-   ARGUMENTS:
-       a ... Java array
-
-   RETURN VALUE:
-         -1 ... exception thrown
-          >= 0 ... length of the Java array
+       _handle = a.get_handle();
+}
 
-*******************************************************************************/
 
-int32_t array_length_get(java_handle_t *a)
+/**
+ * Creates an array of references to classinfos on the heap.
+ * The handle pointer to the array can be NULL in case of an exception.
+ */
+ClassArray::ClassArray(int32_t length)
+               : ArrayTemplate<classinfo*>(NULL)
 {
-       classinfo *c;
-       int32_t    size;
-
-       if (a == NULL) {
-               exceptions_throw_nullpointerexception();
-               return -1;
-       }
-
-       LLNI_class_get(a, c);
-
-       if (!class_is_array(c)) {
-/*             exceptions_throw_illegalargumentexception("Argument is not an array"); */
-               exceptions_throw_illegalargumentexception();
-               return -1;
-       }
-
-       size = LLNI_array_size(a);
+       // Delegate allocation to object array class
+       ObjectArray oa(length, class_java_lang_Class);
 
-       return size;
+       _handle = oa.get_handle();
 }
 
 
index 86f10843b0577087540bd676724f1af76e020742..ced1ab3a75151b1360128ea24e85f3f80af7ef3a 100644 (file)
@@ -2,6 +2,7 @@
 
    Copyright (C) 2007
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+   Copyright (C) 2008 Theobroma Systems Ltd.
 
    This file is part of CACAO.
 
 
 #include <stdint.h>
 
+#include "mm/gc.hpp" // XXX Remove me!
+
+#include "native/llni.h" // XXX Remove me!
+
+#include "vm/class.hpp"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/primitive.hpp"
 
 #define ARRAYTYPE_OBJECT      PRIMITIVETYPE_VOID     /* don't use as index! */
 
 
-/* function prototypes ********************************************************/
-
 #ifdef __cplusplus
-extern "C" {
+
+/**
+ * This is a generic accessor class for Java arrays (of unspecified type),
+ * which can be used to safely operate on Java arrays in native code.
+ */
+class Array {
+protected:
+       // Handle of Java array.
+       java_handle_array_t* _handle;
+
+private:
+       // We don't want a Java arrays to be copied.
+       Array(Array* a) {}
+       Array(Array& a) {}
+
+public:
+       Array(java_handle_t* h);
+       Array(int32_t length, classinfo* arrayclass);
+       virtual ~Array() {}
+
+       // Getters.
+       virtual java_handle_array_t* get_handle() const { return _handle; }
+       int32_t                      get_length() const;
+
+       // Null checks.
+       bool is_null    () const;
+       bool is_non_null() const;
+
+       // Safe element modification functions for primitive values
+       imm_union get_primitive_element(int32_t index);
+       void      set_primitive_element(int32_t index, imm_union value);
+
+       // Safe element modification functions for boxed values
+       java_handle_t* get_boxed_element(int32_t index);
+       void           set_boxed_element(int32_t index, java_handle_t *o);
+};
+
+
+/**
+ * Constructor checks if passed handle really is a Java array.
+ */
+inline Array::Array(java_handle_t* h)
+{
+       if (h == NULL) {
+               _handle = NULL;
+               return;
+       }
+
+#if 0
+       classinfo* c;
+       LLNI_class_get(h, c);
+       if (!class_is_array(c)) {
+               printf("Array::Array(): WARNING, passed handle is not an array\n");
+               //exceptions_throw_illegalargumentexception("Argument is not an array");
+               exceptions_throw_illegalargumentexception();
+               _handle = NULL;
+               return;
+       }
 #endif
 
-java_handle_t *array_element_get(java_handle_t *a, int32_t index);
-void           array_element_set(java_handle_t *a, int32_t index, java_handle_t *o);
-
-imm_union      array_element_primitive_get(java_handle_t *a, int32_t index);
-void           array_element_primitive_set(java_handle_t *a, int32_t index, imm_union value);
-
-uint8_t        array_booleanarray_element_get(java_handle_booleanarray_t *a, int32_t index);
-int8_t         array_bytearray_element_get(java_handle_bytearray_t *a, int32_t index);
-uint16_t       array_chararray_element_get(java_handle_chararray_t *a, int32_t index);
-int16_t        array_shortarray_element_get(java_handle_shortarray_t *a, int32_t index);
-int32_t        array_intarray_element_get(java_handle_intarray_t *a, int32_t index);
-int64_t        array_longarray_element_get(java_handle_longarray_t *a, int32_t index);
-float          array_floatarray_element_get(java_handle_floatarray_t *a, int32_t index);
-double         array_doublearray_element_get(java_handle_doublearray_t *a, int32_t index);
-java_handle_t *array_objectarray_element_get(java_handle_objectarray_t *a, int32_t index);
-
-void           array_booleanarray_element_set(java_handle_booleanarray_t *a, int32_t index, uint8_t value);
-void           array_bytearray_element_set(java_handle_bytearray_t *a, int32_t index, int8_t value);
-void           array_chararray_element_set(java_handle_chararray_t *a, int32_t index, uint16_t value);
-void           array_shortarray_element_set(java_handle_shortarray_t *a, int32_t index, int16_t value);
-void           array_intarray_element_set(java_handle_intarray_t *a, int32_t index, int32_t value);
-void           array_longarray_element_set(java_handle_longarray_t *a, int32_t index, int64_t value);
-void           array_floatarray_element_set(java_handle_floatarray_t *a, int32_t index, float value);
-void           array_doublearray_element_set(java_handle_doublearray_t *a, int32_t index, double value);
-void           array_objectarray_element_set(java_handle_objectarray_t *a, int32_t index, java_handle_t *value);
-
-int32_t        array_length_get(java_handle_t *a);
+       _handle = h;
+}
 
-#ifdef __cplusplus
-} // extern "C"
+/**
+ * Creates an array of the given array type on the heap.
+ * The handle pointer to the array can be NULL in case of an exception.
+ */
+inline Array::Array(int32_t size, classinfo* arrayclass)
+{
+       // Sanity check.
+       assert(class_is_array(arrayclass));
+
+       if (size < 0) {
+               exceptions_throw_negativearraysizeexception();
+               _handle = NULL;
+               return;
+       }
+
+       arraydescriptor* desc          = arrayclass->vftbl->arraydesc;
+       int32_t          dataoffset    = desc->dataoffset;
+       int32_t          componentsize = desc->componentsize;
+       int32_t          actualsize    = dataoffset + size * componentsize;
+
+       // Check for overflow.
+
+       if (((u4) actualsize) < ((u4) size)) {
+               exceptions_throw_outofmemoryerror();
+               _handle = NULL;
+               return;
+       }
+
+       java_array_t* a = (java_array_t*) heap_alloc(actualsize, (desc->arraytype == ARRAYTYPE_OBJECT), NULL, true);
+
+       if (a == NULL) {
+               _handle = NULL;
+               return;
+       }
+
+       LLNI_vftbl_direct(a) = arrayclass->vftbl;
+
+#if defined(ENABLE_THREADS)
+       a->objheader.lockword.init();
+#endif
+
+       a->size = size;
+
+       _handle = (java_handle_array_t*) a;
+}
+
+inline int32_t Array::get_length() const
+{
+       if (is_null()) {
+               printf("Array::get_length(): WARNING, got null-pointer\n");
+               exceptions_throw_nullpointerexception();
+               return -1;
+       }
+
+       // XXX Fix me!
+       int32_t length = ((java_array_t*) _handle)->size;
+
+       return length;
+}
+
+inline bool Array::is_null() const
+{
+       return (_handle == NULL);
+}
+
+inline bool Array::is_non_null() const
+{
+       return (_handle != NULL);
+}
+
+
+/**
+ * This is a template of an accessor class for Java arrays
+ * of a specific type.
+ */
+template<class T> class ArrayTemplate : public Array {
+protected:
+       ArrayTemplate(int32_t length, classinfo* arrayclass) : Array(length, arrayclass) {}
+
+public:
+       ArrayTemplate(java_handle_array_t* h) : Array(h) {}
+
+       // XXX This should be protected or private!
+       virtual T* get_raw_data_ptr() = 0;
+
+       // Safe element modification functions
+       T    get_element(int32_t index);
+       void set_element(int32_t index, T value);
+
+       // Region copy functions
+       void get_region(int32_t offset, int32_t count, T* buffer);
+       void set_region(int32_t offset, int32_t count, const T* buffer);
+};
+
+
+template<class T> inline T ArrayTemplate<T>::get_element(int32_t index)
+{
+       if (is_null()) {
+               exceptions_throw_nullpointerexception();
+               return 0;
+       }
+
+       if ((index < 0) || (index >= get_length())) {
+               exceptions_throw_arrayindexoutofboundsexception();
+               return 0;
+       }
+
+       T* ptr = get_raw_data_ptr();
+
+       return ptr[index];
+}
+
+template<class T> inline void ArrayTemplate<T>::set_element(int32_t index, T value)
+{
+       if (is_null()) {
+               exceptions_throw_nullpointerexception();
+               return;
+       }
+
+       if ((index < 0) || (index >= get_length())) {
+               exceptions_throw_arrayindexoutofboundsexception();
+               return;
+       }
+
+       T* ptr = get_raw_data_ptr();
+
+       ptr[index] = value;
+}
+
+template<> inline void ArrayTemplate<java_handle_t*>::set_element(int32_t index, java_handle_t* value)
+{
+       if (is_null()) {
+               exceptions_throw_nullpointerexception();
+               return;
+       }
+
+       // Sanity check.
+       assert(((java_array_t*) get_handle())->objheader.vftbl->arraydesc->arraytype == ARRAYTYPE_OBJECT);
+
+       // Check if value can be stored
+       if (!builtin_canstore(get_handle(), value)) {
+               exceptions_throw_illegalargumentexception();
+               return;
+       }
+
+       if ((index < 0) || (index >= get_length())) {
+               exceptions_throw_arrayindexoutofboundsexception();
+               return;
+       }
+
+       java_handle_t** ptr = get_raw_data_ptr();
+
+       ptr[index] = value;
+}
+
+template<class T> inline void ArrayTemplate<T>::get_region(int32_t offset, int32_t count, T* buffer)
+{
+       // Copy the array region inside a GC critical section.
+       GCCriticalSection cs;
+
+       const T* ptr = get_raw_data_ptr();
+
+       os::memcpy(buffer, ptr + offset, sizeof(T) * count);
+}
+
+template<class T> inline void ArrayTemplate<T>::set_region(int32_t offset, int32_t count, const T* buffer)
+{
+       // Copy the array region inside a GC critical section.
+       GCCriticalSection cs;
+
+       T* ptr = get_raw_data_ptr();
+
+       os::memcpy(ptr + offset, buffer, sizeof(T) * count);
+}
+
+
+/**
+ * Actual implementations of common Java array access classes.
+ */
+class BooleanArray : public ArrayTemplate<uint8_t> {
+public:
+       BooleanArray(java_handle_booleanarray_t* h) : ArrayTemplate<uint8_t>(h) {}
+       BooleanArray(int32_t length) : ArrayTemplate<uint8_t>(length, primitivetype_table[ARRAYTYPE_BOOLEAN].arrayclass) {}
+       uint8_t* get_raw_data_ptr() { return ((java_booleanarray_t*) get_handle())->data; }
+};
+
+class ByteArray : public ArrayTemplate<int8_t> {
+public:
+       ByteArray(java_handle_bytearray_t* h) : ArrayTemplate<int8_t>(h) {}
+       ByteArray(int32_t length) : ArrayTemplate<int8_t>(length, primitivetype_table[ARRAYTYPE_BYTE].arrayclass) {}
+       int8_t* get_raw_data_ptr() { return ((java_bytearray_t*) get_handle())->data; }
+};
+
+class CharArray : public ArrayTemplate<uint16_t> {
+public:
+       CharArray(java_handle_chararray_t* h) : ArrayTemplate<uint16_t>(h) {}
+       CharArray(int32_t length) : ArrayTemplate<uint16_t>(length, primitivetype_table[ARRAYTYPE_CHAR].arrayclass) {}
+       uint16_t* get_raw_data_ptr() { return ((java_chararray_t*) get_handle())->data; }
+};
+
+class ShortArray : public ArrayTemplate<int16_t> {
+public:
+       ShortArray(java_handle_shortarray_t* h) : ArrayTemplate<int16_t>(h) {}
+       ShortArray(int32_t length) : ArrayTemplate<int16_t>(length, primitivetype_table[ARRAYTYPE_SHORT].arrayclass) {}
+       int16_t* get_raw_data_ptr() { return ((java_shortarray_t*) get_handle())->data; }
+};
+
+class IntArray : public ArrayTemplate<int32_t> {
+public:
+       IntArray(java_handle_intarray_t* h) : ArrayTemplate<int32_t>(h) {}
+       IntArray(int32_t length) : ArrayTemplate<int32_t>(length, primitivetype_table[ARRAYTYPE_INT].arrayclass) {}
+       int32_t* get_raw_data_ptr() { return ((java_intarray_t*) get_handle())->data; }
+};
+
+class LongArray : public ArrayTemplate<int64_t> {
+public:
+       LongArray(java_handle_longarray_t* h) : ArrayTemplate<int64_t>(h) {}
+       LongArray(int32_t length) : ArrayTemplate<int64_t>(length, primitivetype_table[ARRAYTYPE_LONG].arrayclass) {}
+       int64_t* get_raw_data_ptr() { return ((java_longarray_t*) get_handle())->data; }
+};
+
+class FloatArray : public ArrayTemplate<float> {
+public:
+       FloatArray(java_handle_floatarray_t* h) : ArrayTemplate<float>(h) {}
+       FloatArray(int32_t length) : ArrayTemplate<float>(length, primitivetype_table[ARRAYTYPE_FLOAT].arrayclass) {}
+       float* get_raw_data_ptr() { return ((java_floatarray_t*) get_handle())->data; }
+};
+
+class DoubleArray : public ArrayTemplate<double> {
+public:
+       DoubleArray(java_handle_doublearray_t* h) : ArrayTemplate<double>(h) {}
+       DoubleArray(int32_t length) : ArrayTemplate<double>(length, primitivetype_table[ARRAYTYPE_DOUBLE].arrayclass) {}
+       double* get_raw_data_ptr() { return ((java_doublearray_t*) get_handle())->data; }
+};
+
+/**
+ * Actual implementation of access class for Java Object arrays.
+ */
+class ObjectArray : public ArrayTemplate<java_handle_t*> {
+public:
+       ObjectArray(java_handle_objectarray_t* h) : ArrayTemplate<java_handle_t*>(h) {}
+       ObjectArray(int32_t length, classinfo* componentclass);
+       java_handle_t** get_raw_data_ptr() { return ((java_objectarray_t*) get_handle())->data; }
+};
+
+/**
+ * Actual implementation of access class for java.lang.Class arrays.
+ */
+class ClassArray : public ArrayTemplate<classinfo*> {
+public:
+       ClassArray(int32_t length);
+       classinfo** get_raw_data_ptr() { return (classinfo**) ((java_objectarray_t*) get_handle())->data; }
+};
+
+
+#else
+# warning No legacy C functions for array access classes.
 #endif
 
 #endif // _VM_ARRAY_HPP
index 0c1739a3c0ed7089cc206e1cecebdac9218af788..ee17a20ca34b2cf212d14a819c07425fee45992c 100644 (file)
@@ -1643,7 +1643,6 @@ java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOn
        utf                   *outername;
        int                    declaredclasscount;  /* number of declared classes */
        int                    pos;                     /* current declared class */
-       java_handle_objectarray_t *oa;               /* array of declared classes */
        int                    i;
        classinfo             *ic;
 
@@ -1676,9 +1675,9 @@ java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOn
 
        /* Allocate Class[] and check for OOM. */
 
-       oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
+       ClassArray declaredclasses(declaredclasscount);
 
-       if (oa == NULL)
+       if (declaredclasses.is_null())
                return NULL;
 
        for (i = 0, pos = 0; i < c->innerclasscount; i++) {
@@ -1710,11 +1709,11 @@ java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOn
                                if (!link_class(ic))
                                        return NULL;
 
-                       LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
+                       declaredclasses.set_element(pos++, ic);
                }
        }
 
-       return oa;
+       return declaredclasses.get_handle();
 }
 
 
@@ -1729,11 +1728,10 @@ java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOn
 #if defined(ENABLE_JAVASE)
 java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
 {
-       methodinfo*                m;
-       java_handle_objectarray_t* oa;
-       int                        count;
-       int                        index;
-       int                        i;
+       methodinfo* m;
+       int         count;
+       int         index;
+       int         i;
 
        /* Determine number of constructors. */
 
@@ -1749,9 +1747,9 @@ java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool pub
 
        /* Create array of constructors. */
 
-       oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
+       ObjectArray oa(count, class_java_lang_reflect_Constructor);
 
-       if (oa == NULL)
+       if (oa.is_null())
                return NULL;
 
        /* Get the constructors and store them in the array. */
@@ -1767,12 +1765,12 @@ java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool pub
 
                        /* Store object into array. */
 
-                       array_objectarray_element_set(oa, index, rc.get_handle());
+                       oa.set_element(index, rc.get_handle());
                        index++;
                }
        }
 
-       return oa;
+       return oa.get_handle();
 }
 #endif
 
@@ -1793,11 +1791,10 @@ java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool pub
 #if defined(ENABLE_JAVASE)
 java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
 {
-       java_handle_objectarray_t *oa;
-       fieldinfo                 *f;
-       int                        count;
-       int                        index;
-       int                        i;
+       fieldinfo* f;
+       int        count;
+       int        index;
+       int        i;
 
        /* Determine number of fields. */
 
@@ -1809,9 +1806,9 @@ java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnl
 
        /* Create array of fields. */
 
-       oa = builtin_anewarray(count, class_java_lang_reflect_Field);
+       ObjectArray oa(count, class_java_lang_reflect_Field);
 
-       if (oa == NULL)
+       if (oa.is_null())
                return NULL;
 
        /* Get the fields and store them in the array. */
@@ -1826,12 +1823,12 @@ java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnl
 
                        /* Store object into array. */
 
-                       array_objectarray_element_set(oa, index, rf.get_handle());
+                       oa.set_element(index, rf.get_handle());
                        index++;
                }
        }
 
-       return oa;
+       return oa.get_handle();
 }
 #endif
 
@@ -1852,19 +1849,20 @@ java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnl
 #if defined(ENABLE_JAVASE)
 java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
 {
-       java_handle_objectarray_t *oa;         /* result: array of Method-objects */
-       methodinfo                *m;     /* the current method to be represented */
-       int                        count;
-       int                        index;
-       int                        i;
+       methodinfo* m;     /* the current method to be represented */
+       int         count;
+       int         index;
+       int         i;
 
        /* JOWENN: array classes do not declare methods according to mauve
           test.  It should be considered, if we should return to my old
           clone method overriding instead of declaring it as a member
           function. */
 
-       if (class_is_array(c))
-               return builtin_anewarray(0, class_java_lang_reflect_Method);
+       if (class_is_array(c)) {
+               ObjectArray oa(0, class_java_lang_reflect_Method);
+               return oa.get_handle();
+       }
 
        /* Determine number of methods. */
 
@@ -1881,9 +1879,9 @@ java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOn
 
        /* Create array of methods. */
 
-       oa = builtin_anewarray(count, class_java_lang_reflect_Method);
+       ObjectArray oa(count, class_java_lang_reflect_Method);
 
-       if (oa == NULL)
+       if (oa.is_null())
                return NULL;
 
        /* Get the methods and store them in the array. */
@@ -1900,12 +1898,12 @@ java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOn
 
                        /* Store object into array. */
 
-                       array_objectarray_element_set(oa, index, rm.get_handle());
+                       oa.set_element(index, rm.get_handle());
                        index++;
                }
        }
 
-       return oa;
+       return oa.get_handle();
 }
 #endif
 
@@ -2103,28 +2101,27 @@ java_handle_t* class_get_enclosingmethod(classinfo *c)
 
 *******************************************************************************/
 
-java_handle_objectarray_t *class_get_interfaces(classinfo *c)
+java_handle_objectarray_tclass_get_interfaces(classinfo *c)
 {
-       classinfo                 *ic;
-       java_handle_objectarray_t *oa;
-       u4                         i;
+       classinfo* ic;
+       u4         i;
 
        if (!(c->state & CLASS_LINKED))
                if (!link_class(c))
                        return NULL;
 
-       oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
+       ClassArray interfaces(c->interfacescount);
 
-       if (oa == NULL)
+       if (interfaces.is_null())
                return NULL;
 
        for (i = 0; i < c->interfacescount; i++) {
                ic = c->interfaces[i];
 
-               LLNI_array_direct(oa, i) = (java_object_t *) ic;
+               interfaces.set_element(i, ic);
        }
 
-       return oa;
+       return interfaces.get_handle();
 }
 
 
@@ -2149,7 +2146,7 @@ java_handle_bytearray_t *class_get_annotations(classinfo *c)
 
        LLNI_classinfo_field_get(c, annotations, annotations);
 
-       return (java_handle_bytearray_t*)annotations;
+       return (java_handle_bytearray_t*) annotations;
 #else
        return NULL;
 #endif
index 6b6b4ed43be2776661cef9998341f69008b6bea4..9d034b36cbcfefce3714e5dfb5db7f3211fca972 100644 (file)
@@ -405,26 +405,24 @@ java_handle_bytearray_t *field_get_annotations(fieldinfo *f)
 #if defined(ENABLE_ANNOTATIONS)
        classinfo               *c;           /* declaring class           */
        int                      slot;        /* slot of this field        */
-       java_handle_bytearray_t *annotations; /* unparsed annotations      */
        java_handle_t           *field_annotations;  /* array of unparsed  */
                       /* annotations of all fields of the declaring class */
 
-       c           = f->clazz;
-       slot        = f - c->fields;
-       annotations = NULL;
+       c    = f->clazz;
+       slot = f - c->fields;
 
        LLNI_classinfo_field_get(c, field_annotations, field_annotations);
 
+       ObjectArray oa(field_annotations);
+
        /* the field_annotations array might be shorter then the field
         * count if the fields above a certain index have no annotations.
         */
-       if (field_annotations != NULL &&
-               array_length_get(field_annotations) > slot) {
-               annotations = (java_handle_bytearray_t*)array_objectarray_element_get(
-                               (java_handle_objectarray_t*)field_annotations, slot);
+       if (field_annotations != NULL && oa.get_length() > slot) {
+               return (java_handle_bytearray_t*) oa.get_element(slot);
+       } else {
+               return NULL;
        }
-       
-       return annotations;
 #else
        return NULL;
 #endif
index 011d9b4a03e78ed78a64e8158fceada9e0ebcc9b..33b7fb1e7ecd32cae73c00b1d1155bc902e12e16 100644 (file)
@@ -323,34 +323,17 @@ struct java_objectarray_t {
 
 *******************************************************************************/
 
-#if defined(ENABLE_HANDLES)
-typedef struct java_handle_t {
-       java_object_t *heap_object;
-} java_handle_t;
-
-typedef struct java_handle_array_t        { java_array_t        *heap_object; } java_handle_array_t;
-typedef struct java_handle_objectarray_t  { java_objectarray_t  *heap_object; } java_handle_objectarray_t;
-typedef struct java_handle_booleanarray_t { java_booleanarray_t *heap_object; } java_handle_booleanarray_t;
-typedef struct java_handle_bytearray_t    { java_bytearray_t    *heap_object; } java_handle_bytearray_t;
-typedef struct java_handle_chararray_t    { java_chararray_t    *heap_object; } java_handle_chararray_t;
-typedef struct java_handle_shortarray_t   { java_shortarray_t   *heap_object; } java_handle_shortarray_t;
-typedef struct java_handle_intarray_t     { java_intarray_t     *heap_object; } java_handle_intarray_t;
-typedef struct java_handle_longarray_t    { java_longarray_t    *heap_object; } java_handle_longarray_t;
-typedef struct java_handle_floatarray_t   { java_floatarray_t   *heap_object; } java_handle_floatarray_t;
-typedef struct java_handle_doublearray_t  { java_doublearray_t  *heap_object; } java_handle_doublearray_t;
-#else
 typedef java_object_t       java_handle_t;
-typedef java_array_t        java_handle_array_t;
-typedef java_objectarray_t  java_handle_objectarray_t;
-typedef java_booleanarray_t java_handle_booleanarray_t;
-typedef java_bytearray_t    java_handle_bytearray_t;
-typedef java_chararray_t    java_handle_chararray_t;
-typedef java_shortarray_t   java_handle_shortarray_t;
-typedef java_intarray_t     java_handle_intarray_t;
-typedef java_longarray_t    java_handle_longarray_t;
-typedef java_floatarray_t   java_handle_floatarray_t;
-typedef java_doublearray_t  java_handle_doublearray_t;
-#endif
+typedef java_handle_t       java_handle_array_t;
+typedef java_handle_array_t java_handle_objectarray_t;
+typedef java_handle_array_t java_handle_booleanarray_t;
+typedef java_handle_array_t java_handle_bytearray_t;
+typedef java_handle_array_t java_handle_chararray_t;
+typedef java_handle_array_t java_handle_shortarray_t;
+typedef java_handle_array_t java_handle_intarray_t;
+typedef java_handle_array_t java_handle_longarray_t;
+typedef java_handle_array_t java_handle_floatarray_t;
+typedef java_handle_array_t java_handle_doublearray_t;
 
 
 /* global constants related to the verifier ***********************************/
index b8a0d601326b5b830b68e14a474d44ca009341df..901756534cd4441f25d5f03a5e2b7e706f402e52 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/javaobjects.cpp - functions to create and access Java objects
 
-   Copyright (C) 2008 Theobroma Systems Ltd.
+   Copyright (C) 2008, 2009 Theobroma Systems Ltd.
 
    This file is part of CACAO.
 
 
 #if defined(ENABLE_JAVASE)
 
+/**
+ * Invokes the static Java method getSystemClassLoader().
+ *
+ * @return Return value of the invocation or NULL in
+ * case of an exception.
+ */
+java_handle_t* java_lang_ClassLoader::invoke_getSystemClassLoader()
+{
+       methodinfo    *m;
+       java_handle_t *clo;
+       classloader_t *cl;
+
+       assert(class_java_lang_Object);
+       assert(class_java_lang_ClassLoader);
+       assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
+
+       m = class_resolveclassmethod(class_java_lang_ClassLoader,
+                                                                utf_getSystemClassLoader,
+                                                                utf_void__java_lang_ClassLoader,
+                                                                class_java_lang_Object,
+                                                                false);
+
+       if (m == NULL)
+               return NULL;
+
+       clo = vm_call_method(m, NULL);
+
+       if (clo == NULL)
+               return NULL;
+
+       cl = loader_hashtable_classloader_add(clo);
+
+       return cl;
+}
+
+
 /**
  * Constructs a Java object with the given
  * java.lang.reflect.Constructor.
@@ -67,7 +103,7 @@ java_handle_t* java_lang_reflect_Constructor::new_instance(java_handle_objectarr
 
        if (h == NULL)
                return NULL;
-        
+
        // Call initializer.
        (void) Reflection::invoke(m, h, args);
 
index b8ee1215a26280226c6296bd90cfcfb2a268d55c..71f58abb11147bfe1de4996a6df396331f529237 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/javaobjects.hpp - functions to create and access Java objects
 
-   Copyright (C) 2008 Theobroma Systems Ltd.
+   Copyright (C) 2008, 2009 Theobroma Systems Ltd.
 
    This file is part of CACAO.
 
@@ -590,6 +590,39 @@ inline void java_lang_Class::set_pd(java_handle_t* value)
 }
 
 
+/**
+ * GNU Classpath java/lang/ClassLoader
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. java.util.HashMap     definedPackages
+ * 2. java.lang.ClassLoader parent
+ * [other fields are not used]
+ */
+class java_lang_ClassLoader : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_definedPackages = MEMORY_ALIGN(sizeof(java_object_t),                  SIZEOF_VOID_P);
+       static const off_t offset_parent          = MEMORY_ALIGN(offset_definedPackages + SIZEOF_VOID_P, SIZEOF_VOID_P);
+
+public:
+       java_lang_ClassLoader(java_handle_t* h) : java_lang_Object(h) {}
+
+       // Getters.
+       java_handle_t* get_parent() const;
+
+       // Invocation wrappers for static methods.
+       static java_handle_t* invoke_getSystemClassLoader();
+};
+
+inline java_handle_t* java_lang_ClassLoader::get_parent() const
+{
+       return get<java_handle_t*>(_handle, offset_parent);
+}
+
+
 /**
  * GNU Classpath java/lang/StackTraceElement
  *
@@ -1715,7 +1748,7 @@ public:
        gnu_classpath_Pointer(java_handle_t* h) : java_lang_Object(h) {}
        gnu_classpath_Pointer(java_handle_t* h, void* data);
 
-       // Setters.
+       // Getters.
        void* get_data() const;
 
        // Setters.
@@ -1788,6 +1821,39 @@ inline java_lang_AssertionStatusDirectives::java_lang_AssertionStatusDirectives(
 }
 
 
+/**
+ * OpenJDK java/lang/ClassLoader
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. boolean               initialized
+ * 2. java.lang.ClassLoader parent
+ * [other fields are not used]
+ */
+class java_lang_ClassLoader : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_initialized = MEMORY_ALIGN(sizeof(java_object_t),                sizeof(int32_t));
+       static const off_t offset_parent      = MEMORY_ALIGN(offset_initialized + sizeof(int32_t), SIZEOF_VOID_P);
+
+public:
+       java_lang_ClassLoader(java_handle_t* h) : java_lang_Object(h) {}
+
+       // Getters.
+       java_handle_t* get_parent() const;
+
+       // Invocation wrappers for static methods.
+       static java_handle_t* invoke_getSystemClassLoader();
+};
+
+inline java_handle_t* java_lang_ClassLoader::get_parent() const
+{
+       return get<java_handle_t*>(_handle, offset_parent);
+}
+
+
 /**
  * OpenJDK java/lang/StackTraceElement
  *
index 5ee7ca6d5b22e5b8d62acb6a222f05f38402a7bf..9736c1e24945dce0707558fdd7920ae1d8e355bb 100644 (file)
@@ -582,10 +582,12 @@ uint64_t *argument_vmarray_from_objectarray(methodinfo *m, java_handle_t *o,
                i++;
        }
 
+       ObjectArray oa(params);
+
        for (j = 0; i < md->paramcount; i++, j++, pd++, td++) {
                /* XXX This function can throw an exception, which should not happend
                   here, since we are outside the nativeworld. */
-               param = array_objectarray_element_get(params, j);
+               param = oa.get_element(j);
 
                switch (td->type) {
                case TYPE_INT:
index bdfb79a4b5eb0409943b48dd74d9dce54bf3dbe0..ff1e2dd9c9c7ae9532d8cfa1a30241fa7d361cc9 100644 (file)
@@ -581,7 +581,7 @@ bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
 
        LLNI_CRITICAL_START;
 
-       result = builtin_fast_canstore(LLNI_DIRECT(oa), LLNI_UNWRAP(o));
+       result = builtin_fast_canstore((java_objectarray_t*) LLNI_DIRECT(oa), LLNI_UNWRAP(o));
 
        LLNI_CRITICAL_END;
 
@@ -1036,7 +1036,7 @@ java_object_t *builtin_fast_new(classinfo *c)
 }
 
 
-/* builtin_newarray ************************************************************
+/* builtin_java_newarray *******************************************************
 
    Creates an array with the given vftbl on the heap. This function
    takes as class argument an array class.
@@ -1044,111 +1044,27 @@ java_object_t *builtin_fast_new(classinfo *c)
    RETURN VALUE:
       pointer to the array or NULL if no memory is available
 
-   NOTE: This builtin can be called from NATIVE code only.
+   NOTE: This is a SLOW builtin and can be called from JIT code only.
 
 *******************************************************************************/
 
-java_handle_t *builtin_newarray(int32_t size, classinfo *arrayclass)
+java_handle_array_t *builtin_java_newarray(int32_t size, java_handle_t *arrayclazz)
 {
-       arraydescriptor *desc;
-       s4               dataoffset;
-       s4               componentsize;
-       s4               actualsize;
-       java_handle_t   *a;
 #if defined(ENABLE_RT_TIMING)
        struct timespec time_start, time_end;
 #endif
 
        RT_TIMING_GET_TIME(time_start);
 
-       desc          = arrayclass->vftbl->arraydesc;
-       dataoffset    = desc->dataoffset;
-       componentsize = desc->componentsize;
-
-       if (size < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
-
-       actualsize = dataoffset + size * componentsize;
+       classinfo* arrayclass = LLNI_classinfo_unwrap(arrayclazz);
 
-       /* check for overflow */
-
-       if (((u4) actualsize) < ((u4) size)) {
-               exceptions_throw_outofmemoryerror();
-               return NULL;
-       }
-
-       a = (java_handle_t*) heap_alloc(actualsize, (desc->arraytype == ARRAYTYPE_OBJECT), NULL, true);
-
-       if (a == NULL)
-               return NULL;
-
-#if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
-       /* XXX this is only a dirty hack to make Boehm work with handles */
-
-       a = LLNI_WRAP((java_object_t *) a);
-#endif
-
-       LLNI_vftbl_direct(a) = arrayclass->vftbl;
-
-#if defined(ENABLE_THREADS)
-       LLNI_DIRECT(a)->lockword.init();
-#endif
-
-       LLNI_array_size(a) = size;
+       // Allocate a new array with given size and class on the heap
+       Array a(size, arrayclass);
 
        RT_TIMING_GET_TIME(time_end);
        RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_ARRAY);
 
-       return a;
-}
-
-
-/* builtin_java_newarray *******************************************************
-
-   NOTE: This is a SLOW builtin and can be called from JIT code only.
-
-*******************************************************************************/
-
-java_handle_t *builtin_java_newarray(int32_t size, java_handle_t *arrayclazz)
-{
-       return builtin_newarray(size, LLNI_classinfo_unwrap(arrayclazz));
-}
-
-
-/* builtin_anewarray ***********************************************************
-
-   Creates an array of references to the given class type on the heap.
-
-   RETURN VALUE:
-      pointer to the array or NULL if no memory is
-      available
-
-   NOTE: This builtin can be called from NATIVE code only.
-
-*******************************************************************************/
-
-java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentclass)
-{
-       classinfo *arrayclass;
-       
-       /* is class loaded */
-
-       assert(componentclass->state & CLASS_LOADED);
-
-       /* is class linked */
-
-       if (!(componentclass->state & CLASS_LINKED))
-               if (!link_class(componentclass))
-                       return NULL;
-
-       arrayclass = class_array_of(componentclass, true);
-
-       if (!arrayclass)
-               return NULL;
-
-       return (java_handle_objectarray_t *) builtin_newarray(size, arrayclass);
+       return a.get_handle();
 }
 
 
@@ -1163,21 +1079,21 @@ java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentc
 
 *******************************************************************************/
 
-#define BUILTIN_NEWARRAY_TYPE(type, arraytype)                             \
-java_handle_##type##array_t *builtin_newarray_##type(int32_t size)              \
-{                                                                          \
-       return (java_handle_##type##array_t *)                                 \
-               builtin_newarray(size, primitivetype_table[arraytype].arrayclass); \
+#define BUILTIN_NEWARRAY_TYPE(type, name)                          \
+java_handle_##type##array_t *builtin_newarray_##type(int32_t size) \
+{                                                                  \
+       name##Array a(size);                                           \
+       return a.get_handle();                                         \
 }
 
-BUILTIN_NEWARRAY_TYPE(boolean, ARRAYTYPE_BOOLEAN)
-BUILTIN_NEWARRAY_TYPE(byte,    ARRAYTYPE_BYTE)
-BUILTIN_NEWARRAY_TYPE(char,    ARRAYTYPE_CHAR)
-BUILTIN_NEWARRAY_TYPE(short,   ARRAYTYPE_SHORT)
-BUILTIN_NEWARRAY_TYPE(int,     ARRAYTYPE_INT)
-BUILTIN_NEWARRAY_TYPE(long,    ARRAYTYPE_LONG)
-BUILTIN_NEWARRAY_TYPE(float,   ARRAYTYPE_FLOAT)
-BUILTIN_NEWARRAY_TYPE(double,  ARRAYTYPE_DOUBLE)
+BUILTIN_NEWARRAY_TYPE(boolean, Boolean)
+BUILTIN_NEWARRAY_TYPE(byte,    Byte)
+BUILTIN_NEWARRAY_TYPE(char,    Char)
+BUILTIN_NEWARRAY_TYPE(short,   Short)
+BUILTIN_NEWARRAY_TYPE(int,     Int)
+BUILTIN_NEWARRAY_TYPE(long,    Long)
+BUILTIN_NEWARRAY_TYPE(float,   Float)
+BUILTIN_NEWARRAY_TYPE(double,  Double)
 
 
 /* builtin_multianewarray_intern ***********************************************
@@ -1195,38 +1111,37 @@ BUILTIN_NEWARRAY_TYPE(double,  ARRAYTYPE_DOUBLE)
 
 ******************************************************************************/
 
-static java_handle_t *builtin_multianewarray_intern(int n,
+static java_handle_array_t *builtin_multianewarray_intern(int n,
                                                                                                        classinfo *arrayclass,
                                                                                                        long *dims)
 {
-       s4             size;
-       java_handle_t *a;
-       classinfo     *componentclass;
-       s4             i;
+       int32_t i;
 
        /* create this dimension */
 
-       size = (s4) dims[0];
-       a = builtin_newarray(size, arrayclass);
+       int32_t size = (int32_t) dims[0];
+       Array a(size, arrayclass);
 
-       if (!a)
+       if (a.is_null())
                return NULL;
 
        /* if this is the last dimension return */
 
        if (!--n)
-               return a;
+               return a.get_handle();
 
        /* get the class of the components to create */
 
-       componentclass = arrayclass->vftbl->arraydesc->componentvftbl->clazz;
+       classinfo* componentclass = arrayclass->vftbl->arraydesc->componentvftbl->clazz;
 
        /* The verifier guarantees that the dimension count is in the range. */
 
        /* create the component arrays */
 
+       ObjectArray oa(a.get_handle());
+
        for (i = 0; i < size; i++) {
-               java_handle_t *ea =
+               java_handle_array_t *ea =
 #if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
                        /* we save an s4 to a s8 slot, 8-byte aligned */
 
@@ -1238,10 +1153,10 @@ static java_handle_t *builtin_multianewarray_intern(int n,
                if (!ea)
                        return NULL;
 
-               array_objectarray_element_set((java_handle_objectarray_t *) a, i, ea);
+               oa.set_element(i, (java_handle_t*) ea);
        }
 
-       return a;
+       return a.get_handle();
 }
 
 
@@ -2086,6 +2001,9 @@ void builtin_arraycopy(java_handle_t *src, s4 srcStart,
                return;
        }
 
+       Array sa(src);
+       Array da(dest);
+
        sdesc = LLNI_vftbl_direct(src)->arraydesc;
        ddesc = LLNI_vftbl_direct(dest)->arraydesc;
 
@@ -2101,8 +2019,8 @@ void builtin_arraycopy(java_handle_t *src, s4 srcStart,
        }
 
        // Check if ranges are valid.
-       if ((((uint32_t) srcStart  + (uint32_t) len) > (uint32_t) LLNI_array_size(src)) ||
-               (((uint32_t) destStart + (uint32_t) len) > (uint32_t) LLNI_array_size(dest))) {
+       if ((((uint32_t) srcStart  + (uint32_t) len) > (uint32_t) sa.get_length()) ||
+               (((uint32_t) destStart + (uint32_t) len) > (uint32_t) da.get_length())) {
                exceptions_throw_arrayindexoutofboundsexception();
                return;
        }
@@ -2129,19 +2047,17 @@ void builtin_arraycopy(java_handle_t *src, s4 srcStart,
        else {
                /* We copy references of different type */
 
-               java_handle_objectarray_t *oas = (java_handle_objectarray_t *) src;
-               java_handle_objectarray_t *oad = (java_handle_objectarray_t *) dest;
+               ObjectArray oas((java_handle_objectarray_t*) src);
+               ObjectArray oad((java_handle_objectarray_t*) dest);
  
                if (destStart <= srcStart) {
                        for (i = 0; i < len; i++) {
-                               java_handle_t *o;
+                               java_handle_t* o = oas.get_element(srcStart + i);
 
-                               o = array_objectarray_element_get(oas, srcStart + i);
-
-                               if (!builtin_canstore(oad, o))
+                               if (!builtin_canstore(oad.get_handle(), o))
                                        return;
 
-                               array_objectarray_element_set(oad, destStart + i, o);
+                               oad.set_element(destStart + i, o);
                        }
                }
                else {
@@ -2152,14 +2068,12 @@ void builtin_arraycopy(java_handle_t *src, s4 srcStart,
                           index have been copied before the throw. */
 
                        for (i = len - 1; i >= 0; i--) {
-                               java_handle_t *o;
-
-                               o = array_objectarray_element_get(oas, srcStart + i);
+                               java_handle_t* o = oas.get_element(srcStart + i);
 
-                               if (!builtin_canstore(oad, o))
+                               if (!builtin_canstore(oad.get_handle(), o))
                                        return;
 
-                               array_objectarray_element_set(oad, destStart + i, o);
+                               oad.set_element(destStart + i, o);
                        }
                }
        }
@@ -2224,7 +2138,9 @@ java_handle_t *builtin_clone(void *env, java_handle_t *o)
        /* we are cloning an array */
 
        if (ad != NULL) {
-               size = ad->dataoffset + ad->componentsize * LLNI_array_size(o);
+               Array a(o);
+
+               size = ad->dataoffset + ad->componentsize * a.get_length();
         
                co = (java_handle_t*) heap_alloc(size, (ad->arraytype == ARRAYTYPE_OBJECT), NULL, true);
 
index 60b58e25c672497252ad3d94c99c1377b1a950c6..af81aced2d3c8adbc2d5cced00f3f0eae663ddb3 100644 (file)
@@ -168,14 +168,9 @@ java_handle_t *builtin_escape_reason_new(classinfo *c);
 java_object_t *builtin_fast_new(classinfo *c);
 #define BUILTIN_FAST_new (functionptr) builtin_fast_new
 
-java_handle_t *builtin_newarray(int32_t size, classinfo *arrayclass);
-/* NOT AN OP */
-java_handle_t *builtin_java_newarray(int32_t size, java_handle_t *arrayclass);
+java_handle_array_t *builtin_java_newarray(int32_t size, java_handle_t *arrayclass);
 #define BUILTIN_newarray (functionptr) builtin_java_newarray
 
-java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentclass);
-/* NOT AN OP */
-
 java_handle_booleanarray_t *builtin_newarray_boolean(int32_t size);
 #define BUILTIN_newarray_boolean (functionptr) builtin_newarray_boolean
 java_handle_chararray_t *builtin_newarray_char(int32_t size);
index 8efa4b25bcfe75e72a730f6f78fbaae542274ab6..b51154ed2578fdb94b3068f88660ece7eb2bffa1 100644 (file)
@@ -2,6 +2,7 @@
 
    Copyright (C) 1996-2005, 2006, 2007, 2008
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+   Copyright (C) 2009 Theobroma Systems Ltd.
 
    This file is part of CACAO.
 
@@ -516,15 +517,14 @@ static int stacktrace_depth(stackframeinfo_t *sfi)
 
 java_handle_bytearray_t *stacktrace_get(stackframeinfo_t *sfi)
 {
-       stackframeinfo_t         tmpsfi;
-       int                      depth;
-       java_handle_bytearray_t *ba;
-       int32_t                  ba_size;
-       stacktrace_t            *st;
-       stacktrace_entry_t      *ste;
-       methodinfo              *m;
-       bool                     skip_fillInStackTrace;
-       bool                     skip_init;
+       stackframeinfo_t    tmpsfi;
+       int                 depth;
+       int32_t             ba_size;
+       stacktrace_t       *st;
+       stacktrace_entry_t *ste;
+       methodinfo         *m;
+       bool                skip_fillInStackTrace;
+       bool                skip_init;
 
        CYCLES_STATS_DECLARE_AND_START_WITH_OVERHEAD
 
@@ -550,9 +550,9 @@ java_handle_bytearray_t *stacktrace_get(stackframeinfo_t *sfi)
 
        ba_size = sizeof(stacktrace_t) + sizeof(stacktrace_entry_t) * depth;
 
-       ba = builtin_newarray_byte(ba_size);
+       ByteArray ba(ba_size);
 
-       if (ba == NULL)
+       if (ba.is_null())
                goto return_NULL;
 
        /* Get a stacktrace entry pointer. */
@@ -561,7 +561,7 @@ java_handle_bytearray_t *stacktrace_get(stackframeinfo_t *sfi)
 
        LLNI_CRITICAL_START;
 
-       st = (stacktrace_t *) LLNI_array_data(ba);
+       st = (stacktrace_t *) ba.get_raw_data_ptr();
 
        ste = st->entries;
 
@@ -639,7 +639,7 @@ java_handle_bytearray_t *stacktrace_get(stackframeinfo_t *sfi)
 
        CYCLES_STATS_END_WITH_OVERHEAD(stacktrace_fillInStackTrace,
                                                                   stacktrace_overhead)
-       return ba;
+       return ba.get_handle();
 
 return_NULL:
 /*     dump_release(dumpsize); */
@@ -774,9 +774,9 @@ java_handle_objectarray_t* stacktrace_get_StackTraceElements(stacktrace_t* st)
        int32_t length = (st != NULL) ? st->length : 0;
 
        // Create the stacktrace element array.
-       java_handle_objectarray_t* oa = builtin_anewarray(length, class_java_lang_StackTraceElement);
+       ObjectArray oa(length, class_java_lang_StackTraceElement);
 
-       if (oa == NULL)
+       if (oa.is_null())
                return NULL;
 
        // Iterate over all stacktrace elements.
@@ -789,10 +789,10 @@ java_handle_objectarray_t* stacktrace_get_StackTraceElements(stacktrace_t* st)
                        return NULL;
 
                // Store stacktrace element in array.
-               array_objectarray_element_set(oa, i, h);
+               oa.set_element(i, h);
        }
 
-       return oa;
+       return oa.get_handle();
 }
 #endif
 
@@ -873,17 +873,12 @@ classinfo *stacktrace_get_caller_class(int depth)
 #endif
 
 
-/* stacktrace_first_nonnull_classloader ****************************************
-
-   Returns the first non-null (user-defined) classloader on the stack.
-   If none is found NULL is returned.
-
-   RETURN:
-       classloader
-
-*******************************************************************************/
-
-classloader_t *stacktrace_first_nonnull_classloader(void)
+/**
+ * Returns the first non-null (user-defined) classloader on the stack.
+ *
+ * @return The first non-null classloader or NULL if none is found.
+ */
+classloader_t* stacktrace_first_nonnull_classloader(void)
 {
        stackframeinfo_t *sfi;
        stackframeinfo_t  tmpsfi;
@@ -916,6 +911,82 @@ classloader_t *stacktrace_first_nonnull_classloader(void)
 }
 
 
+/**
+ * Checks if a given classloader is equal to the the second classloader
+ * or one of its ancestors (parents).
+ *
+ * XXX: This helper method should be moved to java_lang_Classloader.
+ */
+#if defined(ENABLE_JAVASE)
+static bool is_ancestor_of(classloader_t* loader, classloader_t* parent)
+{
+       // Iterate over chain of possible parents.
+       while (parent != NULL) {
+
+               // Check if given loader is parent.
+               if (loader == parent)
+                       return true;
+
+               // Jump to next parent.
+               java_lang_ClassLoader jlcl(parent);
+               parent = jlcl.get_parent();
+       }
+
+       return false;
+}
+#endif /* defined(ENABLE_JAVASE) */
+
+
+/**
+ * Returns the first non-system (user-defined) classloader on the stack.
+ * A non-system classloader is a non-null classloader being not equal to
+ * the system classloader (or one of its ancestors).
+ *
+ * @return The first non-system classloader or NULL if none is found.
+ */
+#if defined(ENABLE_JAVASE)
+classloader_t* stacktrace_first_nonsystem_classloader(void)
+{
+       stackframeinfo_t *sfi;
+       stackframeinfo_t  tmpsfi;
+       methodinfo       *m;
+       classloader_t    *cl;
+       classloader_t    *syscl;
+
+#if !defined(NDEBUG)
+       if (opt_DebugStackTrace)
+               log_println("[stacktrace_first_nonsystem_classloader]");
+#endif
+
+       // Get the stackframeinfo of the current thread.
+       sfi = threads_get_current_stackframeinfo();
+
+       // Get the system class class loader.
+       syscl = java_lang_ClassLoader::invoke_getSystemClassLoader();
+
+       // Iterate over the whole stack.
+       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
+                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
+                stacktrace_stackframeinfo_next(&tmpsfi)) {
+
+               m  = tmpsfi.code->m;
+               cl = class_get_classloader(m->clazz);
+
+               if (cl == NULL)
+                       continue;
+
+               // XXX if a method in a class in a trusted loader is in a
+               // doPrivileged, return NULL (or break) here.
+
+               if (!is_ancestor_of(cl, syscl))
+                       return cl;
+       }
+
+       return NULL;
+}
+#endif /* defined(ENABLE_JAVASE) */
+
+
 /* stacktrace_getClassContext **************************************************
 
    Creates a Class context array.
@@ -931,8 +1002,6 @@ java_handle_objectarray_t *stacktrace_getClassContext(void)
        stackframeinfo_t           *sfi;
        stackframeinfo_t            tmpsfi;
        int                         depth;
-       java_handle_objectarray_t  *oa;
-       java_object_t             **data;
        int                         i;
        methodinfo                 *m;
 
@@ -959,20 +1028,15 @@ java_handle_objectarray_t *stacktrace_getClassContext(void)
 
        /* Allocate the Class array. */
 
-       oa = builtin_anewarray(depth, class_java_lang_Class);
+       ClassArray ca(depth);
 
-       if (oa == NULL) {
+       if (ca.is_null()) {
                CYCLES_STATS_END(stacktrace_getClassContext);
 
                return NULL;
        }
 
        /* Fill the Class array from the stacktrace list. */
-
-       LLNI_CRITICAL_START;
-
-       data = LLNI_array_data(oa);
-
        /* Iterate over the whole stack. */
 
        i = 0;
@@ -991,7 +1055,7 @@ java_handle_objectarray_t *stacktrace_getClassContext(void)
 
                /* Store the class in the array. */
 
-               data[i] = (java_object_t *) m->clazz;
+               ca.set_element(i, m->clazz);
 
                i++;
        }
@@ -1000,7 +1064,7 @@ java_handle_objectarray_t *stacktrace_getClassContext(void)
 
        CYCLES_STATS_END(stacktrace_getClassContext)
 
-       return oa;
+       return ca.get_handle();
 }
 
 
@@ -1092,15 +1156,12 @@ classinfo *stacktrace_get_current_class(void)
 #if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
 java_handle_objectarray_t *stacktrace_get_stack(void)
 {
-       stackframeinfo_t          *sfi;
-       stackframeinfo_t           tmpsfi;
-       int                        depth;
-       java_handle_objectarray_t *oa;
-       java_handle_objectarray_t *classes;
-       java_handle_objectarray_t *methodnames;
-       methodinfo                *m;
-       java_handle_t             *string;
-       int                        i;
+       stackframeinfo_t *sfi;
+       stackframeinfo_t  tmpsfi;
+       int               depth;
+       methodinfo       *m;
+       java_handle_t    *string;
+       int               i;
 
        CYCLES_STATS_DECLARE_AND_START
 
@@ -1122,25 +1183,23 @@ java_handle_objectarray_t *stacktrace_get_stack(void)
 
        /* Allocate the required arrays. */
 
-       oa = builtin_anewarray(2, arrayclass_java_lang_Object);
+       ObjectArray oa(2, arrayclass_java_lang_Object);
+       ClassArray  classes(depth);
+       ObjectArray methodnames(depth, class_java_lang_String);
 
-       if (oa == NULL)
+       if (oa.is_null())
                goto return_NULL;
 
-       classes = builtin_anewarray(depth, class_java_lang_Class);
-
-       if (classes == NULL)
+       if (classes.is_null())
                goto return_NULL;
 
-       methodnames = builtin_anewarray(depth, class_java_lang_String);
-
-       if (methodnames == NULL)
+       if (methodnames.is_null())
                goto return_NULL;
 
        /* Set up the 2-dimensional array. */
 
-       array_objectarray_element_set(oa, 0, (java_handle_t *) classes);
-       array_objectarray_element_set(oa, 1, (java_handle_t *) methodnames);
+       oa.set_element(0, (java_handle_t *) classes.get_handle());
+       oa.set_element(1, (java_handle_t *) methodnames.get_handle());
 
        /* Iterate over the whole stack. */
        /* TODO We should use a critical section here to speed things
@@ -1161,10 +1220,8 @@ java_handle_objectarray_t *stacktrace_get_stack(void)
                        continue;
 
                /* Store the class in the array. */
-               /* NOTE: We use a LLNI-macro here, because a classinfo is not
-                  a handle. */
 
-               LLNI_array_direct(classes, i) = (java_object_t *) m->clazz;
+               classes.set_element(i, m->clazz);
 
                /* Store the name in the array. */
 
@@ -1173,14 +1230,14 @@ java_handle_objectarray_t *stacktrace_get_stack(void)
                if (string == NULL)
                        goto return_NULL;
 
-               array_objectarray_element_set(methodnames, i, string);
+               methodnames.set_element(i, string);
 
                i++;
        }
 
        CYCLES_STATS_END(stacktrace_get_stack)
 
-       return oa;
+       return oa.get_handle();
 
 return_NULL:
        CYCLES_STATS_END(stacktrace_get_stack)
@@ -1324,16 +1381,18 @@ void stacktrace_print_current(void)
 stacktrace_t* stacktrace_get_of_thread(threadobject* t)
 {
        stackframeinfo_t*        sfi;
-       java_handle_bytearray_t* ba;
+       java_handle_bytearray_t* stba;
        stacktrace_t*            st;
 
-       sfi = t->_stackframeinfo;
-       ba  = stacktrace_get(sfi);
+       sfi  = t->_stackframeinfo;
+       stba = stacktrace_get(sfi);
+
+       ByteArray ba(stba);
 
-       if (ba == NULL)
+       if (ba.is_null())
                return NULL;
 
-       st  = (stacktrace_t*) LLNI_array_data(ba);
+       st  = (stacktrace_t*) ba.get_raw_data_ptr();
 
        return st;
 }
@@ -1407,11 +1466,11 @@ void stacktrace_print_exception(java_handle_t *h)
 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
 
        java_lang_VMThrowable vmt(t.get_vmState());
-       java_handle_bytearray_t* backtrace = vmt.get_vmdata();
+       ByteArray backtrace(vmt.get_vmdata());
 
 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
 
-       java_handle_bytearray_t* backtrace = t.get_backtrace();
+       ByteArray backtrace(t.get_backtrace());
 
 #else
 # error unknown classpath configuration
@@ -1419,14 +1478,14 @@ void stacktrace_print_exception(java_handle_t *h)
 
        // Sanity check.
 
-       assert(backtrace != NULL);
+       assert(backtrace.is_non_null());
 
        /* We need a critical section here as we use the byte-array data
           pointer directly. */
 
        LLNI_CRITICAL_START;
        
-       stacktrace_t* st = (stacktrace_t*) LLNI_array_data(backtrace);
+       stacktrace_t* st = (stacktrace_t*) backtrace.get_raw_data_ptr();
 
        stacktrace_print(st);
 
index 2c2920c826b55de4d14e1b517dd824f176b06fce..ee032b2a2107606662dc0bb1faba4cb1637e3f78 100644 (file)
@@ -110,6 +110,7 @@ java_handle_t*             stacktrace_get_StackTraceElement(stacktrace_t *st, in
 java_handle_objectarray_t* stacktrace_get_StackTraceElements(stacktrace_t *st);
 classinfo                 *stacktrace_get_caller_class(int depth);
 classloader_t             *stacktrace_first_nonnull_classloader(void);
+classloader_t             *stacktrace_first_nonsystem_classloader(void);
 java_handle_objectarray_t *stacktrace_getClassContext(void);
 classinfo                 *stacktrace_get_current_class(void);
 java_handle_objectarray_t *stacktrace_get_stack(void);
index 98667f76cc0692b9ef3a08a1fd9e5dcbbe01f98a..f6dd77abae0d6f6d036637b0940cdd7beefb8adc 100644 (file)
@@ -38,6 +38,7 @@
 
 #include "toolbox/logging.hpp"
 
+#include "vm/array.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
 #include "vm/javaobjects.hpp"
@@ -569,9 +570,11 @@ void trace_exception_builtin(java_handle_t* h)
                logtextlen += utf_bytes(jlt.get_vftbl()->clazz->name);
 
                if (jls.get_handle()) {
+                       CharArray ca(jls.get_value());
                        // FIXME This is not handle capable!
+                       uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
                        logtextlen += strlen(": ") +
-                               u2_utflength(jls.get_value()->data + jls.get_offset(), jls.get_count());
+                               u2_utflength(ptr + jls.get_offset(), jls.get_count());
                }
        } 
        else {
index 083f00b30a7f8d2e6fa034fa7dc286af018de523..e697a97ddbc5e693724a63f986815218170467cb 100644 (file)
@@ -2,6 +2,7 @@
 
    Copyright (C) 1996-2005, 2006, 2007, 2008
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+   Copyright (C) 2009 Theobroma Systems Ltd.
 
    This file is part of CACAO.
 
@@ -47,6 +48,7 @@
 #include "vm/field.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
+#include "vm/javaobjects.hpp"
 #include "vm/linker.hpp"
 #include "vm/loader.hpp"
 #include "vm/method.hpp"
@@ -991,37 +993,22 @@ bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
 
 *******************************************************************************/
 
+#if defined(ENABLE_JAVASE)
 classinfo *load_class_from_sysloader(utf *name)
 {
-       methodinfo    *m;
-       java_handle_t *clo;
        classloader_t *cl;
        classinfo     *c;
 
-       assert(class_java_lang_Object);
-       assert(class_java_lang_ClassLoader);
-       assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
-       
-       m = class_resolveclassmethod(class_java_lang_ClassLoader,
-                                                                utf_getSystemClassLoader,
-                                                                utf_void__java_lang_ClassLoader,
-                                                                class_java_lang_Object,
-                                                                false);
+       cl = java_lang_ClassLoader::invoke_getSystemClassLoader();
 
-       if (!m)
-               return false;
-
-       clo = vm_call_method(m, NULL);
-
-       if (!clo)
+       if (cl == NULL)
                return false;
 
-       cl = loader_hashtable_classloader_add(clo);
-
        c = load_class_from_classloader(name, cl);
 
        return c;
 }
+#endif /* defined(ENABLE_JAVASE) */
 
 
 /* load_class_from_classloader *************************************************
@@ -1188,6 +1175,18 @@ classinfo *load_class_from_classloader(utf *name, classloader_t *cl)
 
                        c = tmpc;
                }
+               else {
+                       // Expected behavior for the classloader is to throw an exception
+                       // and never return NULL. If the classloader shows a different
+                       // behavior, we are correcting it here (see PR126).
+                       if (exceptions_get_exception() == NULL) {
+#if !defined(NDEBUG)
+                               if (opt_PrintWarnings)
+                                       log_message_utf("load_class_from_classloader: Correcting faulty classloader behavior (PR126) for ", name);
+#endif
+                               exceptions_throw_classnotfoundexception(name);
+                       }
+               }
 
                RT_TIMING_GET_TIME(time_cache);
 
index 21f542400075da4e55c13da38236e24826c61996..4a166020146d006377d38f33694cbeffd02b347e 100644 (file)
@@ -201,7 +201,15 @@ bool method_load(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
                }
        }
 #endif /* ENABLE_VERIFIER */
-       
+
+       /* Ignore flags for class initializer according to section 4.6
+          of "The Java Virtual Machine Specification, 2nd Edition" (see PR125). */
+
+       if (m->name == utf_clinit) {
+               m->flags &= ACC_STRICT;
+               m->flags |= ACC_STATIC;
+       }
+
        if (!(m->flags & ACC_STATIC))
                argcount++; /* count the 'this' argument */
 
@@ -699,12 +707,11 @@ int32_t method_get_parametercount(methodinfo *m)
 
 java_handle_objectarray_t *method_get_parametertypearray(methodinfo *m)
 {
-       methoddesc                *md;
-       typedesc                  *paramtypes;
-       int32_t                    paramcount;
-       java_handle_objectarray_t *oa;
-       int32_t                    i;
-       classinfo                 *c;
+       methoddesc* md;
+       typedesc*   paramtypes;
+       int32_t     paramcount;
+       int32_t     i;
+       classinfo*  c;
 
        md = m->parseddesc;
 
@@ -726,9 +733,9 @@ java_handle_objectarray_t *method_get_parametertypearray(methodinfo *m)
 
        /* create class-array */
 
-       oa = builtin_anewarray(paramcount, class_java_lang_Class);
+       ClassArray ca(paramcount);
 
-       if (oa == NULL)
+       if (ca.is_null())
                return NULL;
 
     /* get classes */
@@ -737,10 +744,10 @@ java_handle_objectarray_t *method_get_parametertypearray(methodinfo *m)
                if (!resolve_class_from_typedesc(&paramtypes[i], true, false, &c))
                        return NULL;
 
-               LLNI_array_direct(oa, i) = (java_object_t *) c;
+               ca.set_element(i, c);
        }
 
-       return oa;
+       return ca.get_handle();
 }
 
 
@@ -752,15 +759,14 @@ java_handle_objectarray_t *method_get_parametertypearray(methodinfo *m)
 
 java_handle_objectarray_t *method_get_exceptionarray(methodinfo *m)
 {
-       java_handle_objectarray_t *oa;
-       classinfo                 *c;
-       s4                         i;
+       classinfo* c;
+       s4         i;
 
        /* create class-array */
 
-       oa = builtin_anewarray(m->thrownexceptionscount, class_java_lang_Class);
+       ClassArray ca(m->thrownexceptionscount);
 
-       if (oa == NULL)
+       if (ca.is_null())
                return NULL;
 
        /* iterate over all exceptions and store the class in the array */
@@ -771,10 +777,10 @@ java_handle_objectarray_t *method_get_exceptionarray(methodinfo *m)
                if (c == NULL)
                        return NULL;
 
-               LLNI_array_direct(oa, i) = (java_object_t *) c;
+               ca.set_element(i, c);
        }
 
-       return oa;
+       return ca.get_handle();
 }
 
 
@@ -864,26 +870,24 @@ java_handle_bytearray_t *method_get_annotations(methodinfo *m)
 #if defined(ENABLE_ANNOTATIONS)
        classinfo     *c;                  /* methods' declaring class          */
        int            slot;               /* methods' slot                     */
-       java_handle_t *annotations;        /* methods' unparsed annotations     */
        java_handle_t *method_annotations; /* all methods' unparsed annotations */
                                           /* of the declaring class            */
 
-       c           = m->clazz;
-       slot        = m - c->methods;
-       annotations = NULL;
+       c    = m->clazz;
+       slot = m - c->methods;
 
        LLNI_classinfo_field_get(c, method_annotations, method_annotations);
 
+       ObjectArray oa((java_handle_objectarray_t*) method_annotations);
+
        /* the method_annotations array might be shorter then the method
         * count if the methods above a certain index have no annotations.
         */     
-       if (method_annotations != NULL &&
-               array_length_get(method_annotations) > slot) {
-               annotations = array_objectarray_element_get(
-                       (java_handle_objectarray_t*)method_annotations, slot);
+       if (method_annotations != NULL && oa.get_length() > slot) {
+               return (java_handle_bytearray_t*) oa.get_element(slot);
+       } else {
+               return NULL;
        }
-       
-       return (java_handle_bytearray_t*)annotations;
 #else
        return NULL;
 #endif
@@ -910,30 +914,26 @@ java_handle_bytearray_t *method_get_parameterannotations(methodinfo *m)
 #if defined(ENABLE_ANNOTATIONS)
        classinfo     *c;                           /* methods' declaring class */
        int            slot;                        /* methods' slot            */
-       java_handle_t *parameterAnnotations;        /* methods' unparsed        */
-                                                   /* parameter annotations    */
        java_handle_t *method_parameterannotations; /* all methods' unparsed    */
                                                    /* parameter annotations of */
                                                    /* the declaring class      */
 
-       c                    = m->clazz;
-       slot                 = m - c->methods;
-       parameterAnnotations = NULL;
+       c    = m->clazz;
+       slot = m - c->methods;
 
        LLNI_classinfo_field_get(
                c, method_parameterannotations, method_parameterannotations);
 
+       ObjectArray oa((java_handle_objectarray_t*) method_parameterannotations);
+
        /* the method_annotations array might be shorter then the method
         * count if the methods above a certain index have no annotations.
         */     
-       if (method_parameterannotations != NULL &&
-               array_length_get(method_parameterannotations) > slot) {
-               parameterAnnotations = array_objectarray_element_get(
-                               (java_handle_objectarray_t*)method_parameterannotations,
-                               slot);
+       if (method_parameterannotations != NULL && oa.get_length() > slot) {
+               return (java_handle_bytearray_t*) oa.get_element(slot);
+       } else {
+               return NULL;
        }
-       
-       return (java_handle_bytearray_t*)parameterAnnotations;
 #else
        return NULL;
 #endif
@@ -959,29 +959,26 @@ java_handle_bytearray_t *method_get_annotationdefault(methodinfo *m)
 #if defined(ENABLE_ANNOTATIONS)
        classinfo     *c;                         /* methods' declaring class     */
        int            slot;                      /* methods' slot                */
-       java_handle_t *annotationDefault;         /* methods' unparsed            */
-                                                 /* annotation default value     */
        java_handle_t *method_annotationdefaults; /* all methods' unparsed        */
                                                  /* annotation default values of */
                                                  /* the declaring class          */
 
-       c                 = m->clazz;
-       slot              = m - c->methods;
-       annotationDefault = NULL;
+       c    = m->clazz;
+       slot = m - c->methods;
 
        LLNI_classinfo_field_get(
                c, method_annotationdefaults, method_annotationdefaults);
 
+       ObjectArray oa((java_handle_objectarray_t*) method_annotationdefaults);
+
        /* the method_annotations array might be shorter then the method
         * count if the methods above a certain index have no annotations.
-        */     
-       if (method_annotationdefaults != NULL &&
-               array_length_get(method_annotationdefaults) > slot) {
-               annotationDefault = array_objectarray_element_get(
-                               (java_handle_objectarray_t*)method_annotationdefaults, slot);
+        */
+       if (method_annotationdefaults != NULL && oa.get_length() > slot) {
+               return (java_handle_bytearray_t*) oa.get_element(slot);
+       } else {
+               return NULL;
        }
-       
-       return (java_handle_bytearray_t*)annotationDefault;
 #else
        return NULL;
 #endif
index 7ead267c6ef226f565a64d5ebd62b6508efdf35f..cc94d11cd966cd7907fa403f4359e72b6296eaac 100644 (file)
@@ -190,6 +190,7 @@ int      opt_InlineMinSize                = 0;
 #endif
 #endif
 int      opt_PrintConfig                  = 0;
+int      opt_PrintWarnings                = 0;
 int      opt_ProfileGCMemoryUsage         = 0;
 int      opt_ProfileMemoryUsage           = 0;
 FILE    *opt_ProfileMemoryUsageGNUPlot    = NULL;
@@ -254,6 +255,7 @@ enum {
        OPT_InlineMaxSize,
        OPT_InlineMinSize,
        OPT_PrintConfig,
+       OPT_PrintWarnings,
        OPT_ProfileGCMemoryUsage,
        OPT_ProfileMemoryUsage,
        OPT_ProfileMemoryUsageGNUPlot,
@@ -321,6 +323,7 @@ option_t options_XX[] = {
 #endif
 #endif
        { "PrintConfig",                  OPT_PrintConfig,                  OPT_TYPE_BOOLEAN, "print VM configuration" },
+       { "PrintWarnings",                OPT_PrintWarnings,                OPT_TYPE_BOOLEAN, "print warnings about suspicious behavior"},
        { "ProfileGCMemoryUsage",         OPT_ProfileGCMemoryUsage,         OPT_TYPE_VALUE,   "profiles GC memory usage in the given interval, <value> is in seconds (default: 5)" },
        { "ProfileMemoryUsage",           OPT_ProfileMemoryUsage,           OPT_TYPE_VALUE,   "TODO" },
        { "ProfileMemoryUsageGNUPlot",    OPT_ProfileMemoryUsageGNUPlot,    OPT_TYPE_VALUE,   "TODO" },
@@ -735,6 +738,10 @@ void options_xx(JavaVMInitArgs *vm_args)
                        opt_PrintConfig = enable;
                        break;
 
+               case OPT_PrintWarnings:
+                       opt_PrintWarnings = enable;
+                       break;
+
                case OPT_ProfileGCMemoryUsage:
                        if (value == NULL)
                                opt_ProfileGCMemoryUsage = 5;
index 18c1c0013ebe8e04af82c0b06544a5f953b11d5c..a5b6932703867c9b4877f9a7c3795167cc4007e6 100644 (file)
@@ -212,6 +212,7 @@ extern int      opt_InlineMinSize;
 #endif
 #endif
 extern int      opt_PrintConfig;
+extern int      opt_PrintWarnings;
 extern int      opt_ProfileGCMemoryUsage;
 extern int      opt_ProfileMemoryUsage;
 extern FILE    *opt_ProfileMemoryUsageGNUPlot;
index 4d3c6542c18226cea5af4b51524d700c3adac8d0..388c08e2aa945e14d36db662e748568355999ed8 100644 (file)
@@ -480,6 +480,161 @@ imm_union Primitive::unbox(java_handle_t *h)
 }
 
 
+/**
+ * Unbox a primitive of the given type. Also checks if the
+ * boxed primitive type can be widened into the destination
+ * type. This conversion is done according to
+ * "The Java Language Specification, Third Edition,
+ * $5.1.2 Widening Primitive Conversion".
+ *
+ * @param h Handle of the boxing Java object.
+ * @param type Destination type of the conversion.
+ * @param value Pointer to union where the resulting primitive
+ * value will be stored will.
+ *
+ * @return True of the conversion is allowed, false otherwise.
+ */
+bool Primitive::unbox_typed(java_handle_t *h, int type, imm_union* value)
+{
+       classinfo *c;
+       int        src_type;
+
+       if (h == NULL)
+               return false;
+
+       LLNI_class_get(h, c);
+
+       src_type = get_type_by_wrapperclass(c);
+
+       switch (src_type) {
+       case PRIMITIVETYPE_BOOLEAN:
+               switch (type) {
+                       case PRIMITIVETYPE_BOOLEAN:
+                               value->i = unbox_boolean(h);
+                               return true;
+                       default:
+                               return false;
+               }
+
+       case PRIMITIVETYPE_BYTE:
+               switch (type) {
+                       case PRIMITIVETYPE_BYTE:
+                       case PRIMITIVETYPE_SHORT:
+                       case PRIMITIVETYPE_INT:
+                               value->i = unbox_byte(h);
+                               return true;
+                       case PRIMITIVETYPE_LONG:
+                               value->l = unbox_byte(h);
+                               return true;
+                       case PRIMITIVETYPE_FLOAT:
+                               value->f = unbox_byte(h);
+                               return true;
+                       case PRIMITIVETYPE_DOUBLE:
+                               value->d = unbox_byte(h);
+                               return true;
+                       default:
+                               return false;
+               }
+
+       case PRIMITIVETYPE_CHAR:
+               switch (type) {
+                       case PRIMITIVETYPE_CHAR:
+                       case PRIMITIVETYPE_INT:
+                               value->i = unbox_char(h);
+                               return true;
+                       case PRIMITIVETYPE_LONG:
+                               value->l = unbox_char(h);
+                               return true;
+                       case PRIMITIVETYPE_FLOAT:
+                               value->f = unbox_char(h);
+                               return true;
+                       case PRIMITIVETYPE_DOUBLE:
+                               value->d = unbox_char(h);
+                               return true;
+                       default:
+                               return false;
+               }
+
+       case PRIMITIVETYPE_SHORT:
+               switch (type) {
+                       case PRIMITIVETYPE_SHORT:
+                       case PRIMITIVETYPE_INT:
+                               value->i = unbox_short(h);
+                               return true;
+                       case PRIMITIVETYPE_LONG:
+                               value->l = unbox_short(h);
+                               return true;
+                       case PRIMITIVETYPE_FLOAT:
+                               value->f = unbox_short(h);
+                               return true;
+                       case PRIMITIVETYPE_DOUBLE:
+                               value->d = unbox_short(h);
+                               return true;
+                       default:
+                               return false;
+               }
+
+       case PRIMITIVETYPE_INT:
+               switch (type) {
+                       case PRIMITIVETYPE_INT:
+                               value->i = unbox_int(h);
+                               return true;
+                       case PRIMITIVETYPE_LONG:
+                               value->l = unbox_int(h);
+                               return true;
+                       case PRIMITIVETYPE_FLOAT:
+                               value->f = unbox_int(h);
+                               return true;
+                       case PRIMITIVETYPE_DOUBLE:
+                               value->d = unbox_int(h);
+                               return true;
+                       default:
+                               return false;
+               }
+
+       case PRIMITIVETYPE_LONG:
+               switch (type) {
+                       case PRIMITIVETYPE_LONG:
+                               value->l = unbox_long(h);
+                               return true;
+                       case PRIMITIVETYPE_FLOAT:
+                               value->f = unbox_long(h);
+                               return true;
+                       case PRIMITIVETYPE_DOUBLE:
+                               value->d = unbox_long(h);
+                               return true;
+                       default:
+                               return false;
+               }
+
+       case PRIMITIVETYPE_FLOAT:
+               switch (type) {
+                       case PRIMITIVETYPE_FLOAT:
+                               value->f = unbox_float(h);
+                               return true;
+                       case PRIMITIVETYPE_DOUBLE:
+                               value->d = unbox_float(h);
+                               return true;
+                       default:
+                               return false;
+               }
+
+       case PRIMITIVETYPE_DOUBLE:
+               switch (type) {
+                       case PRIMITIVETYPE_DOUBLE:
+                               value->d = unbox_double(h);
+                               return true;
+                       default:
+                               return false;
+               }
+
+       default:
+               os::abort("Primitive::unbox_typed: Invalid primitive type %d", type);
+               return false;
+       }
+}
+
+
 /**
  * Box a primitive type.
  */
index 314bb05d47b4d598f5c73834ba9a1981dbbad0b7..a0c97176e7dc37387b4ead2897a6b5b08e87d6fc 100644 (file)
@@ -63,6 +63,7 @@ public:
        static java_handle_t* box(double value);
 
        static imm_union      unbox(java_handle_t *o);
+       static bool           unbox_typed(java_handle_t *o, int type, imm_union* value);
 
        static uint8_t        unbox_boolean(java_handle_t* o);
        static int8_t         unbox_byte(java_handle_t* o);
index 632f69e040da2314fe6adae59b1bbb039173f403..45b4ad46ebffcf421c594820e695361ad2c16980 100644 (file)
@@ -93,7 +93,6 @@ bool string_init(void)
  
 void stringtable_update(void)
 {
-       java_chararray_t *a;
        literalstring    *s;       /* hashtable entry */
 
        for (unsigned int i = 0; i < hashtable_string.size; i++) {
@@ -109,7 +108,7 @@ void stringtable_update(void)
                                        os::abort("stringtable_update: invalid literalstring in hashtable");
                                }
 
-                               a = LLNI_UNWRAP(js.get_value());
+                               java_chararray_t* a = (java_chararray_t*) js.get_value();
 
                                if (js.get_vftbl() == NULL)
                                        // FIXME
@@ -150,23 +149,26 @@ static java_handle_t *javastring_new_from_utf_buffer(const char *buffer, u4 blen
        int32_t utflength = utf_get_number_of_u2s_for_buffer(buffer, blength);
 
        java_handle_t*           h  = builtin_new(class_java_lang_String);
-       java_handle_chararray_t* ca = builtin_newarray_char(utflength);
+       CharArray ca(utflength);
 
        /* javastring or character-array could not be created */
 
-       if ((h == NULL) || (ca == NULL))
+       if ((h == NULL) || ca.is_null())
                return NULL;
 
+       // XXX: Fix me!
+       uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
+
        /* decompress utf-string */
 
        utf_ptr = buffer;
 
        for (int32_t i = 0; i < utflength; i++)
-               LLNI_array_direct(ca, i) = utf_nextu2((char **) &utf_ptr);
+               ptr[i] = utf_nextu2((char **) &utf_ptr);
        
        /* set fields of the javastring-object */
 
-       java_lang_String jls(h, ca, utflength);
+       java_lang_String jls(h, ca.get_handle(), utflength);
 
        return jls.get_handle();
 }
@@ -204,20 +206,23 @@ java_handle_t *javastring_safe_new_from_utf8(const char *text)
        /* allocate the String object and the char array */
 
        java_handle_t*           h  = builtin_new(class_java_lang_String);
-       java_handle_chararray_t* ca = builtin_newarray_char(len);
+       CharArray ca(len);
 
        /* javastring or character-array could not be created? */
 
-       if ((h == NULL) || (ca == NULL))
+       if ((h == NULL) || ca.is_null())
                return NULL;
 
+       // XXX: Fix me!
+       uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
+
        /* decompress UTF-8 string */
 
-       utf8_safe_convert_to_u2s(text, nbytes, LLNI_array_data(ca));
+       utf8_safe_convert_to_u2s(text, nbytes, ptr);
 
        /* set fields of the String object */
 
-       java_lang_String jls(h, ca, len);
+       java_lang_String jls(h, ca.get_handle(), len);
 
        return jls.get_handle();
 }
@@ -266,21 +271,24 @@ java_handle_t *javastring_new(utf *u)
        int32_t utflength = utf_get_number_of_u2s(u);
 
        java_handle_t*           h  = builtin_new(class_java_lang_String);
-       java_handle_chararray_t* ca = builtin_newarray_char(utflength);
+       CharArray ca(utflength);
 
        /* javastring or character-array could not be created */
 
-       if ((h == NULL) || (ca == NULL))
+       if ((h == NULL) || ca.is_null())
                return NULL;
 
+       // XXX: Fix me!
+       uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
+
        /* decompress utf-string */
 
        for (int32_t i = 0; i < utflength; i++)
-               LLNI_array_direct(ca, i) = utf_nextu2(&utf_ptr);
+               ptr[i] = utf_nextu2(&utf_ptr);
        
        /* set fields of the javastring-object */
 
-       java_lang_String jls(h, ca, utflength);
+       java_lang_String jls(h, ca.get_handle(), utflength);
 
        return jls.get_handle();
 }
@@ -306,12 +314,15 @@ java_handle_t *javastring_new_slash_to_dot(utf *u)
        int32_t utflength = utf_get_number_of_u2s(u);
 
        java_handle_t*           h  = builtin_new(class_java_lang_String);
-       java_handle_chararray_t* ca = builtin_newarray_char(utflength);
+       CharArray ca(utflength);
 
        /* javastring or character-array could not be created */
-       if ((h == NULL) || (ca == NULL))
+       if ((h == NULL) || ca.is_null())
                return NULL;
 
+       // XXX: Fix me!
+       uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
+
        /* decompress utf-string */
 
        for (int32_t i = 0; i < utflength; i++) {
@@ -320,12 +331,12 @@ java_handle_t *javastring_new_slash_to_dot(utf *u)
                if (ch == '/')
                        ch = '.';
 
-               LLNI_array_direct(ca, i) = ch;
+               ptr[i] = ch;
        }
        
        /* set fields of the javastring-object */
 
-       java_lang_String jls(h, ca, utflength);
+       java_lang_String jls(h, ca.get_handle(), utflength);
 
        return jls.get_handle();
 }
@@ -355,21 +366,24 @@ java_handle_t *javastring_new_from_ascii(const char *text)
        int32_t len = strlen(text);
 
        java_handle_t*           h  = builtin_new(class_java_lang_String);
-       java_handle_chararray_t* ca = builtin_newarray_char(len);
+       CharArray ca(len);
 
        /* javastring or character-array could not be created */
 
-       if ((h == NULL) || (ca == NULL))
+       if ((h == NULL) || ca.is_null())
                return NULL;
 
+       // XXX: Fix me!
+       uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
+
        /* copy text */
 
        for (int32_t i = 0; i < len; i++)
-               LLNI_array_direct(ca, i) = text[i];
+               ptr[i] = text[i];
        
        /* set fields of the javastring-object */
 
-       java_lang_String jls(h, ca, len);
+       java_lang_String jls(h, ca.get_handle(), len);
 
        return jls.get_handle();
 }
@@ -392,9 +406,9 @@ char* javastring_tochar(java_handle_t* h)
        if (jls.is_null())
                return (char*) "";
 
-       java_handle_chararray_t* ca = jls.get_value();
+       CharArray ca(jls.get_value());
 
-       if (ca == NULL)
+       if (ca.is_null())
                return (char*) "";
 
        int32_t count  = jls.get_count();
@@ -402,9 +416,12 @@ char* javastring_tochar(java_handle_t* h)
 
        char* buf = MNEW(char, count + 1);
 
+       // XXX: Fix me!
+       uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
+
        int32_t i;
        for (i = 0; i < count; i++)
-               buf[i] = LLNI_array_direct(ca, offset + i);
+               buf[i] = ptr[offset + i];
 
        buf[i] = '\0';
 
@@ -425,15 +442,18 @@ utf *javastring_toutf(java_handle_t *string, bool isclassname)
        if (jls.is_null())
                return utf_null;
 
-       java_handle_chararray_t* value = jls.get_value();
+       CharArray ca(jls.get_value());
 
-       if (jls.get_value() == NULL)
+       if (ca.is_null())
                return utf_null;
 
        int32_t count  = jls.get_count();
        int32_t offset = jls.get_offset();
 
-       return utf_new_u2(LLNI_array_data(value) + offset, count, isclassname);
+       // XXX: Fix me!
+       uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
+
+       return utf_new_u2(ptr + offset, count, isclassname);
 }
 
 
@@ -446,35 +466,41 @@ utf *javastring_toutf(java_handle_t *string, bool isclassname)
 
 *******************************************************************************/
 
-static java_object_t *literalstring_u2(java_chararray_t *a, int32_t length,
+static java_handle_t *literalstring_u2(java_handle_chararray_t *a, int32_t length,
                                                                           u4 offset, bool copymode)
 {
-    literalstring    *s;                /* hashtable element                  */
-    java_chararray_t *ca;               /* copy of u2-array                   */
-    u4                key;
-    u4                slot;
-    u2                i;
+       literalstring    *s;                /* hashtable element                  */
+       u4                key;
+       u4                slot;
+       u2                i;
 
        mutex->lock();
 
-    /* find location in hashtable */
+       // XXX: Fix me!
+       CharArray ca(a);
+       uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
+
+       /* find location in hashtable */
 
-    key  = unicode_hashkey(a->data + offset, length);
-    slot = key & (hashtable_string.size - 1);
-    s    = (literalstring*) hashtable_string.ptr[slot];
+       key  = unicode_hashkey(ptr + offset, length);
+       slot = key & (hashtable_string.size - 1);
+       s    = (literalstring*) hashtable_string.ptr[slot];
 
-    while (s) {
+       while (s) {
                // FIXME
                java_lang_String js(LLNI_WRAP(s->string));
 
                if (length == js.get_count()) {
                        /* compare text */
 
-                       for (i = 0; i < length; i++)
+                       for (i = 0; i < length; i++) {
                                // FIXME This is not handle capable!
+                               CharArray jsca(js.get_value());
+                               uint16_t* sptr = (uint16_t*) jsca.get_raw_data_ptr();
                                
-                               if (a->data[offset + i] != ((java_chararray_t*) LLNI_UNWRAP(js.get_value()))->data[i])
+                               if (ptr[offset + i] != sptr[i])
                                        goto nomatch;
+                       }
 
                        /* string already in hashtable, free memory */
 
@@ -483,38 +509,37 @@ static java_object_t *literalstring_u2(java_chararray_t *a, int32_t length,
 
                        mutex->unlock();
 
-                       return (java_object_t*) LLNI_UNWRAP(js.get_handle());
+                       return js.get_handle();
                }
 
        nomatch:
                /* follow link in external hash chain */
                s = s->hashlink;
-    }
+       }
 
-    if (copymode) {
+       java_chararray_t* acopy;
+       if (copymode) {
                /* create copy of u2-array for new javastring */
                u4 arraysize = sizeof(java_chararray_t) + sizeof(u2) * (length - 1) + 10;
-               ca = (java_chararray_t*) mem_alloc(arraysize);
+               acopy = (java_chararray_t*) mem_alloc(arraysize);
 /*             memcpy(ca, a, arraysize); */
-               memcpy(&(ca->header), &(a->header), sizeof(java_array_t));
-               memcpy(&(ca->data), &(a->data) + offset, sizeof(u2) * (length - 1) + 10);
-    }
+               memcpy(&(acopy->header), &(((java_chararray_t*) a)->header), sizeof(java_array_t));
+               memcpy(&(acopy->data), &(((java_chararray_t*) a)->data) + offset, sizeof(u2) * (length - 1) + 10);
+       }
        else {
-               ca = a;
+               acopy = (java_chararray_t*) a;
        }
 
-    /* location in hashtable found, complete arrayheader */
+       /* location in hashtable found, complete arrayheader */
 
-    ca->header.objheader.vftbl = Primitive::get_arrayclass_by_type(ARRAYTYPE_CHAR)->vftbl;
-    ca->header.size            = length;
+       acopy->header.objheader.vftbl = Primitive::get_arrayclass_by_type(ARRAYTYPE_CHAR)->vftbl;
+       acopy->header.size            = length;
 
        assert(class_java_lang_String);
        assert(class_java_lang_String->state & CLASS_LOADED);
 
        // Create a new java.lang.String object on the system heap.
        java_object_t* o = (java_object_t*) MNEW(uint8_t, class_java_lang_String->instancesize);
-       // FIXME
-       java_handle_t* h = LLNI_WRAP(o);
 
 #if defined(ENABLE_STATISTICS)
        if (opt_stat)
@@ -527,8 +552,8 @@ static java_object_t *literalstring_u2(java_chararray_t *a, int32_t length,
 
        o->vftbl = class_java_lang_String->vftbl;
 
-       // FIXME
-       java_lang_String jls(h, LLNI_WRAP(ca), length);
+       CharArray cacopy((java_handle_chararray_t*) acopy);
+       java_lang_String jls(o, cacopy.get_handle(), length);
 
        /* create new literalstring */
 
@@ -603,23 +628,23 @@ static java_object_t *literalstring_u2(java_chararray_t *a, int32_t length,
 
 java_object_t *literalstring_new(utf *u)
 {
-    char             *utf_ptr;       /* pointer to current unicode character  */
+       char             *utf_ptr;       /* pointer to current unicode character  */
                                         /* utf string                            */
-    u4                utflength;     /* length of utf-string if uncompressed  */
-    java_chararray_t *a;             /* u2-array constructed from utf string  */
-    u4                i;
+       u4                utflength;     /* length of utf-string if uncompressed  */
+       java_chararray_t *a;             /* u2-array constructed from utf string  */
+       u4                i;
 
        utf_ptr = u->text;
        utflength = utf_get_number_of_u2s(u);
 
-    /* allocate memory */ 
-    a = (java_chararray_t*) mem_alloc(sizeof(java_chararray_t) + sizeof(u2) * (utflength - 1) + 10);
+       /* allocate memory */ 
+       a = (java_chararray_t*) mem_alloc(sizeof(java_chararray_t) + sizeof(u2) * (utflength - 1) + 10);
 
-    /* convert utf-string to u2-array */
-    for (i = 0; i < utflength; i++)
+       /* convert utf-string to u2-array */
+       for (i = 0; i < utflength; i++)
                a->data[i] = utf_nextu2(&utf_ptr);
 
-    return literalstring_u2(a, utflength, 0, false);
+       return literalstring_u2((java_handle_chararray_t*) a, utflength, 0, false);
 }
 
 
@@ -653,25 +678,20 @@ static void literalstring_free(java_object_t* string)
 
    Intern the given Java string.
 
-   XXX NOTE: Literal Strings are direct references since they are not placed
-   onto the GC-Heap. That's why this function looks so "different".
-
 *******************************************************************************/
 
 java_handle_t *javastring_intern(java_handle_t *string)
 {
        java_lang_String jls(string);
 
-       java_handle_chararray_t* value = jls.get_value();
-       // FIXME
-       java_chararray_t* ca = LLNI_UNWRAP(value); /* XXX see note above */
+       CharArray ca(jls.get_value());
 
        int32_t count  = jls.get_count();
        int32_t offset = jls.get_offset();
 
-       java_object_t* o = literalstring_u2(ca, count, offset, true); /* XXX see note above */
+       java_handle_t* o = literalstring_u2(ca.get_handle(), count, offset, true);
 
-       return LLNI_WRAP(o); /* XXX see note above */
+       return o;
 }
 
 
@@ -685,13 +705,16 @@ void javastring_fprint(java_handle_t *s, FILE *stream)
 {
        java_lang_String jls(s);
 
-       java_handle_chararray_t* value = jls.get_value();
+       CharArray ca(jls.get_value());
 
        int32_t count  = jls.get_count();
        int32_t offset = jls.get_offset();
 
+       // XXX: Fix me!
+       uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
+
        for (int32_t i = offset; i < offset + count; i++) {
-               uint16_t c = LLNI_array_direct(value, i);
+               uint16_t c = ptr[i];
                fputc(c, stream);
        }
 }
index 8cbc0ed5cfb59e63e9f2c6fe8b7bffaa8a76e8d7..1239da685cfc3c129b10ff7f81576d1a2ee68b83 100644 (file)
@@ -1577,21 +1577,8 @@ void VM::print_run_time_config()
 
 void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
 {
-       char*                      option;
-       char*                      mainname;
-       char*                      p;
-       utf                       *mainutf;
-       classinfo                 *mainclass;
-       java_handle_t             *e;
-       methodinfo                *m;
-       java_handle_objectarray_t *oa; 
-       s4                         oalength;
-       utf                       *u;
-       java_handle_t             *s;
-       int                        status;
-
-       // Prevent compiler warnings.
-       oa = NULL;
+       methodinfo* m;
+       int         status;
 
 #if !defined(NDEBUG)
        if (opt_CompileAll) {
@@ -1600,9 +1587,9 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
        }
 #endif
 
-       /* Get the main class plus it's arguments. */
+       /* Get the main class or jar file argument. */
 
-       mainname = NULL;
+       char* mainname = NULL;
 
        if (opt_index < vm_args->nOptions) {
                /* Get main-class argument. */
@@ -1613,7 +1600,7 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
                   classpath. */
 
                if (opt_jar == true) {
-                       p = MNEW(char, strlen(mainname) + strlen("0"));
+                       char* p = MNEW(char, strlen(mainname) + strlen("0"));
 
                        strcpy(p, mainname);
 
@@ -1629,22 +1616,9 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
                                        mainname[i] = '/';
                }
 
-               /* Build argument array.  Move index to first argument. */
+               /* Move index to first argument. */
 
                opt_index++;
-
-               oalength = vm_args->nOptions - opt_index;
-
-               oa = builtin_anewarray(oalength, class_java_lang_String);
-
-               for (int i = 0; i < oalength; i++) {
-                       option = vm_args->options[opt_index + i].optionString;
-
-                       u = utf_new_char(option);
-                       s = javastring_new(u);
-
-                       array_objectarray_element_set(oa, i, s);
-               }
        }
 
        /* Do we have a main-class argument? */
@@ -1659,6 +1633,24 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
        }
 #endif
 
+       /* Build argument array. */
+
+       int32_t oalength = vm_args->nOptions - opt_index;
+
+       ObjectArray oa(oalength, class_java_lang_String);
+
+       if (oa.is_null())
+               vm_exit(1);
+
+       for (int i = 0; i < oalength; i++) {
+               char* option = vm_args->options[opt_index + i].optionString;
+
+               utf*           u = utf_new_char(option);
+               java_handle_t* s = javastring_new(u);
+
+               oa.set_element(i, s);
+       }
+
        /* set return value to OK */
 
        status = 0;
@@ -1674,17 +1666,17 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
 
        /* load the main class */
 
-       mainutf = utf_new_char(mainname);
+       utf* mainutf = utf_new_char(mainname);
 
 #if defined(ENABLE_JAVAME_CLDC1_1)
-       mainclass = load_class_bootstrap(mainutf);
+       classinfo* mainclass = load_class_bootstrap(mainutf);
 #else
-       mainclass = load_class_from_sysloader(mainutf);
+       classinfo* mainclass = load_class_from_sysloader(mainutf);
 #endif
 
        /* error loading class */
 
-       e = exceptions_get_and_clear_exception();
+       java_handle_t* e = exceptions_get_and_clear_exception();
 
        if ((e != NULL) || (mainclass == NULL)) {
                exceptions_throw_noclassdeffounderror_cause(e);
@@ -1744,7 +1736,7 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
 
        /* start the main thread */
 
-       (void) vm_call_method(m, NULL, oa);
+       (void) vm_call_method(m, NULL, oa.get_handle());
 
        /* exception occurred? */
 
@@ -2019,7 +2011,11 @@ static char *vm_get_mainclass_from_jar(char *mainname)
        methodinfo    *m;
        java_handle_t *s;
 
+#if defined(ENABLE_JAVAME_CLDC1_1)
+       c = load_class_bootstrap(utf_new_char("java/util/jar/JarFile"));
+#else
        c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
+#endif
 
        if (c == NULL) {
                exceptions_print_stacktrace();
index defe754e64628f6869764228dc6eb65df0d60b66..c7df408602bb2af4b670dcc79a1b47baa927d3a7 100644 (file)
@@ -1,6 +1,6 @@
 /* tests/regression/bugzilla/All.java - runs all CACAO regression unit tests
 
-   Copyright (C) 2008
+   Copyright (C) 2008, 2009
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
@@ -39,7 +39,8 @@ PR112.class,
 PR113.class,
 PR114.class,
 PR116.class,
-PR119.class
+PR119.class,
+PR125.class
 })
 
 public class All {
diff --git a/tests/regression/bugzilla/PR125.java b/tests/regression/bugzilla/PR125.java
new file mode 100644 (file)
index 0000000..92a646f
--- /dev/null
@@ -0,0 +1,84 @@
+/* tests/regression/bugzilla/PR125.java
+
+   Copyright (C) 2009
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   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., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import java.lang.reflect.Field;
+
+public class PR125 extends ClassLoader {
+    @Test
+    public void test() throws NoSuchFieldException, IllegalAccessException {
+        Class cls = super.defineClass(null, bytecode, 0, bytecode.length);
+        Field fld = cls.getDeclaredField("val");
+        assertEquals(42, fld.getInt(null));
+    }
+
+    /*
+     * The following Bytecode was derived from a class like this:
+     *    public class Foo {
+     *       public static int val = 42;
+     *    }
+     *
+     * The access_flags of the <clinit> were modified by hand to
+     * not contain the ACC_STATIC flag.
+     */
+    static byte[] bytecode = {
+       (byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x31, 
+       (byte)0x00, (byte)0x12, (byte)0x0a, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x0e, (byte)0x09, 
+       (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x0f, (byte)0x07, (byte)0x00, (byte)0x10, (byte)0x07, 
+       (byte)0x00, (byte)0x11, (byte)0x01, (byte)0x00, (byte)0x03, (byte)0x76, (byte)0x61, (byte)0x6c, 
+       (byte)0x01, (byte)0x00, (byte)0x01, (byte)0x49, (byte)0x01, (byte)0x00, (byte)0x06, (byte)0x3c, 
+       (byte)0x69, (byte)0x6e, (byte)0x69, (byte)0x74, (byte)0x3e, (byte)0x01, (byte)0x00, (byte)0x03, 
+       (byte)0x28, (byte)0x29, (byte)0x56, (byte)0x01, (byte)0x00, (byte)0x04, (byte)0x43, (byte)0x6f, 
+       (byte)0x64, (byte)0x65, (byte)0x01, (byte)0x00, (byte)0x0f, (byte)0x4c, (byte)0x69, (byte)0x6e, 
+       (byte)0x65, (byte)0x4e, (byte)0x75, (byte)0x6d, (byte)0x62, (byte)0x65, (byte)0x72, (byte)0x54, 
+       (byte)0x61, (byte)0x62, (byte)0x6c, (byte)0x65, (byte)0x01, (byte)0x00, (byte)0x08, (byte)0x3c, 
+       (byte)0x63, (byte)0x6c, (byte)0x69, (byte)0x6e, (byte)0x69, (byte)0x74, (byte)0x3e, (byte)0x01, 
+       (byte)0x00, (byte)0x0a, (byte)0x53, (byte)0x6f, (byte)0x75, (byte)0x72, (byte)0x63, (byte)0x65, 
+       (byte)0x46, (byte)0x69, (byte)0x6c, (byte)0x65, (byte)0x01, (byte)0x00, (byte)0x08, (byte)0x46, 
+       (byte)0x6f, (byte)0x6f, (byte)0x2e, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x0c, 
+       (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x08, (byte)0x0c, (byte)0x00, (byte)0x05, (byte)0x00, 
+       (byte)0x06, (byte)0x01, (byte)0x00, (byte)0x03, (byte)0x46, (byte)0x6f, (byte)0x6f, (byte)0x01, 
+       (byte)0x00, (byte)0x10, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c, 
+       (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x4f, (byte)0x62, (byte)0x6a, (byte)0x65, 
+       (byte)0x63, (byte)0x74, (byte)0x00, (byte)0x21, (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x04, 
+       (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09, (byte)0x00, (byte)0x05, 
+       (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x01, 
+       (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09, 
+       (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x1d, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x01, 
+       (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x2a, (byte)0xb7, (byte)0x00, (byte)0x01, 
+       (byte)0xb1, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x0a, (byte)0x00, 
+       (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, 
+       (byte)0x01, (byte)0x00, (byte)/*0x08*/0x00, (byte)0x00, (byte)0x0b, (byte)0x00, (byte)0x08, (byte)0x00, 
+       (byte)0x01, (byte)0x00, (byte)0x09, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x1e, (byte)0x00, 
+       (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x10, 
+       (byte)0x2a, (byte)0xb3, (byte)0x00, (byte)0x02, (byte)0xb1, (byte)0x00, (byte)0x00, (byte)0x00, 
+       (byte)0x01, (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x00, 
+       (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x01, (byte)0x00, 
+       (byte)0x0c, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x0d, 
+    };
+}
+