Change virtual methods in ArrayData to take Object pointer
authorLars Knoll <lars.knoll@digia.com>
Wed, 22 Jan 2014 14:25:50 +0000 (15:25 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Fri, 24 Jan 2014 13:32:33 +0000 (14:32 +0100)
Pass a pointer to the underlying object instead of the ArrayData
to virtual methods that modify the arrayData. This prepares
for allocating the ArrayData together with the array itself.

Change-Id: I66fe187f8b1e4d382ab243a518dbde5f18a1d16d
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
13 files changed:
src/qml/jsruntime/qv4argumentsobject.cpp
src/qml/jsruntime/qv4arraydata.cpp
src/qml/jsruntime/qv4arraydata_p.h
src/qml/jsruntime/qv4arrayobject.cpp
src/qml/jsruntime/qv4jsonobject.cpp
src/qml/jsruntime/qv4object.cpp
src/qml/jsruntime/qv4object_p.h
src/qml/jsruntime/qv4qobjectwrapper.cpp
src/qml/jsruntime/qv4regexpobject.cpp
src/qml/jsruntime/qv4runtime.cpp
src/qml/jsruntime/qv4serialize.cpp
src/qml/qml/qqmllocale.cpp
src/qml/qml/v8/qv8engine.cpp

index 4a3c3c1..8f1c030 100644 (file)
@@ -65,7 +65,7 @@ ArgumentsObject::ArgumentsObject(CallContext *context)
         memberData[CallerPropertyIndex] = pd;
 
         arrayReserve(context->callData->argc);
-        arrayData->put(0, context->callData->args, context->callData->argc);
+        arrayPut(0, context->callData->args, context->callData->argc);
         fullyCreated = true;
     } else {
         hasAccessorProperty = 1;
@@ -99,9 +99,9 @@ void ArgumentsObject::fullyCreate()
         mappedArguments.append(context->callData->args[i]);
         arraySet(i, context->engine->argumentsAccessors.at(i), Attr_Accessor);
     }
-    arrayData->put(numAccessors, context->callData->args + numAccessors, argCount - numAccessors);
+    arrayPut(numAccessors, context->callData->args + numAccessors, argCount - numAccessors);
     for (uint i = numAccessors; i < argCount; ++i)
-        arrayData->setAttributes(i, Attr_Data);
+        setArrayAttributes(i, Attr_Data);
 
     fullyCreated = true;
 }
@@ -121,7 +121,7 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
     if (isMapped) {
         map = *pd;
         mapAttrs = arrayData->attributes(index);
-        arrayData->setAttributes(index, Attr_Data);
+        setArrayAttributes(index, Attr_Data);
         pd = arrayData->getProperty(index);
         pd->value = mappedArguments.at(index);
     }
@@ -138,7 +138,7 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
         map.setter()->call(callData);
 
         if (attrs.isWritable()) {
-            arrayData->setAttributes(index, mapAttrs);
+            setArrayAttributes(index, mapAttrs);
             pd = arrayData->getProperty(index);
             *pd = map;
         }
index a71aa12..7626a33 100644 (file)
@@ -163,9 +163,9 @@ ReturnedValue SimpleArrayData::get(const ArrayData *d, uint index)
     return dd->data[index].asReturnedValue();
 }
 
-bool SimpleArrayData::put(ArrayData *d, uint index, ValueRef value)
+bool SimpleArrayData::put(Object *o, uint index, ValueRef value)
 {
-    SimpleArrayData *dd = static_cast<SimpleArrayData *>(d);
+    SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
     Q_ASSERT(index >= dd->len || !dd->attrs || !dd->attrs[index].isAccessor());
     // ### honour attributes
     dd->data[index] = value;
@@ -177,9 +177,9 @@ bool SimpleArrayData::put(ArrayData *d, uint index, ValueRef value)
     return true;
 }
 
-bool SimpleArrayData::del(ArrayData *d, uint index)
+bool SimpleArrayData::del(Object *o, uint index)
 {
-    SimpleArrayData *dd = static_cast<SimpleArrayData *>(d);
+    SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
     if (index >= dd->len)
         return true;
 
@@ -194,9 +194,9 @@ bool SimpleArrayData::del(ArrayData *d, uint index)
     return false;
 }
 
