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};
98
99struct SimpleArrayData : public ArrayData {
100 uint mappedIndex(uint index) const { index += offset; if (index >= values.alloc) index -= values.alloc; return index; }
101 const Value &data(uint index) const { return values[mappedIndex(index)]; }
102 void setData(EngineBase *e, uint index, Value newVal) {
103 values.set(e, mappedIndex(index), newVal);
104 }
105
107 return attrs ? attrs[i] : Attr_Data;
108 }
109};
111
112struct SparseArrayData : public ArrayData {
113 void destroy() {
114 delete sparse;
115 ArrayData::destroy();
116 }
117
118 uint mappedIndex(uint index) const {
119 SparseArrayNode *n = sparse->findNode(index);
120 if (!n)
121 return UINT_MAX;
122 return n->value;
123 }
124
126 if (!attrs)
127 return Attr_Data;
128 uint index = mappedIndex(i);
129 return index < UINT_MAX ? attrs[index] : Attr_Data;
130 }
131};
132
133}
134
135struct Q_QML_EXPORT ArrayData : public Managed
136{
140 enum {
142 };
143
144 uint alloc() const { return d()->values.alloc; }
145 uint &alloc() { return d()->values.alloc; }
146 void setAlloc(uint a) { d()->values.alloc = a; }
147 Type type() const { return static_cast<Type>(d()->type); }
148 void setType(Type t) { d()->type = t; }
149 PropertyAttributes *attrs() const { return d()->attrs; }
151 const Value *arrayData() const { return d()->values.data(); }
155
156 const ArrayVTable *vtable() const { return d()->vtable(); }
157 bool isSparse() const { return type() == Heap::ArrayData::Sparse; }
158
159 uint length() const {
160 return d()->length();
161 }
162
163 bool hasAttributes() const {
164 return attrs();
165 }
167 return d()->attributes(i);
168 }
169
170 bool isEmpty(uint i) const {
171 return d()->isEmpty(i);
172 }
173
175 return d()->get(i);
176 }
177
178 static void ensureAttributes(Object *o);
179 static void realloc(Object *o, Type newType, uint alloc, bool enforceAttributes);
180
183 static void insert(Object *o, uint index, const Value *v, bool isAccessor = false);
184};
185
186struct Q_QML_EXPORT SimpleArrayData : public ArrayData
187{
190
191 uint mappedIndex(uint index) const { return d()->mappedIndex(index); }
192 Value data(uint index) const { return d()->data(index); }
193
194 uint &len() { return d()->values.size; }
195 uint len() const { return d()->values.size; }
196
198
199 static ReturnedValue get(const Heap::ArrayData *d, uint index);
200 static bool put(Object *o, uint index, const Value &value);
201 static bool putArray(Object *o, uint index, const Value *values, uint n);
202 static bool del(Object *o, uint index);
204 static void push_front(Object *o, const Value *values, uint n);
206 static uint truncate(Object *o, uint newLen);
207 static uint length(const Heap::ArrayData *d);
208};
209
210struct Q_QML_EXPORT SparseArrayData : public ArrayData
211{
215
216 SparseArray *sparse() const { return d()->sparse; }
217 void setSparse(SparseArray *s) { d()->sparse = s; }
218
219 static uint allocate(Object *o, bool doubleSlot = false);
220 static void free(Heap::ArrayData *d, uint idx);
221
222 uint mappedIndex(uint index) const { return d()->mappedIndex(index); }
223
225 static ReturnedValue get(const Heap::ArrayData *d, uint index);
226 static bool put(Object *o, uint index, const Value &value);
227 static bool putArray(Object *o, uint index, const Value *values, uint n);
228 static bool del(Object *o, uint index);
230 static void push_front(Object *o, const Value *values, uint n);
232 static uint truncate(Object *o, uint newLen);
233 static uint length(const Heap::ArrayData *d);
234};
235
237{
238public:
239 inline ArrayElementLessThan(ExecutionEngine *engine, const Value &comparefn)
240 : m_engine(engine), m_comparefn(comparefn) {}
241
242 bool operator()(Value v1, Value v2) const;
243
244private:
245 ExecutionEngine *m_engine;
246 const Value &m_comparefn;
247};
248
249template <typename RandomAccessIterator, typename LessThan>
250void sortHelper(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
251{
252top:
253 using std::swap;
254
255 int span = int(end - start);
256 if (span < 2)
257 return;
258
259 --end;
260 RandomAccessIterator low = start, high = end - 1;
261 RandomAccessIterator pivot = start + span / 2;
262
263 if (lessThan(*end, *start))
264 swap(*end, *start);
265 if (span == 2)
266 return;
267
268 if (lessThan(*pivot, *start))
269 swap(*pivot, *start);
270 if (lessThan(*end, *pivot))
271 swap(*end, *pivot);
272 if (span == 3)
273 return;
274
275 swap(*pivot, *end);
276
277 while (low < high) {
278 while (low < high && lessThan(*low, *end))
279 ++low;
280
281 while (high > low && lessThan(*end, *high))
282 --high;
283
284 if (low < high) {
285 swap(*low, *high);
286 ++low;
287 --high;
288 } else {
289 break;
290 }
291 }
292
293 if (lessThan(*low, *end))
294 ++low;
295
296 swap(*end, *low);
297 sortHelper(start, low, lessThan);
298
299 start = low + 1;
300 ++end;
301 goto top;
302}
303
304namespace Heap {
305
306inline uint ArrayData::mappedIndex(uint index) const
307{
308 if (isSparse())
309 return static_cast<const SparseArrayData *>(this)->mappedIndex(index);
310 if (index >= values.size)
311 return UINT_MAX;
312 uint idx = static_cast<const SimpleArrayData *>(this)->mappedIndex(index);
313 return values[idx].isEmpty() ? UINT_MAX : idx;
314}
315
317{
319 if (mapped == UINT_MAX) {
321 return false;
322 }
323
325 if (p) {
326 p->value = *(PropertyIndex{ this, values.values + mapped });
327 if (attrs->isAccessor())
328 p->set = *(PropertyIndex{ this, values.values + mapped + 1 /*Object::SetterOffset*/ });
329 }
330 return true;
331}
332
334{
337 values.set(e, mapped, p->value);
339 values.set(e, mapped + 1 /*QV4::Object::SetterOffset*/, p->set);
340}
341
343{
344 if (isSparse())
345 return static_cast<const SparseArrayData *>(this)->attributes(i);
346 return static_cast<const SimpleArrayData *>(this)->attributes(i);
347}
348
350{
352 if (idx == UINT_MAX) {
354 return { nullptr, nullptr };
355 }
356
358 if (attrs->isAccessor())
359 ++idx;
360 return { this, values.values + idx };
361}
362
363
364
365}
366
367}
368
369QT_END_NAMESPACE
370
371#endif
ArrayElementLessThan(ExecutionEngine *engine, const Value &comparefn)
bool operator()(Value v1, Value v2) const
ReturnedValue operator*() const
Definition qv4value_p.h:477
OptionalReturnedValue(ReturnedValue v)
Definition qv4value_p.h:470
ReturnedValue operator->() const
Definition qv4value_p.h:476
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)
Q_STATIC_ASSERT(std::is_trivial_v< ArrayData >)
CallResultDestination
Definition qjsvalue.h:23
Value Primitive
Definition qv4value_p.h:351
Scoped< FunctionObject > ScopedFunctionObject
void sortHelper(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
QVector< StackFrame > StackTrace
int qYouForgotTheQ_MANAGED_Macro(T, T)
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(QObjectPrivate::ConnectionList, 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:408
void set(EngineBase *e, HeapBasePtr b)
Definition qv4value_p.h:418
HeapBasePtr base()
Definition qv4value_p.h:409
void set(EngineBase *e, const Value &newVal)
Definition qv4value_p.h:415
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:450
Value values[1]
Definition qv4value_p.h:431
void set(EngineBase *e, uint index, Value v)
Definition qv4value_p.h:440
void set(EngineBase *e, uint index, Value::HeapBasePtr b)
Definition qv4value_p.h:443
void mark(MarkStack *markStack)
Definition qv4value_p.h:454
Value::HeapBasePtr base()
Definition qv4value_p.h:433
const Value & operator[](uint index) const
Definition qv4value_p.h:446
static constexpr size_t offset
Definition qv4value_p.h:428