Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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 for (uint index = 0; index < m_size; ++index) {
115 if (m_keys[index].sameValueZero(key)) {
116 // Remove the element at |index| by moving all elements to the right
117 // of |index| one place to the left.
118 size_t count = (m_size - (index + 1)) * sizeof(Value);
119 memmove(m_keys + index, m_keys + index + 1, count);
120 memmove(m_values + index, m_values + index + 1, count);
121 m_size--;
122 return true;
123 }
124 }
125 return false;
126}
127
128// Returns the size of the table. Note that the size may not match the underlying allocation.
130{
131 return m_size;
132}
133
134// Retrieves a key and value for a given \a idx, and places them in \a key and
135// \a value. They must be valid pointers.
137{
138 Q_ASSERT(idx < m_size);
139 Q_ASSERT(key);
141 *key = m_keys[idx];
142 *value = m_values[idx];
143}
144
146{
147 uint idx = 0;
148 uint toIdx = 0;
149 for (; idx < m_size; ++idx) {
150 Q_ASSERT(m_keys[idx].isObject());
151 Object &o = static_cast<Object &>(m_keys[idx]);
152 if (o.d()->isMarked()) {
153 m_keys[toIdx] = m_keys[idx];
154 m_values[toIdx] = m_values[idx];
155 ++toIdx;
156 }
157 }
158 m_size = toIdx;
159}
160
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()
quint64 ReturnedValue
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLuint64 key
GLuint index
[2]
GLenum GLenum GLsizei count
GLdouble s
[6]
Definition qopenglext.h:235
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
unsigned int uint
Definition qtypes.h:34
static constexpr ReturnedValue undefined()
constexpr ReturnedValue asReturnedValue() const
void mark(MarkStack *markStack)
Definition qv4value_p.h:277
static Value fromDouble(double d)
Definition qv4value_p.h:199