aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2014-01-22 15:25:50 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-24 14:32:33 +0100
commitc53fef423a8f607e1443b1d409712864f8cac9d5 (patch)
tree87d1efbdcf64ecb14fa6980a70fb20ffc994831d /src
parent6ae57f01bb1495a74b23a81c590672ce788d5400 (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.cpp10
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp102
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h75
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp11
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4object.cpp22
-rw-r--r--src/qml/jsruntime/qv4object_p.h21
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp2
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp4
-rw-r--r--src/qml/jsruntime/qv4serialize.cpp2
-rw-r--r--src/qml/qml/qqmllocale.cpp4
-rw-r--r--src/qml/qml/v8/qv8engine.cpp8
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();
}