diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index 469081e68393831586e6fbf436a3151f48878ddb..c40f50153d0f518455c0b8f0b6fbb4958d3997e8 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -119,7 +119,7 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
 
     while (alloc < requested)
         alloc *= 2;
-    size_t size = sizeof(ArrayData::Data) + alloc*sizeof(Value);
+    size_t size = sizeof(ArrayData::Data) + (alloc - 1)*sizeof(Value);
     if (enforceAttributes)
         size += alloc*sizeof(PropertyAttributes);
 
@@ -137,7 +137,6 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
     }
     newData->setAlloc(alloc);
     newData->setType(newType);
-    newData->d()->arrayData = reinterpret_cast<Value *>(newData->d() + 1);
     newData->setAttrs(enforceAttributes ? reinterpret_cast<PropertyAttributes *>(newData->d()->arrayData + alloc) : 0);
     o->setArrayData(newData);
 
@@ -417,10 +416,10 @@ uint SparseArrayData::allocate(Object *o, bool doubleSlot)
 ReturnedValue SparseArrayData::get(const ArrayData *d, uint index)
 {
     const SparseArrayData *s = static_cast<const SparseArrayData *>(d);
-    SparseArrayNode *n = s->sparse()->findNode(index);
-    if (!n)
+    index = s->mappedIndex(index);
+    if (index == UINT_MAX)
         return Primitive::emptyValue().asReturnedValue();
-    return s->arrayData()[n->value].asReturnedValue();
+    return s->arrayData()[index].asReturnedValue();
 }
 
 bool SparseArrayData::put(Object *o, uint index, ValueRef value)
@@ -428,7 +427,7 @@ bool SparseArrayData::put(Object *o, uint index, ValueRef value)
     if (value->isEmpty())
         return true;
 
-    const SparseArrayData *s = static_cast<const SparseArrayData *>(o->arrayData());
+    SparseArrayData *s = static_cast<SparseArrayData *>(o->arrayData());
     SparseArrayNode *n = s->sparse()->insert(index);
     Q_ASSERT(n->value == UINT_MAX || !o->arrayData()->attrs() || !o->arrayData()->attrs()[n->value].isAccessor());
     if (n->value == UINT_MAX)
@@ -442,6 +441,7 @@ bool SparseArrayData::put(Object *o, uint index, ValueRef value)
 bool SparseArrayData::del(Object *o, uint index)
 {
     SparseArrayData *dd = static_cast<SparseArrayData *>(o->arrayData());
+
     SparseArrayNode *n = dd->sparse()->findNode(index);
     if (!n)
         return true;
@@ -567,14 +567,14 @@ bool SparseArrayData::putArray(Object *o, uint index, Value *values, uint n)
 }
 
 
-uint ArrayData::append(Object *obj, const ArrayObject *otherObj, uint n)
+uint ArrayData::append(Object *obj, ArrayObject *otherObj, uint n)
 {
     Q_ASSERT(!obj->arrayData()->hasAttributes());
 
     if (!n)
         return obj->getLength();
 
-    const ArrayData *other = otherObj->arrayData();
+    ArrayData *other = otherObj->arrayData();
 
     if (other->isSparse())
         obj->initSparseArray();
@@ -584,7 +584,7 @@ uint ArrayData::append(Object *obj, const ArrayObject *otherObj, uint n)
     uint oldSize = obj->getLength();
 
     if (other->isSparse()) {
-        const SparseArrayData *os = static_cast<const SparseArrayData *>(other);
+        SparseArrayData *os = static_cast<SparseArrayData *>(other);
         if (otherObj->hasAccessorProperty() && other->hasAttributes()) {
             Scope scope(obj->engine());
             ScopedValue v(scope);
@@ -599,7 +599,7 @@ uint ArrayData::append(Object *obj, const ArrayObject *otherObj, uint n)
                 obj->arraySet(oldSize + it->key(), ValueRef(os->arrayData()[it->value]));
         }
     } else {
-        const SimpleArrayData *os = static_cast<const SimpleArrayData *>(other);
+        SimpleArrayData *os = static_cast<SimpleArrayData *>(other);
         uint toCopy = n;
         uint chunk = toCopy;
         if (chunk > os->alloc() - os->d()->offset)
@@ -628,7 +628,7 @@ Property *ArrayData::insert(Object *o, uint index, bool isAccessor)
                     d->data(i) = Primitive::emptyValue();
                 d->len() = index + 1;
             }
-            return reinterpret_cast<Property *>(d->d()->arrayData + d->realIndex(index));
+            return reinterpret_cast<Property *>(d->d()->arrayData + d->mappedIndex(index));
         }
     }
 
diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h
index cd080baa4aef6a208e6ab9f9855cedb0fdb2db27..70c581d75d94b194127dbafc703d0736e71beb04 100644
--- a/src/qml/jsruntime/qv4arraydata_p.h
+++ b/src/qml/jsruntime/qv4arraydata_p.h
@@ -98,7 +98,7 @@ struct Q_QML_EXPORT ArrayData : public Managed
             uint offset;
             SparseArray *sparse;
         };
-        Value *arrayData;
+        Value arrayData[1];
     };
     V4_MANAGED(Managed)
 
@@ -109,8 +109,8 @@ struct Q_QML_EXPORT ArrayData : public Managed
     void setType(Type t) { d()->type = t; }
     PropertyAttributes *attrs() const { return d()->attrs; }
     void setAttrs(PropertyAttributes *a) { d()->attrs = a; }
