aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4arraydata_p.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-12-16 09:16:57 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-09 07:47:06 +0100
commit459c9a2a8840995436e610459216957bc7ebd914 (patch)
treeef28df2fdbc62bf551088d13850492d2c6a771b1 /src/qml/jsruntime/qv4arraydata_p.h
parent5cf95512af83fc6a0f70d3493be571accaf50d84 (diff)
Rework array handling for JS objects
Split up ArrayData into two classes, one for regular arrays, one for sparse arrays and cleanly separate the two cases. Only create array data on demand. Change-Id: I9ca8d0b53592174f213ba0f20caf93e77dba690a Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsruntime/qv4arraydata_p.h')
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h242
1 files changed, 242 insertions, 0 deletions
diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h
new file mode 100644
index 0000000000..89628cde0e
--- /dev/null
+++ b/src/qml/jsruntime/qv4arraydata_p.h
@@ -0,0 +1,242 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QV4ARRAYDATA_H
+#define QV4ARRAYDATA_H
+
+#include "qv4global_p.h"
+#include "qv4managed_p.h"
+#include "qv4property_p.h"
+#include "qv4sparsearray_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+struct ArrayData;
+
+struct ArrayVTable
+{
+ uint type;
+ void (*freeData)(ArrayData *d);
+ 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);
+ 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);
+};
+
+
+struct Q_QML_EXPORT ArrayData
+{
+ ArrayData()
+ : vtable(&static_vtbl)
+ , offset(0)
+ , len(0)
+ , alloc(0)
+ , type(0)
+ , attrs(0)
+ , data(0)
+ {
+ }
+
+ enum Type {
+ Simple = 0,
+ Complex = 1,
+ Sparse = 2,
+ Custom = 3
+ };
+
+ const ArrayVTable *vtable;
+ uint offset;
+ uint len;
+ uint alloc;
+ uint type;
+ PropertyAttributes *attrs;
+ Property *data;
+
+ bool isSparse() const { return this && type == Sparse; }
+
+ uint length() const {
+ return this ? len : 0;
+ }
+ void setLength(uint l) {
+ Q_ASSERT(this);
+ len = l;
+ }
+
+ bool hasAttributes() const {
+ return this && attrs;
+ }
+ void ensureAttributes();
+ PropertyAttributes attributes(int i) const {
+ 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)
+ return true;
+ return (vtable->get(this, i) == Primitive::emptyValue().asReturnedValue());
+ }
+
+
+ inline void free() {
+ vtable->freeData(this);
+ }
+
+ 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 len;
+ }
+ inline bool deleteIndex(uint index) {
+ return vtable->del(this, index);
+ }
+ inline uint truncate(uint newLen) {
+ if (!this || len < newLen)
+ 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();
+ return vtable->get(this, i);
+ }
+ inline Property *getProperty(uint index) const;
+
+
+
+ static void sort(ExecutionContext *context, ObjectRef thisObject, const ValueRef comparefn, uint dataLen);
+ static uint append(Object *o, const ArrayObject *otherObj, uint n);
+ static Property *insert(Object *o, uint index);
+ void markObjects(ExecutionEngine *e);
+
+ static void getHeadRoom(ArrayData *d);
+ static void reserve(ArrayData *d, uint n);
+
+ static void freeData(ArrayData *d);
+ 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 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 const ArrayVTable static_vtbl;
+};
+
+struct Q_QML_EXPORT SparseArrayData : public ArrayData
+{
+ SparseArrayData()
+ : freeList(0)
+ , sparse(0)
+ { vtable = &static_vtbl; }
+
+ uint freeList;
+ SparseArray *sparse;
+
+ static uint allocate(ArrayData *d);
+ static void free(ArrayData *d, uint idx);
+
+ static void freeData(ArrayData *d);
+ 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 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 const ArrayVTable static_vtbl;
+};
+
+
+inline Property *ArrayData::getProperty(uint index) const
+{
+ if (!this)
+ return 0;
+ if (type != Sparse) {
+ if (index >= len)
+ return 0;
+ return data + index;
+ } else {
+ SparseArrayNode *n = static_cast<const SparseArrayData *>(this)->sparse->findNode(index);
+ if (!n)
+ return 0;
+ return data + n->value;
+ }
+}
+
+}
+
+QT_END_NAMESPACE
+
+#endif