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