Fixes PR52.
[cacao.git] / src / vm / array.c
index b03937f5a23a9234814ff7de6eca437f6565b28f..30f231d3e720a8a60ae388a7dfb5abed406b3114 100644 (file)
@@ -1,9 +1,7 @@
-/* src/vm/array.c - array functions
+/* src/vm/array.c - Java array functions
 
-   Copyright (C) 2007 R. Grafl, A. Krall, C. Kruegel,
-   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-   J. Wenninger, Institut f. Computersprachen - TU Wien
+   Copyright (C) 2007
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -51,6 +49,11 @@ java_handle_t *array_element_get(java_handle_t *a, int32_t index)
        imm_union      value;
        java_handle_t *o;
 
+       if (a == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
        v = LLNI_vftbl_direct(a);
 
        type = v->arraydesc->arraytype;
@@ -91,6 +94,12 @@ imm_union array_element_primitive_get(java_handle_t *a, int32_t index)
        int       type;
        imm_union value;
 
+       if (a == NULL) {
+               exceptions_throw_nullpointerexception();
+               value.a = NULL;
+               return value;
+       }
+
        v = LLNI_vftbl_direct(a);
 
        type = v->arraydesc->arraytype;
@@ -151,6 +160,11 @@ void array_element_primitive_set(java_handle_t *a, int32_t index, imm_union valu
        vftbl_t *v;
        int      type;
 
+       if (a == NULL) {
+               exceptions_throw_nullpointerexception();
+               return;
+       }
+
        v = LLNI_vftbl_direct(a);
 
        type = v->arraydesc->arraytype;
@@ -218,7 +232,7 @@ type array_##name##array_element_get(java_handle_##name##array_t *a, int32_t ind
                                                                                \
        size = LLNI_array_size(a);                                                 \
                                                                                \
-       if ((index < 0) || (index > size)) {                                       \
+       if ((index < 0) || (index >= size)) {                                      \
                exceptions_throw_arrayindexoutofboundsexception();                     \
                return (type) 0;                                                       \
        }                                                                          \
@@ -228,6 +242,30 @@ type array_##name##array_element_get(java_handle_##name##array_t *a, int32_t ind
        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)
@@ -236,7 +274,6 @@ 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_TYPEARRAY_ELEMENT_GET(object,  java_handle_t*)
 
 
 /* array_xxxarray_element_set **************************************************
@@ -257,7 +294,7 @@ void array_##name##array_element_set(java_handle_##name##array_t *a, int32_t ind
                                                                                \
        size = LLNI_array_size(a);                                                 \
                                                                                \
-       if ((index < 0) || (index > size)) {                                       \
+       if ((index < 0) || (index >= size)) {                                      \
                exceptions_throw_arrayindexoutofboundsexception();                     \
                return;                                                                \
        }                                                                          \
@@ -265,6 +302,38 @@ void array_##name##array_element_set(java_handle_##name##array_t *a, int32_t ind
        LLNI_array_direct(a, index) = value;                                       \
 }
 
+void array_objectarray_element_set(java_handle_objectarray_t *a, int32_t index, java_handle_t *value)
+{
+       int32_t size;
+
+       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();
+                       return;
+               }
+       }
+
+       size = LLNI_array_size(a);
+
+       if ((index < 0) || (index >= size)) {
+               exceptions_throw_arrayindexoutofboundsexception();
+               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)
@@ -273,31 +342,37 @@ 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_TYPEARRAY_ELEMENT_SET(object,  java_handle_t*)
 
 
 /* array_length_get ***********************************************************
 
    Returns a the length of the given Java array.
 
+   ARGUMENTS:
+       a ... Java array
+
+   RETURN VALUE:
+         -1 ... exception thrown
+          >= 0 ... length of the Java array
+
 *******************************************************************************/
 
 int32_t array_length_get(java_handle_t *a)
 {
-       vftbl_t *v;
-       int32_t  size;
+       classinfo *c;
+       int32_t    size;
 
        if (a == NULL) {
                exceptions_throw_nullpointerexception();
-               return 0;
+               return -1;
        }
 
-       v = LLNI_vftbl_direct(a);
+       LLNI_class_get(a, c);
 
-       if (!class_is_array(v->class)) {
+       if (!class_is_array(c)) {
 /*             exceptions_throw_illegalargumentexception("Argument is not an array"); */
                exceptions_throw_illegalargumentexception();
-               return 0;
+               return -1;
        }
 
        size = LLNI_array_size(a);