Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qv4arraydata_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant
4#ifndef QV4ARRAYDATA_H
5#define QV4ARRAYDATA_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qv4global_p.h"
19#include "qv4managed_p.h"
20#include "qv4property_p.h"
22
24
25namespace QV4 {
26
27#define V4_ARRAYDATA(DataClass)
28 public:
30 typedef QV4::Heap::DataClass Data;
31 static const QV4::ArrayVTable static_vtbl;
32 static inline const QV4::VTable *staticVTable() { return &static_vtbl.vTable; }
34 const Data *d() const { return static_cast<const Data *>(m()); }
35 Data *d() { return static_cast<Data *>(m()); }
36
37
38struct ArrayData;
39
41{
43 uint type;
44 Heap::ArrayData *(*reallocate)(Object *o, uint n, bool enforceAttributes);
45 ReturnedValue (*get)(const Heap::ArrayData *d, uint index);
46 bool (*put)(Object *o, uint index, const Value &value);
47 bool (*putArray)(Object *o, uint index, const Value *values, uint n);
48 bool (*del)(Object *o, uint index);
49 void (*setAttribute)(Object *o, uint index, PropertyAttributes attrs);
50 void (*push_front)(Object *o, const Value *values, uint n);
51 ReturnedValue (*pop_front)(Object *o);
52 uint (*truncate)(Object *o, uint newLen);
53 uint (*length)(const Heap::ArrayData *d);
54};
55
56namespace Heap {
57
58#define ArrayDataMembers(class, Member)
59 Member(class, NoMark, ushort, type)
60 Member(class, NoMark, ushort, unused)
61 Member(class, NoMark, uint, offset)
62 Member(class, NoMark, PropertyAttributes *, attrs)
63 Member(class, NoMark, SparseArray *, sparse)
64 Member(class, ValueArray, ValueArray, values)
65
66DECLARE_HEAP_OBJECT(ArrayData, Base) {
67 static void markObjects(Heap::Base *base, MarkStack *stack);
68
69 enum Type { Simple = 0, Sparse = 1, Custom = 2 };
70
71 bool isSparse() const { return type == Sparse; }
72
73 const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(internalClass->vtable); }
74
75 inline ReturnedValue get(uint i) const {
76 return vtable()->get(this, i);
77 }
78 inline bool getProperty(uint index, Property *p, PropertyAttributes *attrs);
79 inline void setProperty(EngineBase *e, uint index, const Property *p);
80 inline PropertyIndex getValueOrSetter(uint index, PropertyAttributes *attrs);
81 inline PropertyAttributes attributes(uint i) const;
82
83 bool isEmpty(uint i) const {
84 return get(i) == Value::emptyValue().asReturnedValue();
85 }
86
87 inline uint length() const {
88 return vtable()->length(this);
89 }
90
91 void setArrayData(EngineBase *e, uint index, Value newVal) {
92 values.set(e, index, newVal);
93 }
94
95 uint mappedIndex(uint index) const;
96};
99
100struct SimpleArrayData : public ArrayData {
101 uint mappedIndex(uint index) const { index += offset; if (index >= values.alloc) index -= values.alloc; return index; }
102 const Value &data(uint index) const { return values[mappedIndex(index)]; }
103 void setData(EngineBase *e, uint index, Value newVal) {
104 values.set(e, mappedIndex(index), newVal);
105 }
106
108 return attrs ? attrs[i] : Attr_Data;
109 }
110};
113
114struct SparseArrayData : public ArrayData {
115 void destroy() {
116 delete sparse;
117 ArrayData::destroy();
118 }
119
120 uint mappedIndex(uint index) const {
121 SparseArrayNode *n = sparse->findNode(index);
122 if (!n)
123 return UINT_MAX;
124 return n->value;
125 }
126
128 if (!attrs)
129 return Attr_Data;
130 uint index = mappedIndex(i);
131 return index < UINT_MAX ? attrs[index] : Attr_Data;
132 }
133};
134
135}
136
137struct Q_QML_EXPORT ArrayData : public Managed
138{
142 enum {
144 };
145
146 uint alloc() const { return d()->values.alloc; }
147 uint &alloc() { return d()->values.alloc; }
148 void setAlloc(uint a) { d()->values.alloc = a; }
149 Type type() const { return static_cast<Type>(d()->type); }
150 void setType(Type t) { d()->type = t; }
151 PropertyAttributes *attrs() const { return d()->attrs; }
153 const Value *arrayData() const { return d()->values.data(); }
157
158 const ArrayVTable *vtable() const { return d()->vtable(); }
159 bool isSparse() const { return type() == Heap::ArrayData::Sparse; }
160
161 uint length() const {
162 return d()->length();
163 }
164
165 bool hasAttributes() const {
166 return attrs();
167 }
169 return d()->attributes(i);
170 }
171
172 bool isEmpty(uint i) const {
173 return d()->isEmpty(i);
174 }
175
177 return d()->get(i);
178 }
179
180 static void ensureAttributes(Object *o);
181 static void realloc(Object *o, Type newType, uint alloc, bool enforceAttributes);
182
185 static void insert(Object *o, uint index, const Value *v, bool isAccessor = false);
186};
187
188struct Q_QML_EXPORT SimpleArrayData : public ArrayData
189{
192
193 uint mappedIndex(uint index) const { return d()->mappedIndex(index); }
194 Value data(uint index) const { return d()->data(index); }
195
196 uint &len() { return d()->values.size; }
197 uint len() const { return d()->values.size; }
198
200
201 static ReturnedValue get(const Heap::ArrayData *d, uint index);
202 static bool put(Object *o, uint index, const Value &value);
203 static bool putArray(Object *o, uint index, const Value *values, uint n);
204 static bool del(Object *o, uint index);
206 static void push_front(Object *o, const Value *values, uint n);
208 static uint truncate(Object *o, uint newLen);
209 static uint length(const Heap::ArrayData *d);
210};
211
212struct Q_QML_EXPORT SparseArrayData : public ArrayData
213{
217
218 SparseArray *sparse() const { return d()->sparse; }
219 void setSparse(SparseArray *s) { d()->sparse = s; }
220
221 static uint allocate(Object *o, bool doubleSlot = false);
222 static void free(Heap::ArrayData *d, uint idx);
223
224 uint mappedIndex(uint index) const { return d()->mappedIndex(index); }
225
227 static ReturnedValue get(const Heap::ArrayData *d, uint index);
228 static bool put(Object *o, uint index, const Value &value);
229 static bool putArray(Object *o, uint index, const Value *values, uint n);
230 static bool del(Object *o, uint index);
232 static void push_front(Object *o, const Value *values, uint n);
234 static uint truncate(Object *o, uint newLen);
235 static uint length(const Heap::ArrayData *d);
236};
237
239{
240public:
241 inline ArrayElementLessThan(ExecutionEngine *engine, const Value &comparefn)
242 : m_engine(engine), m_comparefn(comparefn) {}
243
244 bool operator()(Value v1, Value v2) const;
245
246private:
247 ExecutionEngine *m_engine;
248 const Value &m_comparefn;
249};
250
251template <typename RandomAccessIterator, typename LessThan>
252void sortHelper(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
253{
254top:
255 using std::swap;
256
257 int span = int(end - start);
258 if (span < 2)
259 return;
260
261 --end;
262 RandomAccessIterator low = start, high = end - 1;
263 RandomAccessIterator pivot = start + span / 2;
264
265 if (lessThan(*end, *start))
266 swap(*end, *start);
267 if (span == 2)
268 return;
269
270 if (lessThan(*pivot, *start))
271 swap(*pivot, *start);
272 if (lessThan(*end, *pivot))
273 swap(*end, *pivot);
274 if (span == 3)
275 return;
276
277 swap(*pivot, *end);
278
279 while (low < high) {
280 while (low < high && lessThan(*low, *end))
281 ++low;
282
283 while (high > low && lessThan(*end, *high))
284 --high;
285
286 if (low < high) {
287 swap(*low, *high);
288 ++low;
289 --high;
290 } else {
291 break;
292 }
293 }
294
295 if (lessThan(*low, *end))
296 ++low;
297
298 swap(*end, *low);
299 sortHelper(start, low, lessThan);
300
301 start = low + 1;
302 ++end;
303 goto top;
304}
305
306namespace Heap {
307
308inline uint ArrayData::mappedIndex(uint index) const
309{
310 if (isSparse())
311 return static_cast<const SparseArrayData *>(this)->mappedIndex(index);
312 if (index >= values.size)
313 return UINT_MAX;
314 uint idx = static_cast<const SimpleArrayData *>(this)->mappedIndex(index);
315 return values[idx].isEmpty() ? UINT_MAX : idx;
316}
317
319{
321 if (mapped == UINT_MAX) {
323 return false;
324 }
325
327 if (p) {
328 p->value = *(PropertyIndex{ this, values.values + mapped });
329 if (attrs->isAccessor())
330 p->set = *(PropertyIndex{ this, values.values + mapped + 1 /*Object::SetterOffset*/ });
331 }
332 return true;
333}
334
336{
339 values.set(e, mapped, p->value);
341 values.set(e, mapped + 1 /*QV4::Object::SetterOffset*/, p->set);
342}
343
345{
346 if (isSparse())
347 return static_cast<const SparseArrayData *>(this)->attributes(i);
348 return static_cast<const SimpleArrayData *>(this)->attributes(i);
349}
350
352{
354 if (idx == UINT_MAX) {
356 return { nullptr, nullptr };
357 }
358
360 if (attrs->isAccessor())
361 ++idx;
362 return { this, values.values + idx };
363}
364
365
366
367}
368
369}
370
371QT_END_NAMESPACE
372
373#endif
ArrayElementLessThan(ExecutionEngine *engine, const Value &comparefn)
bool operator()(Value v1, Value v2) const
ReturnedValue operator*() const
Definition qv4value_p.h:478
OptionalReturnedValue(ReturnedValue v)
Definition qv4value_p.h:471
ReturnedValue operator->() const
Definition qv4value_p.h:477
Combined button and popup list for selecting options.
DECLARE_HEAP_OBJECT(StrictArgumentsObject, Object)
DECLARE_EXPORTED_HEAP_OBJECT(Object, Base)
Definition qv4object_p.h:37
DECLARE_HEAP_OBJECT(ArgumentsObject, Object)
DECLARE_HEAP_OBJECT(MemberData, Base)
DECLARE_HEAP_OBJECT(ArrayData, Base)
CallResultDestination
Definition qjsvalue.h:24
Value Primitive
Definition qv4value_p.h:352
Scoped< FunctionObject > ScopedFunctionObject
void sortHelper(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
int qYouForgotTheQ_MANAGED_Macro(T, T)
QList< StackFrame > StackTrace
Scoped< Object > ScopedObject
ReturnedValue value_convert(ExecutionEngine *e, const Value &v)
Scoped< ArrayObject > ScopedArrayObject
Scoped< String > ScopedString
Scoped< StringOrSymbol > ScopedStringOrSymbol
void qYouForgotTheQ_MANAGED_Macro(T1, T2)
PropertyFlag
@ Attr_Invalid
@ Attr_NotConfigurable
@ Attr_Data
@ Attr_NotEnumerable
@ Attr_ReadOnly
@ Attr_NotWritable
@ Attr_ReadOnly_ButConfigurable
@ Attr_Accessor
Q_STATIC_ASSERT(sizeof(CppStackFrame)==sizeof(JSTypesStackFrame))
Scoped< ExecutionContext > ScopedContext
Q_DECLARE_TYPEINFO(QDateTime::Data, Q_RELOCATABLE_TYPE)
DEFINE_OBJECT_VTABLE(StrictArgumentsObject)
DEFINE_OBJECT_VTABLE(ArgumentsObject)
#define V4_ARRAYDATA(DataClass)
#define V4_MANAGED(DataClass, superClass)
#define V4_MANAGED_SIZE_TEST
#define V4_NEEDS_DESTROY
#define V4_MANAGED_ITSELF(DataClass, superClass)
#define Q_MANAGED_TYPE(type)
#define V4_INTERNALCLASS(c)
#define Q_MANAGED_CHECK
static qint64 virtualGetLength(const Managed *m)
static bool virtualDefineOwnProperty(Managed *m, PropertyKey id, const Property *desc, PropertyAttributes attrs)
Heap::CallContext * context() const
static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty)
static OwnPropertyKeyIterator * virtualOwnPropertyKeys(const Object *m, Value *target)
static bool isNonStrictArgumentsObject(Managed *m)
static bool virtualDeleteProperty(Managed *m, PropertyKey id)
static PropertyAttributes virtualGetOwnProperty(const Managed *m, PropertyKey id, Property *p)
bool isMapped(uint arg) const
static bool virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver)
static bool virtualDefineOwnProperty(Managed *m, PropertyKey id, const Property *p, PropertyAttributes attrs)
static qint64 virtualGetLength(const Managed *m)
QStringList toQStringList() const
void(* setAttribute)(Object *o, uint index, PropertyAttributes attrs)
bool(* putArray)(Object *o, uint index, const Value *values, uint n)
bool(* put)(Object *o, uint index, const Value &value)
void(* push_front)(Object *o, const Value *values, uint n)
ReturnedValue(* get)(const Heap::ArrayData *d, uint index)
bool(* del)(Object *o, uint index)
ReturnedValue(* pop_front)(Object *o)
static constexpr size_t offset
Definition qv4value_p.h:409
void set(EngineBase *e, HeapBasePtr b)
Definition qv4value_p.h:419
HeapBasePtr base()
Definition qv4value_p.h:410
void set(EngineBase *e, const Value &newVal)
Definition qv4value_p.h:416
void init(const QStringList &list)
void init(double val)
PropertyAttributes attributes(uint i) const
uint mappedIndex(uint index) const
void setData(EngineBase *e, uint index, Value newVal)
const Value & data(uint index) const
uint mappedIndex(uint index) const
PropertyAttributes attributes(uint i) const
static Heap::MemberData * allocate(QV4::ExecutionEngine *e, uint n, Heap::MemberData *old=nullptr)
const Value * data() const
void set(EngineBase *e, uint index, Value v)
const Value & operator[](uint idx) const
void set(EngineBase *e, uint index, Heap::Base *b)
uint size() const
PropertyKey next(const Object *o, Property *pd=nullptr, PropertyAttributes *attrs=nullptr) override
const Value * data() const
Definition qv4value_p.h:451
Value values[1]
Definition qv4value_p.h:432
void set(EngineBase *e, uint index, Value v)
Definition qv4value_p.h:441
void set(EngineBase *e, uint index, Value::HeapBasePtr b)
Definition qv4value_p.h:444
void mark(MarkStack *markStack)
Definition qv4value_p.h:455
Value::HeapBasePtr base()
Definition qv4value_p.h:434
const Value & operator[](uint index) const
Definition qv4value_p.h:447
static constexpr size_t offset
Definition qv4value_p.h:429