28ReturnedValue WeakSetCtor::construct(
const FunctionObject *f,
const Value *argv,
int argc,
const Value *newTarget,
bool isWeak)
31 Scoped<SetObject> a(scope, scope.engine->memoryManager->allocate<SetObject>());
32 bool protoSet =
false;
34 protoSet = a->setProtoFromNewTarget(newTarget);
35 if (!protoSet && isWeak)
36 a->setPrototypeOf(scope.engine->weakSetPrototype());
37 a->d()->isWeakSet = isWeak;
40 ScopedValue iterable(scope, argv[0]);
41 if (!iterable->isUndefined() && !iterable->isNull()) {
42 ScopedFunctionObject adder(scope, a->get(ScopedString(scope, scope.engine->newString(u"add"_s))));
44 return scope.engine->throwTypeError();
45 ScopedObject iter(scope, Runtime::GetIterator::call(scope.engine, iterable,
true));
48 return a.asReturnedValue();
50 Value *nextValue = scope.constructUndefined(1);
51 ScopedValue done(scope);
53 done = Runtime::IteratorNext::call(scope.engine, iter, nextValue);
55 if (done->toBoolean())
56 return a.asReturnedValue();
58 adder->call(a, nextValue, 1);
59 if (scope.hasException())
60 return Runtime::IteratorClose::call(scope.engine, iter);
65 return a.asReturnedValue();
84void WeakSetPrototype::init(ExecutionEngine *engine, Object *ctor)
87 ScopedObject o(scope);
88 ctor->defineReadonlyConfigurableProperty(engine->id_length(), Value::fromInt32(0));
89 ctor->defineReadonlyProperty(engine->id_prototype(), (o =
this));
90 defineDefaultProperty(engine->id_constructor(), (o = ctor));
92 defineDefaultProperty(QStringLiteral(
"add"), method_add, 1);
93 defineDefaultProperty(QStringLiteral(
"delete"), method_delete, 1);
94 defineDefaultProperty(QStringLiteral(
"has"), method_has, 1);
96 ScopedString val(scope, engine->newString(QLatin1String(
"WeakSet")));
97 defineReadonlyConfigurableProperty(engine->symbol_toStringTag(), val);
100ReturnedValue WeakSetPrototype::method_add(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
103 Scoped<SetObject> that(scope, thisObject);
104 if ((!that || !that->d()->isWeakSet) ||
105 (!argc || !argv[0].isObject()))
106 return scope.engine->throwTypeError();
108 QV4::WriteBarrier::markCustom(scope.engine, [&](QV4::MarkStack *ms) {
109 if (scope.engine->memoryManager->gcStateMachine->state <= GCState::FreeWeakSets)
111 argv[0].heapObject()->mark(ms);
114 that->d()->esTable->set(argv[0], Value::undefinedValue());
115 return that.asReturnedValue();
118ReturnedValue WeakSetPrototype::method_delete(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
121 Scoped<SetObject> that(scope, thisObject);
122 if (!that || !that->d()->isWeakSet)
123 return scope.engine->throwTypeError();
124 if (!argc || !argv[0].isObject())
125 return Encode(
false);
127 return Encode(that->d()->esTable->remove(argv[0]));
130ReturnedValue WeakSetPrototype::method_has(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
133 Scoped<SetObject> that(scope, thisObject);
134 if (!that || !that->d()->isWeakSet)
135 return scope.engine->throwTypeError();
136 if (!argc || !argv[0].isObject())
137 return Encode(
false);
139 return Encode(that->d()->esTable->has(argv[0]));
142void SetPrototype::init(ExecutionEngine *engine, Object *ctor)
145 ScopedObject o(scope);
146 ctor->defineReadonlyConfigurableProperty(engine->id_length(), Value::fromInt32(0));
147 ctor->defineReadonlyProperty(engine->id_prototype(), (o =
this));
148 ctor->addSymbolSpecies();
149 defineDefaultProperty(engine->id_constructor(), (o = ctor));
151 defineDefaultProperty(QStringLiteral(
"add"), method_add, 1);
152 defineDefaultProperty(QStringLiteral(
"clear"), method_clear, 0);
153 defineDefaultProperty(QStringLiteral(
"delete"), method_delete, 1);
154 defineDefaultProperty(QStringLiteral(
"entries"), method_entries, 0);
155 defineDefaultProperty(QStringLiteral(
"forEach"), method_forEach, 1);
156 defineDefaultProperty(QStringLiteral(
"has"), method_has, 1);
157 defineAccessorProperty(QStringLiteral(
"size"), method_get_size,
nullptr);
160 ScopedString valString(scope, scope.engine->newIdentifier(QStringLiteral(
"values")));
161 ScopedFunctionObject valuesFn(scope, FunctionObject::createBuiltinFunction(engine, valString, SetPrototype::method_values, 0));
162 defineDefaultProperty(QStringLiteral(
"keys"), valuesFn);
163 defineDefaultProperty(QStringLiteral(
"values"), valuesFn);
165 defineDefaultProperty(engine->symbol_iterator(), valuesFn);
167 ScopedString val(scope, engine->newString(QLatin1String(
"Set")));
168 defineReadonlyConfigurableProperty(engine->symbol_toStringTag(), val);
188void Heap::SetObject::markObjects(Heap::Base *that, MarkStack *markStack)
190 SetObject *s =
static_cast<SetObject *>(that);
191 s->esTable->markObjects(markStack, s->isWeakSet);
192 Object::markObjects(that, markStack);
195ReturnedValue SetPrototype::method_add(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int)
198 Scoped<SetObject> that(scope, thisObject);
199 if (!that || that->d()->isWeakSet)
200 return scope.engine->throwTypeError();
202 QV4::WriteBarrier::markCustom(scope.engine, [&](QV4::MarkStack *ms) {
203 if (
auto *h = argv[0].heapObject())
207 that->d()->esTable->set(argv[0], Value::undefinedValue());
208 return that.asReturnedValue();
211ReturnedValue SetPrototype::method_clear(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
214 Scoped<SetObject> that(scope, thisObject);
215 if (!that || that->d()->isWeakSet)
216 return scope.engine->throwTypeError();
218 that->d()->esTable->clear();
219 return Encode::undefined();
222ReturnedValue SetPrototype::method_delete(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int)
225 Scoped<SetObject> that(scope, thisObject);
226 if (!that || that->d()->isWeakSet)
227 return scope.engine->throwTypeError();
229 return Encode(that->d()->esTable->remove(argv[0]));
232ReturnedValue SetPrototype::method_entries(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
235 Scoped<SetObject> that(scope, thisObject);
236 if (!that || that->d()->isWeakSet)
237 return scope.engine->throwTypeError();
239 Scoped<SetIteratorObject> ao(scope, scope.engine->newSetIteratorObject(that));
240 ao->d()->iterationKind = IteratorKind::KeyValueIteratorKind;
241 return ao->asReturnedValue();
244ReturnedValue SetPrototype::method_forEach(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
247 Scoped<SetObject> that(scope, thisObject);
248 if (!that || that->d()->isWeakSet)
249 return scope.engine->throwTypeError();
251 ScopedFunctionObject callbackfn(scope, argv[0]);
253 return scope.engine->throwTypeError();
255 ScopedValue thisArg(scope, Value::undefinedValue());
257 thisArg = ScopedValue(scope, argv[1]);
259 ESTable::ShiftObserver observer{};
260 that->d()->esTable->observeShifts(observer);
262 Value *arguments = scope.constructUndefined(3);
263 while (observer.pivot < that->d()->esTable->size()) {
264 that->d()->esTable->iterate(observer.pivot, &arguments[0], &arguments[1]);
265 arguments[1] = arguments[0];
268 callbackfn->call(thisArg, arguments, 3);
274 that->d()->esTable->stopObservingShifts(observer);
276 return Encode::undefined();
279ReturnedValue SetPrototype::method_has(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int)
282 Scoped<SetObject> that(scope, thisObject);
283 if (!that || that->d()->isWeakSet)
284 return scope.engine->throwTypeError();
286 return Encode(that->d()->esTable->has(argv[0]));
289ReturnedValue SetPrototype::method_get_size(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
292 Scoped<SetObject> that(scope, thisObject);
293 if (!that || that->d()->isWeakSet)
294 return scope.engine->throwTypeError();
296 return Encode(that->d()->esTable->size());
299ReturnedValue SetPrototype::method_values(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
302 Scoped<SetObject> that(scope, thisObject);
303 if (!that || that->d()->isWeakSet)
304 return scope.engine->throwTypeError();
306 Scoped<SetIteratorObject> ao(scope, scope.engine->newSetIteratorObject(that));
307 ao->d()->iterationKind = IteratorKind::ValueIteratorKind;
308 return ao->asReturnedValue();