diff options
author | Lars Knoll <lars.knoll@digia.com> | 2014-01-22 15:25:50 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-24 14:32:33 +0100 |
commit | c53fef423a8f607e1443b1d409712864f8cac9d5 (patch) | |
tree | 87d1efbdcf64ecb14fa6980a70fb20ffc994831d /src | |
parent | 6ae57f01bb1495a74b23a81c590672ce788d5400 (diff) |
Change virtual methods in ArrayData to take Object pointer
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsruntime/qv4argumentsobject.cpp | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4arraydata.cpp | 102 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4arraydata_p.h | 75 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4arrayobject.cpp | 11 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4jsonobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 22 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object_p.h | 21 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexpobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4serialize.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmllocale.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8engine.cpp | 8 |
13 files changed, 126 insertions, 139 deletions
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp index 4a3c3c1faa..8f1c030462 100644 --- a/src/qml/jsruntime/qv4argumentsobject.cpp +++ b/src/qml/jsruntime/qv4argumentsobject.cpp @@ -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; } diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp index a71aa12310..7626a33106 100644 --- a/src/qml/jsruntime/qv4arraydata.cpp +++ b/src/qml/jsruntime/qv4arraydata.cpp @@ -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; diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h index e0f8964bee..ea6c95bb5d 100644 --- a/src/qml/jsruntime/qv4arraydata_p.h +++ b/src/qml/jsruntime/qv4arraydata_p.h @@ -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); }; diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 8069952d43..9a2407fe2c 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -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) { diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index 0614346cff..20927ab8e7 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -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(); } diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 89e32c4b17..86c7ab1986 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -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); } diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 0572c4efa5..9c272ce7d0 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -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()) diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 1cf6ef06b7..235aaf94db 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -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>()) { diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index aafecb5ad8..6f7281d0be 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -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); diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 77b00122ef..c929b39e6a 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -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(); diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp index 084ff9c98c..50899c3893 100644 --- a/src/qml/jsruntime/qv4serialize.cpp +++ b/src/qml/jsruntime/qv4serialize.cpp @@ -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); diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index 8cea66c99e..0ea9785673 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -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()); diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index 35fc5315d5..316d066097 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -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(); } |