Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
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
// Qt-Security score:significant
4
5
#
include
"qv4estable_p.h"
6
#
include
"qv4object_p.h"
7
8
using
namespace
QV4;
9
10
// The ES spec requires that Map/Set be implemented using a data structure that
11
// is a little different from most; it requires nonlinear access, and must also
12
// preserve the order of insertion of items in a deterministic way.
13
//
14
// This class implements those requirements, except for fast access: that
15
// will be addressed in a followup patch.
16
17
ESTable::ESTable()
18
: m_capacity(8)
19
{
20
m_keys = (Value*)malloc(m_capacity *
sizeof
(Value));
21
m_values = (Value*)malloc(m_capacity *
sizeof
(Value));
22
memset(m_keys, 0, m_capacity);
23
memset(m_values, 0, m_capacity);
24
}
25
26
ESTable::~ESTable()
27
{
28
free(m_keys);
29
free(m_values);
30
m_size = 0;
31
m_capacity = 0;
32
m_keys =
nullptr
;
33
m_values =
nullptr
;
34
}
35
36
void
ESTable::markObjects(MarkStack *s,
bool
isWeakMap)
37
{
38
for
(uint i = 0; i < m_size; ++i) {
39
if
(!isWeakMap)
40
m_keys[i].mark(s);
41
m_values[i].mark(s);
42
}
43
}
44
45
// Pretends that there's nothing in the table. Doesn't actually free memory, as
46
// it will almost certainly be reused again anyway.
47
void
ESTable::clear()
48
{
49
m_size = 0;
50
51
std::for_each(m_observers.begin(), m_observers.end(), [](ShiftObserver* ob){
52
Q_ASSERT(ob);
53
ob->pivot = ShiftObserver::OUT_OF_TABLE;
54
});
55
}
56
57
// Update the table to contain \a value for a given \a key. The key is
58
// normalized, as required by the ES spec.
59
void
ESTable::set(
const
Value &key,
const
Value &value)
60
{
61
for
(uint i = 0; i < m_size; ++i) {
62
if
(m_keys[i].sameValueZero(key)) {
63
m_values[i] = value;
64
return
;
65
}
66
}
67
68
if
(m_capacity == m_size) {
69
uint oldCap = m_capacity;
70
m_capacity *= 2;
71
m_keys = (Value*)realloc(m_keys, m_capacity *
sizeof
(Value));
72
m_values = (Value*)realloc(m_values, m_capacity *
sizeof
(Value));
73
memset(m_keys + oldCap, 0, m_capacity - oldCap);
74
memset(m_values + oldCap, 0, m_capacity - oldCap);
75
}
76
77
Value nk = key;
78
if
(nk.isDouble()) {
79
if
(nk.doubleValue() == 0 && std::signbit(nk.doubleValue()))
80
nk = Value::fromDouble(+0);
81
}
82
83
m_keys[m_size] = nk;
84
m_values[m_size] = value;
85
86
m_size++;
87
}
88
89
// Returns true if the table contains \a key, false otherwise.
90
bool
ESTable::has(
const
Value &key)
const
91
{
92
for
(uint i = 0; i < m_size; ++i) {
93
if
(m_keys[i].sameValueZero(key))
94
return
true
;
95
}
96
97
return
false
;
98
}
99
100
// Fetches the value for the given \a key, and if \a hasValue is passed in,
101
// it is set depending on whether or not the given key was found.
102
ReturnedValue ESTable::get(
const
Value &key,
bool
*hasValue)
const
103
{
104
for
(uint i = 0; i < m_size; ++i) {
105
if
(m_keys[i].sameValueZero(key)) {
106
if
(hasValue)
107
*hasValue =
true
;
108
return
m_values[i].asReturnedValue();
109
}
110
}
111
112
if
(hasValue)
113
*hasValue =
false
;
114
return
Encode::undefined();
115
}
116
117
// Removes the given \a key from the table
118
bool
ESTable::remove(
const
Value &key)
119
{
120
for
(uint index = 0; index < m_size; ++index) {
121
if
(m_keys[index].sameValueZero(key)) {
122
// Remove the element at |index| by moving all elements to the right
123
// of |index| one place to the left.
124
size_t count = (m_size - (index + 1)) *
sizeof
(Value);
125
memmove(m_keys + index, m_keys + index + 1, count);
126
memmove(m_values + index, m_values + index + 1, count);
127
m_size--;
128
129
std::for_each(m_observers.begin(), m_observers.end(), [index](ShiftObserver* ob) {
130
Q_ASSERT(ob);
131
if
(index <= ob->pivot && ob->pivot != ShiftObserver::OUT_OF_TABLE)
132
ob->pivot = ob->pivot == 0 ? ShiftObserver::OUT_OF_TABLE : ob->pivot - 1;
133
});
134
135
return
true
;
136
}
137
}
138
return
false
;
139
}
140
141
// Returns the size of the table. Note that the size may not match the underlying allocation.
142
uint ESTable::size()
const
143
{
144
return
m_size;
145
}
146
147
// Retrieves a key and value for a given \a idx, and places them in \a key and
148
// \a value. They must be valid pointers.
149
void
ESTable::iterate(uint idx, Value *key, Value *value)
150
{
151
Q_ASSERT(idx < m_size);
152
Q_ASSERT(key);
153
Q_ASSERT(value);
154
*key = m_keys[idx];
155
*value = m_values[idx];
156
}
157
158
void
ESTable::removeUnmarkedKeys()
159
{
160
uint idx = 0;
161
uint toIdx = 0;
162
for
(; idx < m_size; ++idx) {
163
Q_ASSERT(m_keys[idx].isObject());
164
Object &o =
static_cast
<Object &>(m_keys[idx]);
165
if
(o.d()->isMarked()) {
166
m_keys[toIdx] = m_keys[idx];
167
m_values[toIdx] = m_values[idx];
168
++toIdx;
169
}
170
}
171
m_size = toIdx;
172
}
qtdeclarative
src
qml
jsruntime
qv4estable.cpp
Generated on
for Qt by
1.18.0