Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qv4estable.cpp
Go to the documentation of this file.
1// Copyright (C) 2018 Crimson AS <info@crimson.no>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qv4estable_p.h"
5#include "qv4object_p.h"
6
7using namespace QV4;
8
9// The ES spec requires that Map/Set be implemented using a data structure that
10// is a little different from most; it requires nonlinear access, and must also
11// preserve the order of insertion of items in a deterministic way.
12//
13// This class implements those requirements, except for fast access: that
14// will be addressed in a followup patch.
15
17 : m_capacity(8)
18{
19 m_keys = (Value*)malloc(m_capacity * sizeof(Value));
20 m_values = (Value*)malloc(m_capacity * sizeof(Value));
21 memset(m_keys, 0, m_capacity);
22 memset(m_values, 0, m_capacity);
23}
24
26{
27 free(m_keys);
28 free(m_values);
29 m_size = 0;
30 m_capacity = 0;
31 m_keys = nullptr;
32 m_values = nullptr;
33}
34
35void ESTable::markObjects(MarkStack *s, bool isWeakMap)
36{
37 for (uint i = 0; i < m_size; ++i) {
38 if (!isWeakMap)
39 m_keys[i].mark(s);
40 m_values[i].mark(s);
41 }
42}
43
44// Pretends that there's nothing in the table. Doesn't actually free memory, as
45// it will almost certainly be reused again anyway.
47{
48 m_size = 0;
49}
50
51// Update the table to contain \a value for a given \a key. The key is
52// normalized, as required by the ES spec.
53void ESTable::set(const Value &key, const Value &value)
54{
55 for (uint i = 0; i < m_size; ++i) {
56 if (m_keys[i].sameValueZero(key)) {
57 m_values[i] = value;
58 return;
59 }
60 }
61
62 if (m_capacity == m_size) {
63 uint oldCap = m_capacity;
64 m_capacity *= 2;
65 m_keys = (Value*)realloc(m_keys, m_capacity * sizeof(Value));
66 m_values = (Value*)realloc(m_values, m_capacity * sizeof(Value));
67 memset(m_keys + oldCap, 0, m_capacity - oldCap);
68 memset(m_values + oldCap, 0, m_capacity - oldCap);
69 }
70
71 Value nk = key;
72 if (nk.isDouble()) {
73 if (nk.doubleValue() == 0 && std::signbit(nk.doubleValue()))
74 nk = Value::fromDouble(+0);
75 }
76
77 m_keys[m_size] = nk;
78 m_values[m_size] = value;
79
80 m_size++;
81}
82
83// Returns true if the table contains \a key, false otherwise.
84bool ESTable::has(const Value &key) const
85{
86 for (uint i = 0; i < m_size; ++i) {
87 if (m_keys[i].sameValueZero(key))
88 return true;
89 }
90
91 return false;
92}
93
94// Fetches the value for the given \a key, and if \a hasValue is passed in,
95// it is set depending on whether or not the given key was found.
96ReturnedValue ESTable::get(const Value &key, bool *hasValue) const
97{
98 for (uint i = 0; i < m_size; ++i) {
99 if (m_keys[i].sameValueZero(key)) {
100 if (hasValue)
101 *hasValue = true;
102 return m_values[i].asReturnedValue();
103 }
104 }
105
106 if (hasValue)
107 *hasValue = false;
108 return Encode::undefined();
109}
110
111// Removes the given \a key from the table
113{
114 bool found = false;
115 uint idx = 0;
116 for (; idx < m_size; ++idx) {
117 if (m_keys[idx].sameValueZero(key)) {
118 found = true;
119 break;
120 }
121 }
122
123 if (found == true) {
124 memmove(m_keys + idx, m_keys + idx + 1, (m_size - idx)*sizeof(Value));
125 memmove(m_values + idx, m_values + idx + 1, (m_size - idx)*sizeof(Value));
126 m_size--;
127 }
128 return found;
129}
130
131// Returns the size of the table. Note that the size may not match the underlying allocation.
133{
134 return m_size;
135}
136
137// Retrieves a key and value for a given \a idx, and places them in \a key and
138// \a value. They must be valid pointers.
140{
141 Q_ASSERT(idx < m_size);
142 Q_ASSERT(key);
144 *key = m_keys[idx];
145 *value = m_values[idx];
146}
147
149{
150 uint idx = 0;
151 uint toIdx = 0;
152 for (; idx < m_size; ++idx) {
153 Q_ASSERT(m_keys[idx].isObject());
154 Object &o = static_cast<Object &>(m_keys[idx]);
155 if (o.d()->isMarked()) {
156 m_keys[toIdx] = m_keys[idx];
157 m_values[toIdx] = m_values[idx];
158 ++toIdx;
159 }
160 }
161 m_size = toIdx;
162}
163
ReturnedValue get(const Value &k, bool *hasValue=nullptr) const
void iterate(uint idx, Value *k, Value *v)
bool remove(const Value &k)
uint size() const
void set(const Value &k, const Value &v)
bool has(const Value &k) const
void markObjects(MarkStack *s, bool isWeakMap)
void removeUnmarkedKeys()
\qmltype Particle \inqmlmodule QtQuick.Particles
quint64 ReturnedValue
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLuint64 key
GLdouble s
[6]
Definition qopenglext.h:235
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
unsigned int uint
Definition qtypes.h:29
static constexpr ReturnedValue undefined()
constexpr ReturnedValue asReturnedValue() const
QV4_NEARLY_ALWAYS_INLINE double doubleValue() const
bool isDouble() const
void mark(MarkStack *markStack)
Definition qv4value_p.h:277
static Value fromDouble(double d)
Definition qv4value_p.h:199