26ReturnedValue WeakMapCtor::construct(
const FunctionObject *f,
const Value *argv,
int argc,
const Value *newTarget,
bool weakMap)
29 Scoped<MapObject> a(scope, scope.engine->memoryManager->allocate<MapObject>());
30 bool protoSet =
false;
32 protoSet = a->setProtoFromNewTarget(newTarget);
33 if (!protoSet && weakMap) {
34 a->setPrototypeOf(scope.engine->weakMapPrototype());
35 scope.engine->memoryManager->registerWeakMap(a->d());
37 a->d()->isWeakMap = weakMap;
40 ScopedValue iterable(scope, argv[0]);
42 if (!iterable->isNullOrUndefined()) {
43 ScopedFunctionObject adder(scope, a->get(ScopedString(scope, scope.engine->newString(QString::fromLatin1(
"set")))));
45 return scope.engine->throwTypeError();
47 ScopedObject iter(scope, Runtime::GetIterator::call(scope.engine, iterable,
true));
48 if (scope.hasException())
49 return Encode::undefined();
52 ScopedValue obj(scope);
53 Value *arguments = scope.constructUndefined(2);
54 ScopedValue done(scope);
56 done = Runtime::IteratorNext::call(scope.engine, iter, obj);
57 if (scope.hasException())
59 if (done->toBoolean())
60 return a->asReturnedValue();
61 const Object *o = obj->objectValue();
63 scope.engine->throwTypeError();
67 arguments[0] = o->get(PropertyKey::fromArrayIndex(0));
68 if (scope.hasException())
70 arguments[1] = o->get(PropertyKey::fromArrayIndex(1));
71 if (scope.hasException())
74 adder->call(a, arguments, 2);
75 if (scope.hasException())
78 return Runtime::IteratorClose::call(scope.engine, iter);
81 return a->asReturnedValue();
102void WeakMapPrototype::init(ExecutionEngine *engine, Object *ctor)
105 ScopedObject o(scope);
106 ctor->defineReadonlyConfigurableProperty(engine->id_length(), Value::fromInt32(0));
107 ctor->defineReadonlyProperty(engine->id_prototype(), (o =
this));
108 defineDefaultProperty(engine->id_constructor(), (o = ctor));
110 defineDefaultProperty(QStringLiteral(
"delete"), method_delete, 1);
111 defineDefaultProperty(QStringLiteral(
"get"), method_get, 1);
112 defineDefaultProperty(QStringLiteral(
"has"), method_has, 1);
113 defineDefaultProperty(QStringLiteral(
"set"), method_set, 2);
115 ScopedString val(scope, engine->newString(QLatin1String(
"WeakMap")));
116 defineReadonlyConfigurableProperty(engine->symbol_toStringTag(), val);
120void MapPrototype::init(ExecutionEngine *engine, Object *ctor)
123 ScopedObject o(scope);
124 ctor->defineReadonlyConfigurableProperty(engine->id_length(), Value::fromInt32(0));
125 ctor->defineReadonlyProperty(engine->id_prototype(), (o =
this));
126 ctor->addSymbolSpecies();
127 defineDefaultProperty(engine->id_constructor(), (o = ctor));
129 defineDefaultProperty(QStringLiteral(
"clear"), method_clear, 0);
130 defineDefaultProperty(QStringLiteral(
"delete"), method_delete, 1);
131 defineDefaultProperty(QStringLiteral(
"forEach"), method_forEach, 1);
132 defineDefaultProperty(QStringLiteral(
"get"), method_get, 1);
133 defineDefaultProperty(QStringLiteral(
"has"), method_has, 1);
134 defineDefaultProperty(QStringLiteral(
"keys"), method_keys, 0);
135 defineDefaultProperty(QStringLiteral(
"set"), method_set, 2);
136 defineAccessorProperty(QStringLiteral(
"size"), method_get_size,
nullptr);
137 defineDefaultProperty(QStringLiteral(
"values"), method_values, 0);
140 ScopedString valString(scope, scope.engine->newIdentifier(QStringLiteral(
"entries")));
141 ScopedFunctionObject entriesFn(scope, FunctionObject::createBuiltinFunction(engine, valString, MapPrototype::method_entries, 0));
142 defineDefaultProperty(QStringLiteral(
"entries"), entriesFn);
143 defineDefaultProperty(engine->symbol_iterator(), entriesFn);
145 ScopedString val(scope, engine->newString(QLatin1String(
"Map")));
146 defineReadonlyConfigurableProperty(engine->symbol_toStringTag(), val);
166void Heap::MapObject::markObjects(Heap::Base *that, MarkStack *markStack)
168 MapObject *m =
static_cast<MapObject *>(that);
169 m->esTable->markObjects(markStack, m->isWeakMap);
170 Object::markObjects(that, markStack);
173ReturnedValue WeakMapPrototype::method_delete(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
176 Scoped<MapObject> that(scope, thisObject);
177 if (!that || !that->d()->isWeakMap)
178 return scope.engine->throwTypeError();
179 if (!argc || !argv[0].isObject())
180 return Encode(
false);
182 return Encode(that->d()->esTable->remove(argv[0]));
186ReturnedValue WeakMapPrototype::method_get(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
189 Scoped<MapObject> that(scope, thisObject);
190 if (!that || !that->d()->isWeakMap)
191 return scope.engine->throwTypeError();
192 if (!argc || !argv[0].isObject())
193 return Encode::undefined();
195 return that->d()->esTable->get(argv[0]);
198ReturnedValue WeakMapPrototype::method_has(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
201 Scoped<MapObject> that(scope, thisObject);
202 if (!that || !that->d()->isWeakMap)
203 return scope.engine->throwTypeError();
204 if (!argc || !argv[0].isObject())
205 return Encode(
false);
207 return Encode(that->d()->esTable->has(argv[0]));
210ReturnedValue WeakMapPrototype::method_set(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
213 Scoped<MapObject> that(scope, thisObject);
214 if ((!that || !that->d()->isWeakMap) ||
215 (!argc || !argv[0].isObject()))
216 return scope.engine->throwTypeError();
218 QV4::WriteBarrier::markCustom(scope.engine, [&](QV4::MarkStack *ms) {
219 if (scope.engine->memoryManager->gcStateMachine->state <= GCState::FreeWeakMaps)
221 Q_ASSERT(argv[0].heapObject());
222 argv[0].heapObject()->mark(ms);
224 if (
auto *h = argv[1].heapObject())
229 that->d()->esTable->set(argv[0], argc > 1 ? argv[1] : Value::undefinedValue());
230 return that.asReturnedValue();
234ReturnedValue MapPrototype::method_clear(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
237 Scoped<MapObject> that(scope, thisObject);
238 if (!that || that->d()->isWeakMap)
239 return scope.engine->throwTypeError();
241 that->d()->esTable->clear();
242 return Encode::undefined();
245ReturnedValue MapPrototype::method_delete(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
248 Scoped<MapObject> that(scope, thisObject);
249 if (!that || that->d()->isWeakMap)
250 return scope.engine->throwTypeError();
252 return Encode(that->d()->esTable->remove(argc ? argv[0] : Value::undefinedValue()));
255ReturnedValue MapPrototype::method_entries(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
258 Scoped<MapObject> that(scope, thisObject);
259 if (!that || that->d()->isWeakMap)
260 return scope.engine->throwTypeError();
262 Scoped<MapIteratorObject> ao(scope, scope.engine->newMapIteratorObject(that));
263 ao->d()->iterationKind = IteratorKind::KeyValueIteratorKind;
264 return ao->asReturnedValue();
267ReturnedValue MapPrototype::method_forEach(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
270 Scoped<MapObject> that(scope, thisObject);
271 if (!that || that->d()->isWeakMap)
272 return scope.engine->throwTypeError();
274 ScopedFunctionObject callbackfn(scope, argv[0]);
276 return scope.engine->throwTypeError();
278 ScopedValue thisArg(scope, Value::undefinedValue());
280 thisArg = ScopedValue(scope, argv[1]);
282 Value *arguments = scope.constructUndefined(3);
285 ESTable::ShiftObserver observer{};
286 that->d()->esTable->observeShifts(observer);
288 while (observer.pivot < that->d()->esTable->size()) {
289 that->d()->esTable->iterate(observer.pivot, &arguments[1], &arguments[0]);
291 callbackfn->call(thisArg, arguments, 3);
297 that->d()->esTable->stopObservingShifts(observer);
299 return Encode::undefined();
302ReturnedValue MapPrototype::method_get(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
305 Scoped<MapObject> that(scope, thisObject);
306 if (!that || that->d()->isWeakMap)
307 return scope.engine->throwTypeError();
309 return that->d()->esTable->get(argc ? argv[0] : Value::undefinedValue());
312ReturnedValue MapPrototype::method_has(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
315 Scoped<MapObject> that(scope, thisObject);
316 if (!that || that->d()->isWeakMap)
317 return scope.engine->throwTypeError();
319 return Encode(that->d()->esTable->has(argc ? argv[0] : Value::undefinedValue()));
322ReturnedValue MapPrototype::method_keys(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
325 Scoped<MapObject> that(scope, thisObject);
326 if (!that || that->d()->isWeakMap)
327 return scope.engine->throwTypeError();
329 Scoped<MapIteratorObject> ao(scope, scope.engine->newMapIteratorObject(that));
330 ao->d()->iterationKind = IteratorKind::KeyIteratorKind;
331 return ao->asReturnedValue();
334ReturnedValue MapPrototype::method_set(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
337 Scoped<MapObject> that(scope, thisObject);
338 if (!that || that->d()->isWeakMap)
339 return scope.engine->throwTypeError();
341 QV4::WriteBarrier::markCustom(scope.engine, [&](QV4::MarkStack *ms) {
342 if (
auto *h = argv[0].heapObject())
345 if (
auto *h = argv[1].heapObject())
350 that->d()->esTable->set(argc ? argv[0] : Value::undefinedValue(), argc > 1 ? argv[1] : Value::undefinedValue());
351 return that.asReturnedValue();
354ReturnedValue MapPrototype::method_get_size(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
357 Scoped<MapObject> that(scope, thisObject);
358 if (!that || that->d()->isWeakMap)
359 return scope.engine->throwTypeError();
361 return Encode(that->d()->esTable->size());
364ReturnedValue MapPrototype::method_values(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
367 Scoped<MapObject> that(scope, thisObject);
368 if (!that || that->d()->isWeakMap)
369 return scope.engine->throwTypeError();
371 Scoped<MapIteratorObject> ao(scope, scope.engine->newMapIteratorObject(that));
372 ao->d()->iterationKind = IteratorKind::ValueIteratorKind;
373 return ao->asReturnedValue();