-    Value *arrayData() const { return d()->arrayData; }
-    Value *&arrayData() { return d()->arrayData; }
+    const Value *arrayData() const { return &d()->arrayData[0]; }
+    Value *arrayData() { return &d()->arrayData[0]; }
 
     const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(internalClass()->vtable); }
     bool isSparse() const { return this && type() == Sparse; }
@@ -140,13 +140,13 @@ struct Q_QML_EXPORT ArrayData : public Managed
             return Primitive::emptyValue().asReturnedValue();
         return vtable()->get(this, i);
     }
-    inline Property *getProperty(uint index) const;
+    inline Property *getProperty(uint index);
 
     static void ensureAttributes(Object *o);
     static void realloc(Object *o, Type newType, uint alloc, bool enforceAttributes);
 
     static void sort(ExecutionContext *context, Object *thisObject, const ValueRef comparefn, uint dataLen);
-    static uint append(Object *obj, const ArrayObject *otherObj, uint n);
+    static uint append(Object *obj, ArrayObject *otherObj, uint n);
     static Property *insert(Object *o, uint index, bool isAccessor = false);
 };
 
@@ -160,14 +160,14 @@ struct Q_QML_EXPORT SimpleArrayData : public ArrayData
     };
     V4_ARRAYDATA
 
-    uint realIndex(uint index) const { return (index + d()->offset) % d()->alloc; }
-    Value data(uint index) const { return d()->arrayData[realIndex(index)]; }
-    Value &data(uint index) { return d()->arrayData[realIndex(index)]; }
+    uint mappedIndex(uint index) const { return (index + d()->offset) % d()->alloc; }
+    Value data(uint index) const { return d()->arrayData[mappedIndex(index)]; }
+    Value &data(uint index) { return d()->arrayData[mappedIndex(index)]; }
 
-    Property *getProperty(uint index) const {
+    Property *getProperty(uint index) {
         if (index >= len())
             return 0;
-        index = realIndex(index);
+        index = mappedIndex(index);
         if (d()->arrayData[index].isEmpty())
             return 0;
         return reinterpret_cast<Property *>(d()->arrayData + index);
@@ -209,6 +209,20 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData
     static uint allocate(Object *o, bool doubleSlot = false);
     static void free(ArrayData *d, uint idx);
 
+    Property *getProperty(uint index) {
+        SparseArrayNode *n = sparse()->findNode(index);
+        if (!n)
+            return 0;
+        return reinterpret_cast<Property *>(arrayData() + n->value);
+    }
+
+    uint mappedIndex(uint index) const {
+        SparseArrayNode *n = sparse()->findNode(index);
+        if (!n)
+            return UINT_MAX;
+        return n->value;
+    }
+
     static void destroy(Managed *d);
     static void markObjects(Managed *d, ExecutionEngine *e);
 
@@ -226,19 +240,16 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData
 };
 
 
-inline Property *ArrayData::getProperty(uint index) const
+inline Property *ArrayData::getProperty(uint index)
 {
     if (!this)
         return 0;
     if (type() != Sparse) {
-        const SimpleArrayData *that = static_cast<const SimpleArrayData *>(this);
+        SimpleArrayData *that = static_cast<SimpleArrayData *>(this);
         return that->getProperty(index);
     } else {
-        const SparseArrayData *that = static_cast<const SparseArrayData *>(this);
-        SparseArrayNode *n = that->sparse()->findNode(index);
-        if (!n)
-            return 0;
-        return reinterpret_cast<Property *>(that->arrayData() + n->value);
+        SparseArrayData *that = static_cast<SparseArrayData *>(this);
+        return that->getProperty(index);
     }
 }
 
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 1b2532018e9013374f000ecf6ef4f8c6d7471b27..d53ca013b4695492877ed2c619b1b5036f6600d6 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -1075,9 +1075,8 @@ void Object::copyArrayData(Object *other)
     } else if (other->hasAccessorProperty() && other->arrayData()->attrs() && other->arrayData()->isSparse()){
         // do it the slow way
         ScopedValue v(scope);
-        const SparseArrayData *osa = static_cast<const SparseArrayData *>(other->arrayData());
-        for (const SparseArrayNode *it = osa->sparse()->begin();
-             it != osa->sparse()->end(); it = it->nextNode()) {
+        SparseArrayData *osa = static_cast<SparseArrayData *>(other->arrayData());
+        for (const SparseArrayNode *it = osa->sparse()->begin(); it != osa->sparse()->end(); it = it->nextNode()) {
             v = other->getValue(reinterpret_cast<Property *>(osa->arrayData() + it->value), other->arrayData()->attrs()[it->value]);
             arraySet(it->key(), v);
         }
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 86e4e78d28c18871d4590f46ab6bc0c13988e780..4e9d1527c28cd557403bbb9691518259cd991808 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -114,8 +114,7 @@ struct Q_QML_EXPORT Object: Managed {
 
     Members &memberData() { return d()->memberData; }
     const Members &memberData() const { return d()->memberData; }
-    const ArrayData *arrayData() const { return d()->arrayData; }
-    ArrayData *arrayData() { return d()->arrayData; }
+    ArrayData *arrayData() const { return d()->arrayData; }
     void setArrayData(ArrayData *a) { d()->arrayData = a; }
 
     Property *propertyAt(uint index) const { return reinterpret_cast<Property *>(memberData().data() + index); }