1 /****************************************************************************
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
6 ** This file is part of the QtQml module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL21$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
32 ****************************************************************************/
33 #ifndef QV4ARRAYDATA_H
34 #define QV4ARRAYDATA_H
36 #include "qv4global_p.h"
37 #include "qv4managed_p.h"
38 #include "qv4property_p.h"
39 #include "qv4sparsearray_p.h"
45 #define V4_ARRAYDATA(DataClass) \
48 typedef QV4::Heap::DataClass Data; \
49 static const QV4::ArrayVTable static_vtbl; \
50 static inline const QV4::VTable *staticVTable() { return &static_vtbl.vTable; } \
51 V4_MANAGED_SIZE_TEST \
52 const Data *d() const { return static_cast<const Data *>(m()); } \
53 Data *d() { return static_cast<Data *>(m()); }
62 Heap::ArrayData *(*reallocate)(Object *o, uint n, bool enforceAttributes);
63 ReturnedValue (*get)(const Heap::ArrayData *d, uint index);
64 bool (*put)(Object *o, uint index, const Value &value);
65 bool (*putArray)(Object *o, uint index, const Value *values, uint n);
66 bool (*del)(Object *o, uint index);
67 void (*setAttribute)(Object *o, uint index, PropertyAttributes attrs);
68 void (*push_front)(Object *o, const Value *values, uint n);
69 ReturnedValue (*pop_front)(Object *o);
70 uint (*truncate)(Object *o, uint newLen);
71 uint (*length)(const Heap::ArrayData *d);
76 struct ArrayData : public Base {
86 PropertyAttributes *attrs;
89 ReturnedValue freeList;
97 bool isSparse() const { return type == Sparse; }
99 const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(Base::vtable()); }
101 inline ReturnedValue get(uint i) const {
102 return vtable()->get(this, i);
104 inline Property *getProperty(uint index);
105 inline PropertyAttributes attributes(uint i) const;
107 bool isEmpty(uint i) const {
108 return get(i) == Primitive::emptyValue().asReturnedValue();
111 inline ReturnedValue length() const {
112 return vtable()->length(this);
117 struct SimpleArrayData : public ArrayData {
118 uint mappedIndex(uint index) const { return (index + offset) % alloc; }
119 Value data(uint index) const { return arrayData[mappedIndex(index)]; }
120 Value &data(uint index) { return arrayData[mappedIndex(index)]; }
122 Property *getProperty(uint index) {
125 index = mappedIndex(index);
126 if (arrayData[index].isEmpty())
128 return reinterpret_cast<Property *>(arrayData + index);
131 PropertyAttributes attributes(uint i) const {
132 return attrs ? attrs[i] : Attr_Data;
136 struct SparseArrayData : public ArrayData {
137 inline ~SparseArrayData();
139 uint mappedIndex(uint index) const {
140 SparseArrayNode *n = sparse->findNode(index);
146 Property *getProperty(uint index) {
147 SparseArrayNode *n = sparse->findNode(index);
150 return reinterpret_cast<Property *>(arrayData + n->value);
153 PropertyAttributes attributes(uint i) const {
156 uint index = mappedIndex(i);
157 return index < UINT_MAX ? attrs[index] : Attr_Data;
163 struct Q_QML_EXPORT ArrayData : public Managed
165 typedef Heap::ArrayData::Type Type;
166 V4_MANAGED(ArrayData, Managed)
168 uint alloc() const { return d()->alloc; }
169 uint &alloc() { return d()->alloc; }
170 void setAlloc(uint a) { d()->alloc = a; }
171 Type type() const { return d()->type; }
172 void setType(Type t) { d()->type = t; }
173 PropertyAttributes *attrs() const { return d()->attrs; }
174 void setAttrs(PropertyAttributes *a) { d()->attrs = a; }
175 const Value *arrayData() const { return &d()->arrayData[0]; }
176 Value *arrayData() { return &d()->arrayData[0]; }
178 const ArrayVTable *vtable() const { return d()->vtable(); }
179 bool isSparse() const { return type() == Heap::ArrayData::Sparse; }
181 uint length() const {
182 return d()->length();
185 bool hasAttributes() const {
188 PropertyAttributes attributes(uint i) const {
189 return d()->attributes(i);
192 bool isEmpty(uint i) const {
193 return d()->isEmpty(i);
196 ReturnedValue get(uint i) const {
199 inline Property *getProperty(uint index) {
200 return d()->getProperty(index);
203 static void ensureAttributes(Object *o);
204 static void realloc(Object *o, Type newType, uint alloc, bool enforceAttributes);
206 static void sort(ExecutionEngine *engine, Object *thisObject, const Value &comparefn, uint dataLen);
207 static uint append(Object *obj, ArrayObject *otherObj, uint n);
208 static Property *insert(Object *o, uint index, bool isAccessor = false);
211 struct Q_QML_EXPORT SimpleArrayData : public ArrayData
213 V4_ARRAYDATA(SimpleArrayData)
215 uint mappedIndex(uint index) const { return d()->mappedIndex(index); }
216 Value data(uint index) const { return d()->data(index); }
217 Value &data(uint index) { return d()->data(index); }
219 uint &len() { return d()->len; }
220 uint len() const { return d()->len; }
222 static Heap::ArrayData *reallocate(Object *o, uint n, bool enforceAttributes);
224 static void markObjects(Heap::Base *d, ExecutionEngine *e);
226 static ReturnedValue get(const Heap::ArrayData *d, uint index);
227 static bool put(Object *o, uint index, const Value &value);
228 static bool putArray(Object *o, uint index, const Value *values, uint n);
229 static bool del(Object *o, uint index);
230 static void setAttribute(Object *o, uint index, PropertyAttributes attrs);
231 static void push_front(Object *o, const Value *values, uint n);
232 static ReturnedValue pop_front(Object *o);
233 static uint truncate(Object *o, uint newLen);
234 static uint length(const Heap::ArrayData *d);
237 struct Q_QML_EXPORT SparseArrayData : public ArrayData
239 V4_ARRAYDATA(SparseArrayData)
242 ReturnedValue &freeList() { return d()->freeList; }
243 ReturnedValue freeList() const { return d()->freeList; }
244 SparseArray *sparse() const { return d()->sparse; }
245 void setSparse(SparseArray *s) { d()->sparse = s; }
247 static uint allocate(Object *o, bool doubleSlot = false);
248 static void free(Heap::ArrayData *d, uint idx);
250 uint mappedIndex(uint index) const { return d()->mappedIndex(index); }
252 static void markObjects(Heap::Base *d, ExecutionEngine *e);
254 static Heap::ArrayData *reallocate(Object *o, uint n, bool enforceAttributes);
255 static ReturnedValue get(const Heap::ArrayData *d, uint index);
256 static bool put(Object *o, uint index, const Value &value);
257 static bool putArray(Object *o, uint index, const Value *values, uint n);
258 static bool del(Object *o, uint index);
259 static void setAttribute(Object *o, uint index, PropertyAttributes attrs);
260 static void push_front(Object *o, const Value *values, uint n);
261 static ReturnedValue pop_front(Object *o);
262 static uint truncate(Object *o, uint newLen);
263 static uint length(const Heap::ArrayData *d);
268 inline SparseArrayData::~SparseArrayData()
273 inline Property *ArrayData::getProperty(uint index)
276 return static_cast<SparseArrayData *>(this)->getProperty(index);
277 return static_cast<SimpleArrayData *>(this)->getProperty(index);
280 inline PropertyAttributes ArrayData::attributes(uint i) const
283 return static_cast<const SparseArrayData *>(this)->attributes(i);
284 return static_cast<const SimpleArrayData *>(this)->attributes(i);