aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp22
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h45
-rw-r--r--src/qml/jsruntime/qv4object.cpp5
-rw-r--r--src/qml/jsruntime/qv4object_p.h3
4 files changed, 42 insertions, 33 deletions
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index 469081e683..c40f50153d 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 cd080baa4a..70c581d75d 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 1b2532018e..d53ca013b4 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 86e4e78d28..4e9d1527c2 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); }