Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qv4setobject.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
5#include "qv4setobject_p.h"
6#include "qv4setiterator_p.h"
7#include "qv4estable_p.h"
8#include "qv4symbol_p.h"
9
10using namespace QV4;
11
15
17{
18 Heap::FunctionObject::init(scope, QStringLiteral("WeakSet"));
19}
20
22{
23 Heap::FunctionObject::init(scope, QStringLiteral("Set"));
24}
25
26ReturnedValue WeakSetCtor::construct(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget, bool isWeak)
27{
28 Scope scope(f);
29 Scoped<SetObject> a(scope, scope.engine->memoryManager->allocate<SetObject>());
30 bool protoSet = false;
31 if (newTarget)
32 protoSet = a->setProtoFromNewTarget(newTarget);
33 if (!protoSet && isWeak)
34 a->setPrototypeOf(scope.engine->weakSetPrototype());
35 a->d()->isWeakSet = isWeak;
36
37 if (argc > 0) {
38 ScopedValue iterable(scope, argv[0]);
39 if (!iterable->isUndefined() && !iterable->isNull()) {
40 ScopedFunctionObject adder(scope, a->get(ScopedString(scope, scope.engine->newString(QString::fromLatin1("add")))));
41 if (!adder)
42 return scope.engine->throwTypeError();
43 ScopedObject iter(scope, Runtime::GetIterator::call(scope.engine, iterable, true));
45 if (!iter)
46 return a.asReturnedValue();
47
48 Value *nextValue = scope.alloc(1);
50 forever {
51 done = Runtime::IteratorNext::call(scope.engine, iter, nextValue);
53 if (done->toBoolean())
54 return a.asReturnedValue();
55
56 adder->call(a, nextValue, 1);
57 if (scope.hasException()) {
58 ScopedValue falsey(scope, Encode(false));
59 return Runtime::IteratorClose::call(scope.engine, iter, falsey);
60 }
61 }
62 }
63 }
64
65 return a.asReturnedValue();
66}
67
68ReturnedValue WeakSetCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget)
69{
70 return construct(f, argv, argc, newTarget, true);
71}
72
74{
75 Scope scope(f);
76 return scope.engine->throwTypeError(QString::fromLatin1("Set requires new"));
77}
78
79ReturnedValue SetCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget)
80{
81 return construct(f, argv, argc, newTarget, false);
82}
83
85{
86 Scope scope(engine);
87 ScopedObject o(scope);
89 ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
90 defineDefaultProperty(engine->id_constructor(), (o = ctor));
91
92 defineDefaultProperty(QStringLiteral("add"), method_add, 1);
93 defineDefaultProperty(QStringLiteral("delete"), method_delete, 1);
94 defineDefaultProperty(QStringLiteral("has"), method_has, 1);
95
96 ScopedString val(scope, engine->newString(QLatin1String("WeakSet")));
97 defineReadonlyConfigurableProperty(engine->symbol_toStringTag(), val);
98}
99
100ReturnedValue WeakSetPrototype::method_add(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
101{
102 Scope scope(b);
103 Scoped<SetObject> that(scope, thisObject);
104 if ((!that || !that->d()->isWeakSet) ||
105 (!argc || !argv[0].isObject()))
106 return scope.engine->throwTypeError();
107
108 that->d()->esTable->set(argv[0], Value::undefinedValue());
109 return that.asReturnedValue();
110}
111
112ReturnedValue WeakSetPrototype::method_delete(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
113{
114 Scope scope(b);
115 Scoped<SetObject> that(scope, thisObject);
116 if (!that || !that->d()->isWeakSet)
117 return scope.engine->throwTypeError();
118 if (!argc || !argv[0].isObject())
119 return Encode(false);
120
121 return Encode(that->d()->esTable->remove(argv[0]));
122}
123
124ReturnedValue WeakSetPrototype::method_has(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
125{
126 Scope scope(b);
127 Scoped<SetObject> that(scope, thisObject);
128 if (!that || !that->d()->isWeakSet)
129 return scope.engine->throwTypeError();
130 if (!argc || !argv[0].isObject())
131 return Encode(false);
132
133 return Encode(that->d()->esTable->has(argv[0]));
134}
135
137{
138 Scope scope(engine);
139 ScopedObject o(scope);
141 ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
142 ctor->addSymbolSpecies();
143 defineDefaultProperty(engine->id_constructor(), (o = ctor));
144
145 defineDefaultProperty(QStringLiteral("add"), method_add, 1);
146 defineDefaultProperty(QStringLiteral("clear"), method_clear, 0);
147 defineDefaultProperty(QStringLiteral("delete"), method_delete, 1);
148 defineDefaultProperty(QStringLiteral("entries"), method_entries, 0);
149 defineDefaultProperty(QStringLiteral("forEach"), method_forEach, 1);
150 defineDefaultProperty(QStringLiteral("has"), method_has, 1);
151 defineAccessorProperty(QStringLiteral("size"), method_get_size, nullptr);
152
153 // Per the spec, the value for 'keys' is the same as 'values'.
154 ScopedString valString(scope, scope.engine->newIdentifier(QStringLiteral("values")));
156 defineDefaultProperty(QStringLiteral("keys"), valuesFn);
157 defineDefaultProperty(QStringLiteral("values"), valuesFn);
158
159 defineDefaultProperty(engine->symbol_iterator(), valuesFn);
160
161 ScopedString val(scope, engine->newString(QLatin1String("Set")));
162 defineReadonlyConfigurableProperty(engine->symbol_toStringTag(), val);
163}
164
166{
167 Object::init();
168 esTable = new ESTable();
169}
170
172{
173 delete esTable;
174 esTable = 0;
175}
176
178{
179 esTable->removeUnmarkedKeys();
180}
181
183{
184 SetObject *s = static_cast<SetObject *>(that);
185 s->esTable->markObjects(markStack, s->isWeakSet);
186 Object::markObjects(that, markStack);
187}
188
189ReturnedValue SetPrototype::method_add(const FunctionObject *b, const Value *thisObject, const Value *argv, int)
190{
191 Scope scope(b);
192 Scoped<SetObject> that(scope, thisObject);
193 if (!that || that->d()->isWeakSet)
194 return scope.engine->throwTypeError();
195
196 that->d()->esTable->set(argv[0], Value::undefinedValue());
197 return that.asReturnedValue();
198}
199
200ReturnedValue SetPrototype::method_clear(const FunctionObject *b, const Value *thisObject, const Value *, int)
201{
202 Scope scope(b);
203 Scoped<SetObject> that(scope, thisObject);
204 if (!that || that->d()->isWeakSet)
205 return scope.engine->throwTypeError();
206
207 that->d()->esTable->clear();
208 return Encode::undefined();
209}
210
211ReturnedValue SetPrototype::method_delete(const FunctionObject *b, const Value *thisObject, const Value *argv, int)
212{
213 Scope scope(b);
214 Scoped<SetObject> that(scope, thisObject);
215 if (!that || that->d()->isWeakSet)
216 return scope.engine->throwTypeError();
217
218 return Encode(that->d()->esTable->remove(argv[0]));
219}
220
222{
223 Scope scope(b);
224 Scoped<SetObject> that(scope, thisObject);
225 if (!that || that->d()->isWeakSet)
226 return scope.engine->throwTypeError();
227
229 ao->d()->iterationKind = IteratorKind::KeyValueIteratorKind;
230 return ao->asReturnedValue();
231}
232
233ReturnedValue SetPrototype::method_forEach(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
234{
235 Scope scope(b);
236 Scoped<SetObject> that(scope, thisObject);
237 if (!that || that->d()->isWeakSet)
238 return scope.engine->throwTypeError();
239
240 ScopedFunctionObject callbackfn(scope, argv[0]);
241 if (!callbackfn)
242 return scope.engine->throwTypeError();
243
244 ScopedValue thisArg(scope, Value::undefinedValue());
245 if (argc > 1)
246 thisArg = ScopedValue(scope, argv[1]);
247
248 Value *arguments = scope.alloc(3);
249 for (uint i = 0; i < that->d()->esTable->size(); ++i) {
250 that->d()->esTable->iterate(i, &arguments[0], &arguments[1]); // fill in key (0), value (1)
251 arguments[1] = arguments[0]; // but for set, we want to return the key twice; value is always undefined.
252
253 arguments[2] = that;
254 callbackfn->call(thisArg, arguments, 3);
256 }
257 return Encode::undefined();
258}
259
260ReturnedValue SetPrototype::method_has(const FunctionObject *b, const Value *thisObject, const Value *argv, int)
261{
262 Scope scope(b);
263 Scoped<SetObject> that(scope, thisObject);
264 if (!that || that->d()->isWeakSet)
265 return scope.engine->throwTypeError();
266
267 return Encode(that->d()->esTable->has(argv[0]));
268}
269
271{
272 Scope scope(b);
273 Scoped<SetObject> that(scope, thisObject);
274 if (!that || that->d()->isWeakSet)
275 return scope.engine->throwTypeError();
276
277 return Encode(that->d()->esTable->size());
278}
279
280ReturnedValue SetPrototype::method_values(const FunctionObject *b, const Value *thisObject, const Value *, int)
281{
282 Scope scope(b);
283 Scoped<SetObject> that(scope, thisObject);
284 if (!that || that->d()->isWeakSet)
285 return scope.engine->throwTypeError();
286
288 ao->d()->iterationKind = IteratorKind::ValueIteratorKind;
289 return ao->asReturnedValue();
290}
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5710
void markObjects(MarkStack *s, bool isWeakMap)
QList< QVariant > arguments
\qmltype Particle \inqmlmodule QtQuick.Particles
quint64 ReturnedValue
@ KeyValueIteratorKind
@ ValueIteratorKind
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter * iter
#define forever
Definition qforeach.h:78
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLfloat GLfloat f
GLuint GLfloat * val
GLdouble s
[6]
Definition qopenglext.h:235
#define QStringLiteral(str)
unsigned int uint
Definition qtypes.h:29
#define CHECK_EXCEPTION()
#define DEFINE_OBJECT_VTABLE(classname)
QJSEngine engine
[0]
static constexpr ReturnedValue undefined()
Heap::Object * newSetIteratorObject(Object *o)
Heap::String * newIdentifier(const QString &text)
ReturnedValue throwTypeError()
static Heap::FunctionObject * createBuiltinFunction(ExecutionEngine *engine, StringOrSymbol *nameOrSymbol, VTable::Call code, int argumentCount)
Heap::ExecutionContext * scope() const
void init(QV4::ExecutionContext *scope)
static void markObjects(Heap::Base *that, MarkStack *markStack)
void init(QV4::ExecutionContext *scope)
void addSymbolSpecies()
void defineReadonlyConfigurableProperty(const QString &name, const Value &value)
void defineReadonlyProperty(const QString &name, const Value &value)
static ReturnedValue call(ExecutionEngine *, const Value &, int)
static ReturnedValue call(ExecutionEngine *, const Value &, const Value &)
static ReturnedValue call(ExecutionEngine *, const Value &, Value *)
Value * alloc(qint64 nValues) const =delete
ExecutionEngine * engine
QML_NEARLY_ALWAYS_INLINE ReturnedValue asReturnedValue() const
static ReturnedValue method_get_size(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_entries(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_forEach(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_add(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_has(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_values(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_clear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
void init(ExecutionEngine *engine, Object *ctor)
static ReturnedValue method_delete(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
bool isUndefined() const
static constexpr VTable::CallAsConstructor virtualCallAsConstructor
static constexpr VTable::Call virtualCall
static constexpr Value fromInt32(int i)
Definition qv4value_p.h:187
static constexpr Value undefinedValue()
Definition qv4value_p.h:191
bool isObject() const
Definition qv4value_p.h:302
static ReturnedValue construct(const FunctionObject *f, const Value *argv, int argc, const Value *, bool weakSet)
static ReturnedValue method_add(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_has(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
void init(ExecutionEngine *engine, Object *ctor)
static ReturnedValue method_delete(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)