Fixes PR52.
[cacao.git] / src / vm / array.c
index 6c8d5e41b938bc75e83ceefcf42b21ed788934c1..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;                                                       \
        }                                                                          \
@@ -240,7 +254,7 @@ java_handle_t *array_objectarray_element_get(java_handle_objectarray_t *a, int32
 
        size = LLNI_array_size(a);
 
-       if ((index < 0) || (index > size)) {
+       if ((index < 0) || (index >= size)) {
                exceptions_throw_arrayindexoutofboundsexception();
                return NULL;
        }
@@ -280,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;                                                                \
        }                                                                          \
@@ -297,9 +311,20 @@ void array_objectarray_element_set(java_handle_objectarray_t *a, int32_t index,
                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)) {
+       if ((index < 0) || (index >= size)) {
                exceptions_throw_arrayindexoutofboundsexception();
                return;
        }
@@ -323,6 +348,13 @@ ARRAY_TYPEARRAY_ELEMENT_SET(double,  double)
 
    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)
@@ -332,7 +364,7 @@ int32_t array_length_get(java_handle_t *a)
 
        if (a == NULL) {
                exceptions_throw_nullpointerexception();
-               return 0;
+               return -1;
        }
 
        LLNI_class_get(a, c);
@@ -340,7 +372,7 @@ int32_t array_length_get(java_handle_t *a)
        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);