-void SimpleArrayData::setAttribute(ArrayData *d, uint index, PropertyAttributes attrs)
+void SimpleArrayData::setAttribute(Object *o, uint index, PropertyAttributes attrs)
 {
-    d->attrs[index] = attrs;
+    o->arrayData->attrs[index] = attrs;
 }
 
 PropertyAttributes SimpleArrayData::attribute(const ArrayData *d, uint index)
@@ -204,9 +204,9 @@ PropertyAttributes SimpleArrayData::attribute(const ArrayData *d, uint index)
     return d->attrs[index];
 }
 
-void SimpleArrayData::push_front(ArrayData *d, SafeValue *values, uint n)
+void SimpleArrayData::push_front(Object *o, SafeValue *values, uint n)
 {
-    SimpleArrayData *dd = static_cast<SimpleArrayData *>(d);
+    SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
     Q_ASSERT(!dd->attrs);
     for (int i = n - 1; i >= 0; --i) {
         if (!dd->offset)
@@ -221,9 +221,9 @@ void SimpleArrayData::push_front(ArrayData *d, SafeValue *values, uint n)
 
 }
 
-ReturnedValue SimpleArrayData::pop_front(ArrayData *d)
+ReturnedValue SimpleArrayData::pop_front(Object *o)
 {
-    SimpleArrayData *dd = static_cast<SimpleArrayData *>(d);
+    SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
     Q_ASSERT(!dd->attrs);
     if (!dd->len)
         return Encode::undefined();
@@ -236,9 +236,9 @@ ReturnedValue SimpleArrayData::pop_front(ArrayData *d)
     return v;
 }
 
-uint SimpleArrayData::truncate(ArrayData *d, uint newLen)
+uint SimpleArrayData::truncate(Object *o, uint newLen)
 {
-    SimpleArrayData *dd = static_cast<SimpleArrayData *>(d);
+    SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
     if (dd->len < newLen)
         return newLen;
 
@@ -262,9 +262,9 @@ uint SimpleArrayData::length(const ArrayData *d)
     return static_cast<const SimpleArrayData *>(d)->len;
 }
 
-bool SimpleArrayData::putArray(ArrayData *d, uint index, SafeValue *values, uint n)
+bool SimpleArrayData::putArray(Object *o, uint index, SafeValue *values, uint n)
 {
-    SimpleArrayData *dd = static_cast<SimpleArrayData *>(d);
+    SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
     if (index + n > dd->alloc)
         reserve(dd, index + n + 1);
     for (uint i = dd->len; i < index; ++i)
@@ -380,24 +380,24 @@ ReturnedValue SparseArrayData::get(const ArrayData *d, uint index)
     return d->data[n->value].asReturnedValue();
 }
 
-bool SparseArrayData::put(ArrayData *d, uint index, ValueRef value)
+bool SparseArrayData::put(Object *o, uint index, ValueRef value)
 {
     if (value->isEmpty())
         return true;
 
-    SparseArrayNode *n = static_cast<SparseArrayData *>(d)->sparse->insert(index);
-    Q_ASSERT(n->value == UINT_MAX || !d->attrs || !d->attrs[n->value].isAccessor());
+    SparseArrayNode *n = static_cast<SparseArrayData *>(o->arrayData)->sparse->insert(index);
+    Q_ASSERT(n->value == UINT_MAX || !o->arrayData->attrs || !o->arrayData->attrs[n->value].isAccessor());
     if (n->value == UINT_MAX)
-        n->value = allocate(d);
-    d->data[n->value] = value;
-    if (d->attrs)
-        d->attrs[n->value] = Attr_Data;
+        n->value = allocate(o->arrayData);
+    o->arrayData->data[n->value] = value;
+    if (o->arrayData->attrs)
+        o->arrayData->attrs[n->value] = Attr_Data;
     return true;
 }
 
-bool SparseArrayData::del(ArrayData *d, uint index)
+bool SparseArrayData::del(Object *o, uint index)
 {
-    SparseArrayData *dd = static_cast<SparseArrayData *>(d);
+    SparseArrayData *dd = static_cast<SparseArrayData *>(o->arrayData);
     SparseArrayNode *n = dd->sparse->findNode(index);
     if (!n)
         return true;
@@ -416,23 +416,24 @@ bool SparseArrayData::del(ArrayData *d, uint index)
 
     if (isAccessor) {
         // free up both indices
-        d->data[pidx + 1].tag = Value::Undefined_Type;
-        d->data[pidx + 1].uint_32 = static_cast<SparseArrayData *>(d)->freeList;
-        d->data[pidx].tag = Value::Undefined_Type;
-        d->data[pidx].uint_32 = pidx + 1;
+        dd->data[pidx + 1].tag = Value::Undefined_Type;
+        dd->data[pidx + 1].uint_32 = static_cast<SparseArrayData *>(dd)->freeList;
+        dd->data[pidx].tag = Value::Undefined_Type;
+        dd->data[pidx].uint_32 = pidx + 1;
     } else {
-        d->data[pidx].tag = Value::Undefined_Type;
-        d->data[pidx].uint_32 = static_cast<SparseArrayData *>(d)->freeList;
+        dd->data[pidx].tag = Value::Undefined_Type;
+        dd->data[pidx].uint_32 = static_cast<SparseArrayData *>(dd)->freeList;
     }
 
-    static_cast<SparseArrayData *>(d)->freeList = pidx;
-    static_cast<SparseArrayData *>(d)->sparse->erase(n);
+    dd->freeList = pidx;
+    dd->sparse->erase(n);
     return true;
 }
 
-void SparseArrayData::setAttribute(ArrayData *d, uint index, PropertyAttributes attrs)
+void SparseArrayData::setAttribute(Object *o, uint index, PropertyAttributes attrs)
 {
-    SparseArrayNode *n = static_cast<SparseArrayData *>(d)->sparse->insert(index);
+    SparseArrayData *d = static_cast<SparseArrayData *>(o->arrayData);
+    SparseArrayNode *n = d->sparse->insert(index);
     if (n->value == UINT_MAX)
         n->value = allocate(d, attrs.isAccessor());
     else if (attrs.isAccessor() != d->attrs[n->value].isAccessor()) {
@@ -451,35 +452,36 @@ PropertyAttributes SparseArrayData::attribute(const ArrayData *d, uint index)
     return d->attrs[n->value];
 }
 
-void SparseArrayData::push_front(ArrayData *d, SafeValue *values, uint n)
+void SparseArrayData::push_front(Object *o, SafeValue *values, uint n)
 {
-    Q_ASSERT(!d->attrs);
+    Q_ASSERT(!o->arrayData->attrs);
     for (int i = n - 1; i >= 0; --i) {
-        uint idx = allocate(d);
-        d->data[idx] = values[i];
-        static_cast<SparseArrayData *>(d)->sparse->push_front(idx);
+        uint idx = allocate(o->arrayData);
+        o->arrayData->data[idx] = values[i];
+        static_cast<SparseArrayData *>(o->arrayData)->sparse->push_front(idx);
     }
 }
 
-ReturnedValue SparseArrayData::pop_front(ArrayData *d)
+ReturnedValue SparseArrayData::pop_front(Object *o)
 {
-    Q_ASSERT(!d->attrs);
-    uint idx = static_cast<SparseArrayData *>(d)->sparse->pop_front();
+    Q_ASSERT(!o->arrayData->attrs);
+    uint idx = static_cast<SparseArrayData *>(o->arrayData)->sparse->pop_front();
     ReturnedValue v;
     if (idx != UINT_MAX) {
-        v = d->data[idx].asReturnedValue();
-        free(d, idx);
+        v = o->arrayData->data[idx].asReturnedValue();
+        free(o->arrayData, idx);
     } else {
         v = Encode::undefined();
     }
     return v;
 }
 
-uint SparseArrayData::truncate(ArrayData *d, uint newLen)
+uint SparseArrayData::truncate(Object *o, uint newLen)
 {
-    SparseArrayNode *begin = static_cast<SparseArrayData *>(d)->sparse->lowerBound(newLen);
-    if (begin != static_cast<SparseArrayData *>(d)->sparse->end()) {
-        SparseArrayNode *it = static_cast<SparseArrayData *>(d)->sparse->end()->previousNode();
+    SparseArrayData *d = static_cast<SparseArrayData *>(o->arrayData);
+    SparseArrayNode *begin = d->sparse->lowerBound(newLen);
+    if (begin != d->sparse->end()) {
+        SparseArrayNode *it = d->sparse->end()->previousNode();
         while (1) {
             if (d->attrs) {
                 if (!d->attrs[it->value].isConfigurable()) {
@@ -509,10 +511,10 @@ uint SparseArrayData::length(const ArrayData *d)
     return n ? n->key() + 1 : 0;
 }
 
-bool SparseArrayData::putArray(ArrayData *d, uint index, SafeValue *values, uint n)
+bool SparseArrayData::putArray(Object *o, uint index, SafeValue *values, uint n)
 {
     for (uint i = 0; i < n; ++i)
-        put(d, index + i, values[i]);
+        put(o, index + i, values[i]);
     return true;
 }
 
@@ -546,7 +548,7 @@ uint ArrayData::append(Object *obj, const ArrayObject *otherObj, uint n)
                 obj->arraySet(oldSize + it->key(), other->data[it->value]);
         }
     } else {
-        obj->arrayData->put(oldSize, other->data, n);
+        obj->arrayPut(oldSize, other->data, n);
     }
 
     return oldSize + n;
index e0f8964..ea6c95b 100644 (file)
@@ -66,14 +66,14 @@ struct ArrayVTable
     uint type;
     void (*reserve)(ArrayData *d, uint n);
     ReturnedValue (*get)(const ArrayData *d, uint index);
-    bool (*put)(ArrayData *d, uint index, ValueRef value);
-    bool (*putArray)(ArrayData *d, uint index, SafeValue *values, uint n);
-    bool (*del)(ArrayData *d, uint index);
-    void (*setAttribute)(ArrayData *d, uint index, PropertyAttributes attrs);
+    bool (*put)(Object *o, uint index, ValueRef value);
+    bool (*putArray)(Object *o, uint index, SafeValue *values, uint n);
+    bool (*del)(Object *o, uint index);
+    void (*setAttribute)(Object *o, uint index, PropertyAttributes attrs);
     PropertyAttributes (*attribute)(const ArrayData *d, uint index);
-    void (*push_front)(ArrayData *d, SafeValue *values, uint n);
-    ReturnedValue (*pop_front)(ArrayData *d);
-    uint (*truncate)(ArrayData *d, uint newLen);
+    void (*push_front)(Object *o, SafeValue *values, uint n);
+    ReturnedValue (*pop_front)(Object *o);
+    uint (*truncate)(Object *o, uint newLen);
     uint (*length)(const ArrayData *d);
 };
 
@@ -118,14 +118,6 @@ struct Q_QML_EXPORT ArrayData : public Managed
         Q_ASSERT(this);
         return attrs ? vtable()->attribute(this, i) : Attr_Data;
     }
-    void setAttributes(uint i, PropertyAttributes a) {
-        Q_ASSERT(this);
-        if (attrs || a != Attr_Data) {
-            ensureAttributes();
-            a.resolve();
-            vtable()->setAttribute(this, i, a);
-        }
-    }
 
     bool isEmpty(uint i) const {
         if (!this)
@@ -133,31 +125,6 @@ struct Q_QML_EXPORT ArrayData : public Managed
         return (vtable()->get(this, i) == Primitive::emptyValue().asReturnedValue());
     }
 
-
-    inline void push_front(SafeValue *values, uint nValues) {
-        vtable()->push_front(this, values, nValues);
-    }
-    inline ReturnedValue pop_front() {
-        return vtable()->pop_front(this);
-    }
-    inline uint push_back(uint l, uint n, SafeValue *values) {
-        vtable()->putArray(this, l, values, n);
-        return length();
-    }
-    inline bool deleteIndex(uint index) {
-        return vtable()->del(this, index);
-    }
-    inline uint truncate(uint newLen) {
-        if (!this)
-            return newLen;
-        return vtable()->truncate(this, newLen);
-    }
-    bool put(uint index, ValueRef value) {
-        return vtable()->put(this, index, value);
-    }
-    bool put(uint index, SafeValue *values, uint n) {
-        return vtable()->putArray(this, index, values, n);
-    }
     ReturnedValue get(uint i) const {
         if (!this)
             return Primitive::emptyValue().asReturnedValue();
@@ -190,14 +157,14 @@ struct Q_QML_EXPORT SimpleArrayData : public ArrayData
     static void markObjects(Managed *d, ExecutionEngine *e);
 
     static ReturnedValue get(const ArrayData *d, uint index);
-    static bool put(ArrayData *d, uint index, ValueRef value);
-    static bool putArray(ArrayData *d, uint index, SafeValue *values, uint n);
-    static bool del(ArrayData *d, uint index);
-    static void setAttribute(ArrayData *d, uint index, PropertyAttributes attrs);
+    static bool put(Object *o, uint index, ValueRef value);
+    static bool putArray(Object *o, uint index, SafeValue *values, uint n);
+    static bool del(Object *o, uint index);
+    static void setAttribute(Object *o, uint index, PropertyAttributes attrs);
     static PropertyAttributes attribute(const ArrayData *d, uint index);
-    static void push_front(ArrayData *d, SafeValue *values, uint n);
-    static ReturnedValue pop_front(ArrayData *d);
-    static uint truncate(ArrayData *d, uint newLen);
+    static void push_front(Object *o, SafeValue *values, uint n);
+    static ReturnedValue pop_front(Object *o);
+    static uint truncate(Object *o, uint newLen);
     static uint length(const ArrayData *d);
 };
 
@@ -222,14 +189,14 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData
 
     static void reserve(ArrayData *d, uint n);
     static ReturnedValue get(const ArrayData *d, uint index);
-    static bool put(ArrayData *d, uint index, ValueRef value);
-    static bool putArray(ArrayData *d, uint index, SafeValue *values, uint n);
-    static bool del(ArrayData *d, uint index);
-    static void setAttribute(ArrayData *d, uint index, PropertyAttributes attrs);
+    static bool put(Object *o, uint index, ValueRef value);
+    static bool putArray(Object *o, uint index, SafeValue *values, uint n);
+    static bool del(Object *o, uint index);
+    static void setAttribute(Object *o, uint index, PropertyAttributes attrs);
     static PropertyAttributes attribute(const ArrayData *d, uint index);
-    static void push_front(ArrayData *d, SafeValue *values, uint n);
-    static ReturnedValue pop_front(ArrayData *d);
-    static uint truncate(ArrayData *d, uint newLen);
+    static void push_front(Object *o, SafeValue *values, uint n);
+    static ReturnedValue pop_front(Object *o);
+    static uint truncate(Object *o, uint newLen);
     static uint length(const ArrayData *d);
 };
 
index 8069952..9a2407f 100644 (file)
@@ -72,7 +72,7 @@ ReturnedValue ArrayCtor::construct(Managed *m, CallData *callData)
     } else {
         len = callData->argc;
         a->arrayReserve(len);
-        a->arrayData->put(0, callData->args, len);
+        a->arrayPut(0, callData->args, len);
     }
     a->setArrayLengthUnchecked(len);
 
@@ -305,7 +305,8 @@ ReturnedValue ArrayPrototype::method_push(CallContext *ctx)
     if (!ctx->callData->argc) {
         ;
     } else if (!instance->protoHasArray() && instance->arrayData->length() <= len) {
-        len = instance->arrayData->push_back(len, ctx->callData->argc, ctx->callData->args);
+        instance->arrayData->vtable()->putArray(instance.getPointer(), len, ctx->callData->args, ctx->callData->argc);
+        len = instance->arrayData->length();
     } else {
         for (int i = 0; i < ctx->callData->argc; ++i)
             instance->putIndexed(len + i, ctx->callData->args[i]);
@@ -371,7 +372,7 @@ ReturnedValue ArrayPrototype::method_shift(CallContext *ctx)
     ScopedValue result(scope);
 
     if (!instance->protoHasArray() && !instance->arrayData->hasAttributes() && instance->arrayData->length() <= len) {
-        result = instance->arrayData->pop_front();
+        result = instance->arrayData->vtable()->pop_front(instance.getPointer());
     } else {
         result = instance->getIndexed(0);
         if (scope.hasException())
@@ -485,7 +486,7 @@ ReturnedValue ArrayPrototype::method_splice(CallContext *ctx)
         if (scope.hasException())
             return Encode::undefined();
         if (exists)
-            newArray->arrayData->put(i, v);
+            newArray->arrayPut(i, v);
     }
     newArray->setArrayLengthUnchecked(deleteCount);
 
@@ -550,7 +551,7 @@ ReturnedValue ArrayPrototype::method_unshift(CallContext *ctx)
     uint len = instance->getLength();
 
     if (!instance->protoHasArray() && !instance->arrayData->hasAttributes() && instance->arrayData->length() <= len) {
-        instance->arrayData->push_front(ctx->callData->args, ctx->callData->argc);
+        instance->arrayData->vtable()->push_front(instance.getPointer(), ctx->callData->args, ctx->callData->argc);
     } else {
         ScopedValue v(scope);
         for (uint k = len; k > 0; --k) {
index 0614346..20927ab 100644 (file)
@@ -1058,7 +1058,7 @@ QV4::ReturnedValue JsonObject::fromJsonArray(ExecutionEngine *engine, const QJso
     a->arrayReserve(size);
     ScopedValue v(scope);
     for (int i = 0; i < size; i++)
-        a->arrayData->put(i, (v = fromJsonValue(engine, array.at(i))));
+        a->arrayPut(i, (v = fromJsonValue(engine, array.at(i))));
     a->setArrayLengthUnchecked(size);
     return a.asReturnedValue();
 }
index 89e32c4..86c7ab1 100644 (file)
@@ -857,7 +857,7 @@ bool Object::internalDeleteIndexedProperty(uint index)
     if (internalClass->engine->hasException)
         return false;
 
-    if (!arrayData || arrayData->deleteIndex(index))
+    if (!arrayData || arrayData->vtable()->del(this, index))
         return true;
 
     if (engine()->currentContext()->strictMode)
@@ -1025,7 +1025,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Stri
             if (member.isNull()) {
                 // need to convert the array and the slot
                 initSparseArray();
-                arrayData->setAttributes(index, cattrs);
+                setArrayAttributes(index, cattrs);
                 current = arrayData->getProperty(index);
             }
             current->setGetter(0);
@@ -1036,7 +1036,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Stri
             cattrs.setWritable(false);
             if (member.isNull()) {
                 // need to convert the array and the slot
-                arrayData->setAttributes(index, cattrs);
+                setArrayAttributes(index, cattrs);
                 current = arrayData->getProperty(index);
             }
             current->value = Primitive::undefinedValue();
@@ -1062,7 +1062,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Stri
     if (!member.isNull()) {
         internalClass = internalClass->changeMember(member.getPointer(), cattrs);
     } else {
-        arrayData->setAttributes(index, cattrs);
+        setArrayAttributes(index, cattrs);
     }
     if (cattrs.isAccessor())
         hasAccessorProperty = 1;
@@ -1143,10 +1143,14 @@ bool Object::setArrayLength(uint newLen)
     uint oldLen = getLength();
     bool ok = true;
     if (newLen < oldLen) {
-        uint l = arrayData->truncate(newLen);
-        if (l != newLen)
-            ok = false;
-        newLen = l;
+        if (!arrayData) {
+            Q_ASSERT(!newLen);
+        } else {
+            uint l = arrayData->vtable()->truncate(this, newLen);
+            if (l != newLen)
+                ok = false;
+            newLen = l;
+        }
     } else {
         if (newLen >= 0x100000)
             initSparseArray();
@@ -1221,7 +1225,7 @@ ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list)
     arrayReserve(len);
     ScopedValue v(scope);
     for (int ii = 0; ii < len; ++ii)
-        arrayData->put(ii, (v = engine->newString(list.at(ii))));
+        arrayPut(ii, (v = engine->newString(list.at(ii))));
     setArrayLengthUnchecked(len);
 }
 
index 0572c4e..9c272ce 100644 (file)
@@ -183,13 +183,26 @@ public:
     void copyArrayData(Object *other);
 
     bool setArrayLength(uint newLen);
-
     void setArrayLengthUnchecked(uint l);
 
     void arraySet(uint index, const Property &p, PropertyAttributes attributes = Attr_Data);
-
     void arraySet(uint index, ValueRef value);
 
+    bool arrayPut(uint index, ValueRef value) {
+        return arrayData->vtable()->put(this, index, value);
+    }
+    bool arrayPut(uint index, SafeValue *values, uint n) {
+        return arrayData->vtable()->putArray(this, index, values, n);
+    }
+    void setArrayAttributes(uint i, PropertyAttributes a) {
+        Q_ASSERT(arrayData);
+        if (arrayData->attrs || a != Attr_Data) {
+            arrayData->ensureAttributes();
+            a.resolve();
+            arrayData->vtable()->setAttribute(this, i, a);
+        }
+    }
+
     void push_back(const ValueRef v);
 
     ArrayData::Type arrayType() const {
@@ -356,7 +369,7 @@ inline void Object::push_back(const ValueRef v)
 
     uint idx = getLength();
     arrayReserve(idx + 1);
-    arrayData->put(idx, v);
+    arrayPut(idx, v);
     setArrayLengthUnchecked(idx + 1);
 }
 
@@ -372,7 +385,7 @@ inline void Object::arraySet(uint index, const Property &p, PropertyAttributes a
     } else {
         arrayData->vtable()->reserve(arrayData, index + 1);
     }
-    arrayData->setAttributes(index, attributes);
+    setArrayAttributes(index, attributes);
     Property *pd = ArrayData::insert(this, index, attributes.isAccessor());
     pd->value = p.value;
     if (attributes.isAccessor())
index 1cf6ef0..235aaf9 100644 (file)
@@ -1688,7 +1688,7 @@ QV4::ReturnedValue CallArgument::toValue(QV8Engine *engine)
         array->arrayReserve(list.count());
         QV4::ScopedValue v(scope);
         for (int ii = 0; ii < list.count(); ++ii)
-            array->arrayData->put(ii, (v = QV4::QObjectWrapper::wrap(v4, list.at(ii))));
+            array->arrayPut(ii, (v = QV4::QObjectWrapper::wrap(v4, list.at(ii))));
         array->setArrayLengthUnchecked(list.count());
         return array.asReturnedValue();
     } else if (type == qMetaTypeId<QQmlV4Handle>()) {
index aafecb5..6f7281d 100644 (file)
@@ -348,7 +348,7 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
         int start = matchOffsets[i * 2];
         int end = matchOffsets[i * 2 + 1];
         v = (start != -1 && end != -1) ? ctx->engine->newString(s.mid(start, end - start))->asReturnedValue() : Encode::undefined();
-        array->arrayData->put(i, v);
+        array->arrayPut(i, v);
     }
     array->setArrayLengthUnchecked(len);
 
index 77b0012..c929b39 100644 (file)
@@ -614,7 +614,7 @@ void __qmljs_set_element(ExecutionContext *ctx, const ValueRef object, const Val
     uint idx = index->asArrayIndex();
     if (idx < UINT_MAX) {
         if (o->arrayType() == ArrayData::Simple && idx < o->arrayData->length())
-            o->arrayData->put(idx, value);
+            o->arrayPut(idx, value);
         else
             o->putIndexed(idx, value);
         return;
@@ -1105,7 +1105,7 @@ ReturnedValue __qmljs_builtin_define_array(ExecutionContext *ctx, SafeValue *val
 
     if (length) {
         a->arrayReserve(length);
-        a->arrayData->put(0, values, length);
+        a->arrayPut(0, values, length);
         a->setArrayLengthUnchecked(length);
     }
     return a.asReturnedValue();
index 084ff9c..50899c3 100644 (file)
@@ -390,7 +390,7 @@ ReturnedValue Serialize::deserialize(const char *&data, QV8Engine *engine)
         array->arrayReserve(seqLength);
         for (quint32 ii = 0; ii < seqLength; ++ii) {
             value = deserialize(data, engine);
-            array->arrayData->put(ii, value);
+            array->arrayPut(ii, value);
         }
         array->setArrayLengthUnchecked(seqLength);
         QVariant seqVariant = QV4::SequencePrototype::toVariant(array, sequenceType, &succeeded);
index 8cea66c..0ea9785 100644 (file)
@@ -502,7 +502,7 @@ QV4::ReturnedValue QQmlLocaleData::method_get_weekDays(QV4::CallContext *ctx)
         int day = days.at(i);
         if (day == 7) // JS Date days in range 0(Sunday) to 6(Saturday)
             day = 0;
-        result->arrayData->put(i, QV4::Primitive::fromInt32(day));
+        result->arrayPut(i, QV4::Primitive::fromInt32(day));
     }
     result->setArrayLengthUnchecked(days.size());
 
@@ -521,7 +521,7 @@ QV4::ReturnedValue QQmlLocaleData::method_get_uiLanguages(QV4::CallContext *ctx)
     result->arrayReserve(langs.size());
     QV4::ScopedValue v(scope);
     for (int i = 0; i < langs.size(); ++i)
-        result->arrayData->put(i, (v = ctx->engine->newString(langs.at(i))));
+        result->arrayPut(i, (v = ctx->engine->newString(langs.at(i))));
 
     result->setArrayLengthUnchecked(langs.size());
 
index 35fc531..316d066 100644 (file)
@@ -198,7 +198,7 @@ static QV4::ReturnedValue arrayFromStringList(QV8Engine *engine, const QStringLi
     a->arrayReserve(len);
     QV4::ScopedValue v(scope);
     for (int ii = 0; ii < len; ++ii)
-        a->arrayData->put(ii, (v = QV4::Encode(e->newString(list.at(ii)))));
+        a->arrayPut(ii, (v = QV4::Encode(e->newString(list.at(ii)))));
 
     a->setArrayLengthUnchecked(len);
     return a.asReturnedValue();
@@ -213,7 +213,7 @@ static QV4::ReturnedValue arrayFromVariantList(QV8Engine *engine, const QVariant
     a->arrayReserve(len);
     QV4::ScopedValue v(scope);
     for (int ii = 0; ii < len; ++ii)
-        a->arrayData->put(ii, (v = engine->fromVariant(list.at(ii))));
+        a->arrayPut(ii, (v = engine->fromVariant(list.at(ii))));
 
     a->setArrayLengthUnchecked(len);
     return a.asReturnedValue();
@@ -328,7 +328,7 @@ QV4::ReturnedValue QV8Engine::fromVariant(const QVariant &variant)
             a->arrayReserve(list.count());
             QV4::ScopedValue v(scope);
             for (int ii = 0; ii < list.count(); ++ii)
-                a->arrayData->put(ii, (v = QV4::QObjectWrapper::wrap(m_v4Engine, list.at(ii))));
+                a->arrayPut(ii, (v = QV4::QObjectWrapper::wrap(m_v4Engine, list.at(ii))));
             a->setArrayLengthUnchecked(list.count());
             return a.asReturnedValue();
         } else if (QMetaType::typeFlags(type) & QMetaType::PointerToQObject) {
@@ -544,7 +544,7 @@ QV4::ReturnedValue QV8Engine::variantListToJS(const QVariantList &lst)
     a->arrayReserve(lst.size());
     QV4::ScopedValue v(scope);
     for (int i = 0; i < lst.size(); i++)
-        a->arrayData->put(i, (v = variantToJS(lst.at(i))));
+        a->arrayPut(i, (v = variantToJS(lst.at(i))));
     a->setArrayLengthUnchecked(lst.size());
     return a.asReturnedValue();
 }