diff options
Diffstat (limited to 'src/qml/jsruntime/qv4object_p.h')
-rw-r--r-- | src/qml/jsruntime/qv4object_p.h | 224 |
1 files changed, 71 insertions, 153 deletions
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 23f2f682fd..9500c2a4d0 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -49,7 +49,7 @@ #include "qv4managed_p.h" #include "qv4property_p.h" #include "qv4internalclass_p.h" -#include "qv4sparsearray_p.h" +#include "qv4arraydata_p.h" #include <QtCore/QString> #include <QtCore/QHash> @@ -100,20 +100,17 @@ struct SyntaxErrorPrototype; struct TypeErrorPrototype; struct URIErrorPrototype; + struct Q_QML_EXPORT Object: Managed { Q_MANAGED + Q_MANAGED_TYPE(Object) + enum { + IsObject = true + }; uint memberDataAlloc; Property *memberData; - union { - uint arrayFreeList; - uint arrayOffset; - }; - uint arrayDataLen; - uint arrayAlloc; - PropertyAttributes *arrayAttributes; - Property *arrayData; - SparseArray *sparseArray; + ArrayData *arrayData; enum { InlinePropertySize = 4 @@ -136,10 +133,14 @@ struct Q_QML_EXPORT Object: Managed { bool __hasProperty__(const StringRef name) const; bool __hasProperty__(uint index) const; + bool hasOwnProperty(const StringRef name) const; + bool hasOwnProperty(uint index) const; + bool __defineOwnProperty__(ExecutionContext *ctx, Property *current, const StringRef member, const Property &p, PropertyAttributes attrs); bool __defineOwnProperty__(ExecutionContext *ctx, const StringRef name, const Property &p, PropertyAttributes attrs); bool __defineOwnProperty__(ExecutionContext *ctx, uint index, const Property &p, PropertyAttributes attrs); bool __defineOwnProperty__(ExecutionContext *ctx, const QString &name, const Property &p, PropertyAttributes attrs); + bool defineOwnProperty2(ExecutionContext *ctx, uint index, const Property &p, PropertyAttributes attrs); // // helpers @@ -156,7 +157,9 @@ struct Q_QML_EXPORT Object: Managed { void putValue(Property *pd, PropertyAttributes attrs, const ValueRef value); /* The spec default: Writable: true, Enumerable: false, Configurable: true */ - void defineDefaultProperty(const StringRef name, ValueRef value); + void defineDefaultProperty(const StringRef name, ValueRef value) { + insertMember(name, value, Attr_Data|Attr_NotEnumerable); + } void defineDefaultProperty(const QString &name, ValueRef value); void defineDefaultProperty(const QString &name, ReturnedValue (*code)(CallContext *), int argumentCount = 0); void defineDefaultProperty(const StringRef name, ReturnedValue (*code)(CallContext *), int argumentCount = 0); @@ -166,113 +169,63 @@ struct Q_QML_EXPORT Object: Managed { void defineReadonlyProperty(const QString &name, ValueRef value); void defineReadonlyProperty(const StringRef name, ValueRef value); - Property *insertMember(const StringRef s, PropertyAttributes attributes); + void insertMember(const StringRef s, const ValueRef v, PropertyAttributes attributes = Attr_Data) { + insertMember(s, Property::fromValue(*v), attributes); + } + void insertMember(const StringRef s, const Property &p, PropertyAttributes attributes); inline ExecutionEngine *engine() const { return internalClass->engine; } // Array handling - uint allocArrayValue() { - uint idx = arrayFreeList; - if (arrayAlloc <= arrayFreeList) - arrayReserve(arrayAlloc + 1); - arrayFreeList = arrayData[arrayFreeList].value.uint_32; - if (arrayAttributes) - arrayAttributes[idx].setType(PropertyAttributes::Data); - return idx; - } - - uint allocArrayValue(const ValueRef v) { - uint idx = allocArrayValue(); - Property *pd = &arrayData[idx]; - pd->value = *v; - return idx; - } - void freeArrayValue(int idx) { - Property &pd = arrayData[idx]; - pd.value.tag = Value::Empty_Type; - pd.value.int_32 = arrayFreeList; - arrayFreeList = idx; - if (arrayAttributes) - arrayAttributes[idx].clear(); - } - - void getArrayHeadRoom() { - assert(!sparseArray && !arrayOffset); - arrayOffset = qMax(arrayDataLen >> 2, (uint)16); - Property *newArray = new Property[arrayOffset + arrayAlloc]; - memcpy(newArray + arrayOffset, arrayData, arrayDataLen*sizeof(Property)); - delete [] arrayData; - arrayData = newArray + arrayOffset; - if (arrayAttributes) { - PropertyAttributes *newAttrs = new PropertyAttributes[arrayOffset + arrayAlloc]; - memcpy(newAttrs + arrayOffset, arrayAttributes, arrayDataLen*sizeof(PropertyAttributes)); - delete [] arrayAttributes; - arrayAttributes = newAttrs + arrayOffset; - } - } - public: void copyArrayData(Object *other); - void initSparse(); - uint arrayLength() const; bool setArrayLength(uint newLen); void setArrayLengthUnchecked(uint l); - Property *arrayInsert(uint index, PropertyAttributes attributes = Attr_Data); + void arraySet(uint index, const Property &p, PropertyAttributes attributes = Attr_Data); - void arraySet(uint index, const Property *pd); void arraySet(uint index, ValueRef value); - uint propertyIndexFromArrayIndex(uint index) const - { - if (!sparseArray) { - if (index >= arrayDataLen) - return UINT_MAX; - return index; - } else { - SparseArrayNode *n = sparseArray->findNode(index); - if (!n) - return UINT_MAX; - return n->value; - } - } + void push_back(const ValueRef v); - Property *arrayAt(uint index) const { - uint pidx = propertyIndexFromArrayIndex(index); - if (pidx == UINT_MAX) - return 0; - return arrayData + pidx; + ArrayData::Type arrayType() const { + return arrayData ? (ArrayData::Type)arrayData->type : ArrayData::Simple; } - - Property *nonSparseArrayAt(uint index) const { - if (sparseArray) - return 0; - if (index >= arrayDataLen) - return 0; - return arrayData + index; + // ### remove me + void setArrayType(ArrayData::Type t) { + Q_ASSERT(t != ArrayData::Simple && t != ArrayData::Sparse); + arrayCreate(); + arrayData->type = t; } - void push_back(const ValueRef v); + inline void arrayReserve(uint n) { + arrayCreate(); + arrayData->vtable->reserve(arrayData, n); + } - SparseArrayNode *sparseArrayBegin() { return sparseArray ? sparseArray->begin() : 0; } - SparseArrayNode *sparseArrayEnd() { return sparseArray ? sparseArray->end() : 0; } + void arrayCreate() { + if (!arrayData) + arrayData = new ArrayData; + } - void arrayConcat(const ArrayObject *other); - void arraySort(ExecutionContext *context, ObjectRef thisObject, const ValueRef comparefn, uint arrayDataLen); - ReturnedValue arrayIndexOf(const ValueRef v, uint fromIndex, uint arrayDataLen, ExecutionContext *ctx, Object *o); + void initSparseArray(); + SparseArrayNode *sparseBegin() { return arrayType() == ArrayData::Sparse ? static_cast<SparseArrayData *>(arrayData)->sparse->begin() : 0; } + SparseArrayNode *sparseEnd() { return arrayType() == ArrayData::Sparse ? static_cast<SparseArrayData *>(arrayData)->sparse->end() : 0; } - void arrayReserve(uint n); - void ensureArrayAttributes(); + inline Property *arrayInsert(uint index) { + arrayCreate(); + return ArrayData::insert(this, index); + } inline bool protoHasArray() { Scope scope(engine()); Scoped<Object> p(scope, this); while ((p = p->prototype())) - if (p->arrayDataLen) + if (p->arrayData) return true; return false; @@ -298,6 +251,7 @@ public: using Managed::getLookup; using Managed::setLookup; using Managed::advanceIterator; + using Managed::getLength; protected: static void destroy(Managed *that); static void markObjects(Managed *that, ExecutionEngine *e); @@ -312,7 +266,7 @@ protected: static ReturnedValue getLookup(Managed *m, Lookup *l); static void setLookup(Managed *m, Lookup *l, const ValueRef v); static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes); - + static uint getLength(const Managed *m); private: ReturnedValue internalGet(const StringRef name, bool *hasProperty); @@ -328,40 +282,39 @@ private: struct BooleanObject: Object { Q_MANAGED + Q_MANAGED_TYPE(BooleanObject) SafeValue value; BooleanObject(ExecutionEngine *engine, const ValueRef val) : Object(engine->booleanClass) { - type = Type_BooleanObject; value = val; } protected: BooleanObject(InternalClass *ic) : Object(ic) { - setVTable(&static_vtbl); - type = Type_BooleanObject; + Q_ASSERT(internalClass->vtable == &static_vtbl); value = Encode(false); } }; struct NumberObject: Object { Q_MANAGED + Q_MANAGED_TYPE(NumberObject) SafeValue value; NumberObject(ExecutionEngine *engine, const ValueRef val) : Object(engine->numberClass) { - type = Type_NumberObject; value = val; } protected: NumberObject(InternalClass *ic) : Object(ic) { - setVTable(&static_vtbl); - type = Type_NumberObject; + Q_ASSERT(internalClass->vtable == &static_vtbl); value = Encode((int)0); } }; struct ArrayObject: Object { Q_MANAGED + Q_MANAGED_TYPE(ArrayObject) enum { LengthPropertyIndex = 0 }; @@ -372,19 +325,13 @@ struct ArrayObject: Object { void init(ExecutionEngine *engine); + static ReturnedValue getLookup(Managed *m, Lookup *l); + using Managed::getLength; + static uint getLength(const Managed *m); + QStringList toQStringList() const; }; -inline uint Object::arrayLength() const -{ - if (isArrayObject()) { - if (memberData[ArrayObject::LengthPropertyIndex].value.isInteger()) - return memberData[ArrayObject::LengthPropertyIndex].value.integerValue(); - return Primitive::toUInt32(memberData[ArrayObject::LengthPropertyIndex].value.doubleValue()); - } - return 0; -} - inline void Object::setArrayLengthUnchecked(uint l) { if (isArrayObject()) { @@ -396,64 +343,35 @@ inline void Object::setArrayLengthUnchecked(uint l) inline void Object::push_back(const ValueRef v) { - uint idx = arrayLength(); - if (!sparseArray) { - if (idx >= arrayAlloc) - arrayReserve(idx + 1); - arrayData[idx].value = *v; - arrayDataLen = idx + 1; - } else { - uint idx = allocArrayValue(v); - sparseArray->push_back(idx, arrayLength()); - } + arrayCreate(); + Q_ASSERT(!arrayData->isSparse()); + + uint idx = getLength(); + arrayReserve(idx + 1); + arrayData->put(idx, v); + arrayData->setLength(idx + 1); setArrayLengthUnchecked(idx + 1); } -inline Property *Object::arrayInsert(uint index, PropertyAttributes attributes) { +inline void Object::arraySet(uint index, const Property &p, PropertyAttributes attributes) +{ if (attributes.isAccessor()) hasAccessorProperty = 1; - Property *pd; - if (!sparseArray && (index < 0x1000 || index < arrayDataLen + (arrayDataLen >> 2))) { - if (index >= arrayAlloc) - arrayReserve(index + 1); - if (index >= arrayDataLen) { - // mark possible hole in the array - for (uint i = arrayDataLen; i < index; ++i) { - arrayData[i].value = Primitive::emptyValue(); - if (arrayAttributes) - arrayAttributes[i].clear(); - } - arrayDataLen = index + 1; - } - pd = arrayData + index; - } else { - initSparse(); - SparseArrayNode *n = sparseArray->insert(index); - if (n->value == UINT_MAX) - n->value = allocArrayValue(); - pd = arrayData + n->value; - } - if (index >= arrayLength()) + Property *pd = arrayInsert(index); + *pd = p; + arrayData->setAttributes(index, attributes); + if (isArrayObject() && index >= getLength()) setArrayLengthUnchecked(index + 1); - if (arrayAttributes || attributes != Attr_Data) { - if (!arrayAttributes) - ensureArrayAttributes(); - attributes.resolve(); - arrayAttributes[pd - arrayData] = attributes; - } - return pd; } + inline void Object::arraySet(uint index, ValueRef value) { Property *pd = arrayInsert(index); - pd->value = *value; -} - -inline void Object::arraySet(uint index, const Property *pd) -{ - *arrayInsert(index) = *pd; + pd->value = value ? *value : Primitive::undefinedValue(); + if (isArrayObject() && index >= getLength()) + setArrayLengthUnchecked(index + 1); } template<> |