Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qv4arrayobject.cpp
Go to the documentation of this file.
1// Copyright (C) 2018 Crimson AS <info@crimson.no>
2// Copyright (C) 2016 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qv4arrayobject_p.h"
7#include "qv4objectproto_p.h"
9#include "qv4runtime_p.h"
10#include "qv4symbol_p.h"
11#include <QtCore/qscopedvaluerollback.h>
12
13using namespace QV4;
14
16
18{
19 Heap::FunctionObject::init(scope, QStringLiteral("Array"));
20}
21
22ReturnedValue ArrayCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget)
23{
24 ExecutionEngine *v4 = static_cast<const ArrayCtor *>(f)->engine();
25 Scope scope(v4);
27 if (newTarget)
28 a->setProtoFromNewTarget(newTarget);
29 uint len;
30 if (argc == 1 && argv[0].isNumber()) {
31 bool ok;
32 len = argv[0].asArrayLength(&ok);
33
34 if (!ok)
35 return v4->throwRangeError(argv[0]);
36
37 if (len < 0x1000)
38 a->arrayReserve(len);
39 } else {
40 len = argc;
41 a->arrayReserve(len);
42 a->arrayPut(0, argv, len);
43 }
44 a->setArrayLengthUnchecked(len);
45
46 return a.asReturnedValue();
47}
48
49ReturnedValue ArrayCtor::virtualCall(const FunctionObject *f, const Value *, const Value *argv, int argc)
50{
51 return virtualCallAsConstructor(f, argv, argc, f);
52}
53
55{
56 Scope scope(engine);
57 ScopedObject o(scope);
59 ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
60 ctor->defineDefaultProperty(QStringLiteral("isArray"), method_isArray, 1);
61 ctor->defineDefaultProperty(QStringLiteral("of"), method_of, 0);
62 ctor->defineDefaultProperty(QStringLiteral("from"), method_from, 1);
63 ctor->addSymbolSpecies();
64
66 ->changeVTable(QV4::Object::staticVTable()));
67 ScopedObject unscopables(scope, engine->newObject(ic->d()));
68 ScopedString name(scope);
69 defineDefaultProperty(QStringLiteral("constructor"), (o = ctor));
70 defineDefaultProperty(engine->id_toString(), method_toString, 0);
71 defineDefaultProperty(engine->id_toLocaleString(), method_toLocaleString, 0);
72 defineDefaultProperty(QStringLiteral("concat"), method_concat, 1);
73 name = engine->newIdentifier(QStringLiteral("copyWithin"));
74 unscopables->put(name, Value::fromBoolean(true));
75 defineDefaultProperty(name, method_copyWithin, 2);
76 name = engine->newIdentifier(QStringLiteral("entries"));
77 unscopables->put(name, Value::fromBoolean(true));
78 defineDefaultProperty(name, method_entries, 0);
79 name = engine->newIdentifier(QStringLiteral("fill"));
80 unscopables->put(name, Value::fromBoolean(true));
81 defineDefaultProperty(name, method_fill, 1);
82 name = engine->newIdentifier(QStringLiteral("find"));
83 unscopables->put(name, Value::fromBoolean(true));
84 defineDefaultProperty(name, method_find, 1);
85 name = engine->newIdentifier(QStringLiteral("findIndex"));
86 unscopables->put(name, Value::fromBoolean(true));
87 defineDefaultProperty(name, method_findIndex, 1);
88 name = engine->newIdentifier(QStringLiteral("includes"));
89 unscopables->put(name, Value::fromBoolean(true));
90 defineDefaultProperty(name, method_includes, 1);
91 defineDefaultProperty(QStringLiteral("join"), method_join, 1);
92 name = engine->newIdentifier(QStringLiteral("keys"));
93 unscopables->put(name, Value::fromBoolean(true));
94 defineDefaultProperty(name, method_keys, 0);
95 defineDefaultProperty(QStringLiteral("pop"), method_pop, 0);
96 defineDefaultProperty(QStringLiteral("push"), method_push, 1);
97 defineDefaultProperty(QStringLiteral("reverse"), method_reverse, 0);
98 defineDefaultProperty(QStringLiteral("shift"), method_shift, 0);
99 defineDefaultProperty(QStringLiteral("slice"), method_slice, 2);
100 defineDefaultProperty(QStringLiteral("sort"), method_sort, 1);
101 defineDefaultProperty(QStringLiteral("splice"), method_splice, 2);
102 defineDefaultProperty(QStringLiteral("unshift"), method_unshift, 1);
103 defineDefaultProperty(QStringLiteral("indexOf"), method_indexOf, 1);
104 defineDefaultProperty(QStringLiteral("lastIndexOf"), method_lastIndexOf, 1);
105 defineDefaultProperty(QStringLiteral("every"), method_every, 1);
106 defineDefaultProperty(QStringLiteral("some"), method_some, 1);
107 defineDefaultProperty(QStringLiteral("forEach"), method_forEach, 1);
108 defineDefaultProperty(QStringLiteral("map"), method_map, 1);
109 defineDefaultProperty(QStringLiteral("filter"), method_filter, 1);
110 defineDefaultProperty(QStringLiteral("reduce"), method_reduce, 1);
111 defineDefaultProperty(QStringLiteral("reduceRight"), method_reduceRight, 1);
112 ScopedString valuesString(scope, engine->newIdentifier(QStringLiteral("values")));
113 ScopedObject values(scope, FunctionObject::createBuiltinFunction(engine, valuesString, method_values, 0));
115 unscopables->put(valuesString, Value::fromBoolean(true));
116 defineDefaultProperty(valuesString, values);
117 defineDefaultProperty(engine->symbol_iterator(), values);
118
119 defineReadonlyConfigurableProperty(engine->symbol_unscopables(), unscopables);
120}
121
123{
124 if (!argc || !argv->objectValue())
125 return Encode(false);
126 return Encode(argv->objectValue()->isArray());
127}
128
130{
132
133 if (ctor && ctor->isConstructor()) {
134 // this isn't completely kosher. for instance:
135 // Array.from.call(Object, []).constructor == Object
136 // is expected by the tests, but naturally, we get Number.
139 a = ctor->callAsConstructor(argument, useLen ? 1 : 0);
140 } else {
141 a = scope.engine->newArrayObject(len);
142 }
143
144 return a;
145}
146
147ReturnedValue ArrayPrototype::method_from(const FunctionObject *builtin, const Value *thisObject, const Value *argv, int argc)
148{
149 Scope scope(builtin);
150 ScopedFunctionObject thatCtor(scope, thisObject);
151 ScopedObject itemsObject(scope, argv[0]);
152 bool usingIterator = false;
153
154 if (itemsObject) {
155 // If the object claims to support iterators, then let's try use them.
156 ScopedValue it(scope, itemsObject->get(scope.engine->symbol_iterator()));
157 if (!it->isNullOrUndefined()) {
158 ScopedFunctionObject itfunc(scope, it);
159 if (!itfunc)
160 return scope.engine->throwTypeError();
161 usingIterator = true;
162 }
163 }
164
166 Value *mapArguments = nullptr;
167 if (argc > 1) {
168 mapfn = ScopedFunctionObject(scope, argv[1]);
169 if (!mapfn)
170 return scope.engine->throwTypeError(QString::fromLatin1("%1 is not a function").arg(argv[1].toQStringNoThrow()));
171 mapArguments = scope.alloc(2);
172 }
173
174 ScopedValue thisArg(scope);
175 if (argc > 2)
176 thisArg = argv[2];
177
178 if (usingIterator) {
179 // Item iteration supported, so let's go ahead and try use that.
180 ScopedObject a(createObjectFromCtorOrArray(scope, thatCtor, false, 0));
182 ScopedObject iterator(scope, Runtime::GetIterator::call(scope.engine, itemsObject, true));
183 CHECK_EXCEPTION(); // symbol_iterator threw; whoops.
184 if (!iterator) {
185 return scope.engine->throwTypeError(); // symbol_iterator wasn't an object.
186 }
187
188 qint64 k = 0;
189 ScopedValue mappedValue(scope);
190 Value *nextValue = scope.alloc(1);
191 ScopedValue done(scope);
192
193 // The loop below pulls out all the properties using the iterator, and
194 // sets them into the created array.
195 forever {
196 if (k > (static_cast<qint64>(1) << 53) - 1) {
197 ScopedValue falsey(scope, Encode(false));
198 ScopedValue error(scope, scope.engine->throwTypeError());
199 return Runtime::IteratorClose::call(scope.engine, iterator, falsey);
200 }
201
202 // Retrieve the next value. If the iteration ends, we're done here.
205 if (done->toBoolean()) {
206 if (ArrayObject *ao = a->as<ArrayObject>()) {
207 ao->setArrayLengthUnchecked(k);
208 } else {
211 }
212 return a.asReturnedValue();
213 }
214
215 if (mapfn) {
216 Q_ASSERT(mapArguments); // if mapfn is set, we always setup mapArguments with scope.alloc
217 mapArguments[0] = *nextValue;
218 mapArguments[1] = Value::fromDouble(k);
219 mappedValue = mapfn->call(thisArg, mapArguments, 2);
220 if (scope.hasException())
221 return Runtime::IteratorClose::call(scope.engine, iterator, Value::fromBoolean(false));
222 } else {
223 mappedValue = *nextValue;
224 }
225
226 if (a->getOwnProperty(PropertyKey::fromArrayIndex(k)) == Attr_Invalid) {
227 a->arraySet(k, mappedValue);
228 } else {
229 // Don't return: we need to close the iterator.
230 scope.engine->throwTypeError(QString::fromLatin1("Cannot redefine property: %1").arg(k));
231 }
232
233 if (scope.hasException()) {
234 ScopedValue falsey(scope, Encode(false));
235 return Runtime::IteratorClose::call(scope.engine, iterator, falsey);
236 }
237
238 k++;
239 }
240
241 // the return is hidden up in the loop above, when iteration finishes.
242 } else {
243 // Array-like fallback. We request properties by index, and set them on
244 // the return object.
245 ScopedObject arrayLike(scope, argv[0].toObject(scope.engine));
246 if (!arrayLike)
247 return scope.engine->throwTypeError(QString::fromLatin1("Cannot convert %1 to object").arg(argv[0].toQStringNoThrow()));
248 qint64 len = arrayLike->getLength();
249 ScopedObject a(createObjectFromCtorOrArray(scope, thatCtor, true, len));
251
252 qint64 k = 0;
253 ScopedValue mappedValue(scope, Value::undefinedValue());
254 ScopedValue kValue(scope);
255 while (k < len) {
256 kValue = arrayLike->get(k);
258
259 if (mapfn) {
260 Q_ASSERT(mapArguments); // if mapfn is set, we always setup mapArguments with scope.alloc
261 mapArguments[0] = kValue;
262 mapArguments[1] = Value::fromDouble(k);
263 mappedValue = mapfn->call(thisArg, mapArguments, 2);
265 } else {
266 mappedValue = kValue;
267 }
268
269 if (a->getOwnProperty(PropertyKey::fromArrayIndex(k)) != Attr_Invalid)
270 return scope.engine->throwTypeError(QString::fromLatin1("Cannot redefine property: %1").arg(k));
271
272 a->arraySet(k, mappedValue);
274
275 k++;
276 }
277
278 if (ArrayObject *ao = a->as<ArrayObject>()) {
279 ao->setArrayLengthUnchecked(k);
280 } else {
283 }
284 return a.asReturnedValue();
285 }
286
287}
288
289ReturnedValue ArrayPrototype::method_of(const FunctionObject *builtin, const Value *thisObject, const Value *argv, int argc)
290{
291 Scope scope(builtin);
292 ScopedFunctionObject that(scope, thisObject);
293 ScopedObject a(createObjectFromCtorOrArray(scope, that, true, argc));
295
296 int k = 0;
297 while (k < argc) {
298 if (a->getOwnProperty(PropertyKey::fromArrayIndex(k)) != Attr_Invalid) {
299 return scope.engine->throwTypeError(QString::fromLatin1("Cannot redefine property: %1").arg(k));
300 }
301 a->arraySet(k, argv[k]);
303
304 k++;
305 }
306
307 // ArrayObject updates its own length, and will throw if we try touch it.
308 if (!a->as<ArrayObject>()) {
311 }
312
313 return a.asReturnedValue();
314}
315
316ReturnedValue ArrayPrototype::method_toString(const FunctionObject *builtin, const Value *thisObject, const Value *argv, int argc)
317{
318 Scope scope(builtin);
319 ScopedObject that(scope, thisObject->toObject(scope.engine));
320 if (scope.hasException())
321 return QV4::Encode::undefined();
322
323 ScopedString string(scope, scope.engine->newString(QStringLiteral("join")));
324 ScopedFunctionObject f(scope, that->get(string));
325 if (f)
326 return checkedResult(scope.engine, f->call(that, argv, argc));
327 return ObjectPrototype::method_toString(builtin, that, argv, argc);
328}
329
331{
332 Scope scope(b);
333 ScopedObject instance(scope, thisObject);
334 if (!instance)
335 return scope.engine->throwTypeError();
336
337 uint len = instance->getLength();
338 const QString separator = QStringLiteral(",");
339
340 QString R;
341
342 ScopedValue v(scope);
343 ScopedString s(scope);
344
345 ScopedPropertyKey tolocaleString(scope, scope.engine->id_toLocaleString()->toPropertyKey());
347
348 for (uint k = 0; k < len; ++k) {
349 if (k)
350 R += separator;
351
352 v = instance->get(k);
353 if (v->isNullOrUndefined())
354 continue;
355
356 ScopedObject valueAsObject(scope, v->toObject(scope.engine));
357 Q_ASSERT(valueAsObject); // null and undefined handled above
358
359 ScopedFunctionObject function(scope, valueAsObject->get(tolocaleString));
360 if (!function)
361 return scope.engine->throwTypeError();
362
363 v = function->call(valueAsObject, nullptr, 0);
364 if (scope.hasException())
365 return Encode::undefined();
366
367 s = v->toString(scope.engine);
368 if (scope.hasException())
369 return Encode::undefined();
370
371 R += s->toQString();
372 }
373 return scope.engine->newString(R)->asReturnedValue();
374}
375
376ReturnedValue ArrayPrototype::method_concat(const FunctionObject *b, const Value *that, const Value *argv, int argc)
377{
378 Scope scope(b);
379 ScopedObject thisObject(scope, that->toObject(scope.engine));
380 if (!thisObject)
382
384
385 ScopedArrayObject elt(scope);
386 ScopedObject eltAsObj(scope);
387 ScopedValue entry(scope);
388 for (int i = -1; i < argc; ++i) {
389 const Value *v = i == -1 ? thisObject.getPointer() : argv + i;
390 eltAsObj = *v;
391 elt = *v;
392 if (elt) {
393 uint n = elt->getLength();
394 uint newLen = ArrayData::append(result, elt, n);
395 result->setArrayLengthUnchecked(newLen);
396 } else if (eltAsObj && eltAsObj->isConcatSpreadable()) {
397 const uint startIndex = result->getLength();
398 const uint len = eltAsObj->getLength();
399 if (scope.hasException())
400 return Encode::undefined();
401
402 for (uint i = 0; i < len; ++i) {
403 bool hasProperty = false;
404 entry = eltAsObj->get(i, &hasProperty);
405 if (hasProperty) {
406 if (!result->put(startIndex + i, entry))
407 return scope.engine->throwTypeError();
408 }
409 }
410 } else if (eltAsObj && eltAsObj->isArrayLike()) {
411 const uint startIndex = result->getLength();
412 for (int i = 0, len = eltAsObj->getLength(); i < len; ++i) {
413 entry = eltAsObj->get(i);
414 // spec says not to throw if this fails
415 result->put(startIndex + i, entry);
416 }
417 } else {
418 result->arraySet(result->getLength(), *v);
419 }
420 }
421
422 return result.asReturnedValue();
423}
424
425ReturnedValue ArrayPrototype::method_copyWithin(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
426{
427 Scope scope(b);
428 ScopedObject instance(scope, thisObject->toObject(scope.engine));
429 if (!instance)
431
432 double len = instance->getLength();
433 double target = argv[0].toInteger();
434 double start = argc > 1 ? argv[1].toInteger() : 0;
435 double end = len;
436
437 if (argc > 2 && !argv[2].isUndefined()) {
438 end = argv[2].toInteger();
439 }
440
441 double relativeTarget = target;
442 double relativeStart = start;
443 double relativeEnd = end;
444 double from = 0;
445 double to = 0;
446
447 if (relativeTarget < 0) {
448 to = std::max(len+relativeTarget, 0.0);
449 } else {
450 to = std::min(relativeTarget, len);
451 }
452 if (relativeStart < 0) {
453 from = std::max(len+relativeStart, 0.0);
454 } else {
455 from = std::min(relativeStart, len);
456 }
457
458 double fin = 0;
459 if (relativeEnd < 0) {
460 fin = std::max(len+relativeEnd, 0.0);
461 } else {
462 fin = std::min(relativeEnd, len);
463 }
464 double count = std::min(fin-from, len-to);
465 double direction = 1;
466 if (from < to && to < from+count) {
467 direction = -1;
468 from = from + count - 1;
469 to = to + count - 1;
470 }
471
472 while (count > 0) {
473 bool fromPresent = false;
474 ScopedValue fromVal(scope, instance->get(from, &fromPresent));
475
476 if (fromPresent) {
477 instance->setIndexed(to, fromVal, QV4::Object::DoThrowOnRejection);
479 } else {
480 bool didDelete = instance->deleteProperty(PropertyKey::fromArrayIndex(to));
482 if (!didDelete) {
483 return scope.engine->throwTypeError();
484 }
485 }
486
487 from = from + direction;
488 to = to + direction;
489 count = count - 1;
490 }
491
492 return instance.asReturnedValue();
493}
494
496{
497 Scope scope(b);
498 ScopedObject O(scope, thisObject->toObject(scope.engine));
499 if (!O)
501
503 ao->d()->iterationKind = IteratorKind::KeyValueIteratorKind;
504 return ao->asReturnedValue();
505}
506
507ReturnedValue ArrayPrototype::method_find(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
508{
509 Scope scope(b);
510 ScopedObject instance(scope, thisObject->toObject(scope.engine));
511 if (!instance)
513
514 uint len = instance->getLength();
515
516 if (!argc || !argv[0].isFunctionObject())
518 const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
519
520 ScopedValue result(scope);
521 Value *arguments = scope.alloc(3);
522
523 ScopedValue that(scope, argc > 1 ? argv[1] : Value::undefinedValue());
524
525 for (uint k = 0; k < len; ++k) {
526 arguments[0] = instance->get(k);
528
530 arguments[2] = instance;
531 result = callback->call(that, arguments, 3);
532
534 if (result->toBoolean())
535 return arguments[0].asReturnedValue();
536 }
537
539}
540
541ReturnedValue ArrayPrototype::method_findIndex(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
542{
543 Scope scope(b);
544 ScopedObject instance(scope, thisObject->toObject(scope.engine));
545 if (!instance)
547
548 uint len = instance->getLength();
549
550 if (!argc || !argv[0].isFunctionObject())
552 const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
553
554 ScopedValue result(scope);
555 Value *arguments = scope.alloc(3);
556
557 ScopedValue that(scope, argc > 1 ? argv[1] : Value::undefinedValue());
558
559 for (uint k = 0; k < len; ++k) {
560 arguments[0] = instance->get(k);
562
564 arguments[2] = instance;
565 result = callback->call(that, arguments, 3);
566
568 if (result->toBoolean())
569 return Encode(k);
570 }
571
572 return Encode(-1);
573}
574
576 const Value *thisObject, const Value *argv, int argc)
577{
578 Scope scope(functionObject);
579 ScopedObject instance(scope, thisObject->toObject(scope.engine));
580
581 if (!instance)
582 return Encode(scope.engine->newString());
583
584 // We cannot optimize the resolution of the argument away in case of length == 0
585 // It may have side effects.
586 ScopedValue argument(scope, argc ? argv[0] : Value::undefinedValue());
587 const QString separator = argument->isUndefined()
588 ? QStringLiteral(",")
589 : argument->toQString();
590
591 ScopedValue scopedLength(scope, instance->get(scope.engine->id_length()));
592 const quint32 genericLength = scopedLength->isUndefined() ? 0 : scopedLength->toUInt32();
593 if (!genericLength)
594 return Encode(scope.engine->newString());
595
597 if (auto *arrayObject = instance->as<ArrayObject>()) {
598 ScopedValue entry(scope);
599 const qint64 arrayLength = arrayObject->getLength();
600 Q_ASSERT(arrayLength >= 0);
601 Q_ASSERT(arrayLength <= std::numeric_limits<quint32>::max());
602 for (quint32 i = 0; i < quint32(arrayLength); ++i) {
603 if (i)
604 result += separator;
605
606 entry = arrayObject->get(i);
608 if (!entry->isNullOrUndefined())
609 result += entry->toQString();
610 }
611 } else {
612 ScopedString name(scope, scope.engine->newString(QStringLiteral("0")));
613 ScopedValue value(scope, instance->get(name));
615
616 if (!value->isNullOrUndefined())
617 result = value->toQString();
618
619 for (quint32 i = 1; i < genericLength; ++i) {
620 result += separator;
621
623 value = instance->get(name);
625
626 if (!value->isNullOrUndefined())
627 result += value->toQString();
628 }
629 }
630
631 return Encode(scope.engine->newString(result));
632}
633
634ReturnedValue ArrayPrototype::method_pop(const FunctionObject *b, const Value *thisObject, const Value *, int)
635{
636 Scope scope(b);
637 ScopedObject instance(scope, thisObject->toObject(scope.engine));
638 if (!instance)
640
641 uint len = instance->getLength();
642
643 if (!len) {
644 if (!instance->isArrayObject())
645 instance->put(scope.engine->id_length(), ScopedValue(scope, Value::fromInt32(0)));
647 }
648
649 ScopedValue result(scope, instance->get(len - 1));
651
652 if (!instance->deleteProperty(PropertyKey::fromArrayIndex(len - 1)))
653 return scope.engine->throwTypeError();
654
655 if (instance->isArrayObject())
656 instance->setArrayLength(len - 1);
657 else {
658 if (!instance->put(scope.engine->id_length(), ScopedValue(scope, Value::fromDouble(len - 1))))
659 return scope.engine->throwTypeError();
660 }
661 return result->asReturnedValue();
662}
663
664ReturnedValue ArrayPrototype::method_push(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
665{
666 Scope scope(b);
667 ScopedObject instance(scope, thisObject->toObject(scope.engine));
668 if (!instance)
670
671 instance->arrayCreate();
672 Q_ASSERT(instance->arrayData());
673
674 qint64 len = instance->getLength();
675
676 if (len + quint64(argc) >= UINT_MAX) {
677 // ughh... this goes beyond UINT_MAX
678 double l = len;
679 ScopedString s(scope);
680 for (int i = 0, ei = argc; i < ei; ++i) {
681 s = Value::fromDouble(l + i).toString(scope.engine);
682 if (!instance->put(s, argv[i]))
683 return scope.engine->throwTypeError();
684 }
685 double newLen = l + argc;
686 if (!instance->isArrayObject()) {
687 if (!instance->put(scope.engine->id_length(), ScopedValue(scope, Value::fromDouble(newLen))))
688 return scope.engine->throwTypeError();
689 } else {
690 ScopedString str(scope, scope.engine->newString(QStringLiteral("Array.prototype.push: Overflow")));
691 return scope.engine->throwRangeError(str);
692 }
693 return Encode(newLen);
694 }
695
696 if (!argc)
697 ;
698 else if (!instance->protoHasArray() && instance->arrayData()->length() <= len && instance->arrayData()->type == Heap::ArrayData::Simple) {
699 instance->arrayData()->vtable()->putArray(instance, len, argv, argc);
700 len = instance->arrayData()->length();
701 } else {
702 for (int i = 0, ei = argc; i < ei; ++i) {
703 if (!instance->put(len + i, argv[i]))
704 return scope.engine->throwTypeError();
705 }
706 len += argc;
707 }
708 if (instance->isArrayObject())
709 instance->setArrayLengthUnchecked(len);
710 else {
711 if (!instance->put(scope.engine->id_length(), ScopedValue(scope, Value::fromDouble(len))))
712 return scope.engine->throwTypeError();
713 }
714
715 return Encode(uint(len));
716}
717
719{
720 Scope scope(b);
721 ScopedObject instance(scope, thisObject->toObject(scope.engine));
722 if (!instance)
724
725 qint64 length = instance->getLength();
726 // ### FIXME
727 if (length >= UINT_MAX)
728 return scope.engine->throwRangeError(QLatin1String("Array.prototype.reverse: Length out of range."));
729
730 int lo = 0, hi = length - 1;
731
732 ScopedValue lval(scope);
733 ScopedValue hval(scope);
734 for (; lo < hi; ++lo, --hi) {
735 bool loExists, hiExists;
736 lval = instance->get(lo, &loExists);
737 hval = instance->get(hi, &hiExists);
739 bool ok;
740 if (hiExists)
741 ok = instance->put(lo, hval);
742 else
743 ok = instance->deleteProperty(PropertyKey::fromArrayIndex(lo));
744 if (ok) {
745 if (loExists)
746 ok = instance->put(hi, lval);
747 else
748 ok = instance->deleteProperty(PropertyKey::fromArrayIndex(hi));
749 }
750 if (!ok)
751 return scope.engine->throwTypeError();
752 }
753 return instance->asReturnedValue();
754}
755
757{
758 Scope scope(b);
759 ScopedObject instance(scope, thisObject->toObject(scope.engine));
760 if (!instance)
762
763 instance->arrayCreate();
764 Q_ASSERT(instance->arrayData());
765
766 uint len = instance->getLength();
767
768 if (!len) {
769 if (!instance->isArrayObject())
770 if (!instance->put(scope.engine->id_length(), ScopedValue(scope, Value::fromInt32(0))))
771 return scope.engine->throwTypeError();
773 }
774
775 ScopedValue result(scope);
776 if (!instance->protoHasArray() && !instance->arrayData()->attrs && instance->arrayData()->length() <= len && instance->arrayData()->type != Heap::ArrayData::Custom) {
777 result = instance->arrayData()->vtable()->pop_front(instance);
778 } else {
779 result = instance->get(uint(0));
781 ScopedValue v(scope);
782 // do it the slow way
783 for (uint k = 1; k < len; ++k) {
784 bool exists;
785 v = instance->get(k, &exists);
787 bool ok;
788 if (exists)
789 ok = instance->put(k - 1, v);
790 else
791 ok = instance->deleteProperty(PropertyKey::fromArrayIndex(k - 1));
792 if (!ok)
793 return scope.engine->throwTypeError();
794 }
795 bool ok = instance->deleteProperty(PropertyKey::fromArrayIndex(len - 1));
796 if (!ok)
797 return scope.engine->throwTypeError();
798 }
799
800 if (instance->isArrayObject())
801 instance->setArrayLengthUnchecked(len - 1);
802 else {
803 bool ok = instance->put(scope.engine->id_length(), ScopedValue(scope, Value::fromDouble(len - 1)));
804 if (!ok)
805 return scope.engine->throwTypeError();
806 }
807
808 return result->asReturnedValue();
809}
810
811ReturnedValue ArrayPrototype::method_slice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
812{
813 Scope scope(b);
814 ScopedObject o(scope, thisObject->toObject(scope.engine));
815 if (!o)
817
819 uint len = o->getLength();
820 double s = (argc ? argv[0] : Value::undefinedValue()).toInteger();
821 uint start;
822 if (s < 0)
823 start = (uint)qMax(len + s, 0.);
824 else if (s > len)
825 start = len;
826 else
827 start = (uint) s;
828 uint end = len;
829 if (argc > 1 && !argv[1].isUndefined()) {
830 double e = argv[1].toInteger();
831 if (e < 0)
832 end = (uint)qMax(len + e, 0.);
833 else if (e > len)
834 end = len;
835 else
836 end = (uint) e;
837 }
838
839 ScopedValue v(scope);
840 uint n = 0;
841 for (uint i = start; i < end; ++i) {
842 bool exists;
843 v = o->get(i, &exists);
845 if (exists)
846 result->arraySet(n, v);
847 ++n;
848 }
849 return result->asReturnedValue();
850}
851
852ReturnedValue ArrayPrototype::method_sort(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
853{
854 Scope scope(b);
855 ScopedObject instance(scope, thisObject->toObject(scope.engine));
856 if (!instance)
858
859 uint len = instance->getLength();
860
861 ScopedValue comparefn(scope, argc ? argv[0] : Value::undefinedValue());
862 ArrayData::sort(scope.engine, instance, comparefn, len);
863 return thisObject->asReturnedValue();
864}
865
866ReturnedValue ArrayPrototype::method_splice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
867{
868 Scope scope(b);
869 ScopedObject instance(scope, thisObject->toObject(scope.engine));
870 if (!instance)
872
873 qint64 len = instance->getLength();
874
875 double rs = (argc ? argv[0] : Value::undefinedValue()).toInteger();
877 if (rs < 0)
878 start = static_cast<qint64>(qMax(0., len + rs));
879 else
880 start = static_cast<qint64>(qMin(rs, static_cast<double>(len)));
881
882 qint64 deleteCount = 0;
883 qint64 itemCount = 0;
884 if (argc == 1) {
885 deleteCount = len - start;
886 } else if (argc > 1){
887 itemCount = argc - 2;
888 double dc = argv[1].toInteger();
889 deleteCount = static_cast<qint64>(qMin(qMax(dc, 0.), double(len - start)));
890 }
891
892 if (len + itemCount - deleteCount > /*(static_cast<qint64>(1) << 53) - 1*/ UINT_MAX - 1)
893 return scope.engine->throwTypeError();
894 if (deleteCount > /*(static_cast<qint64>(1) << 53) - 1*/ UINT_MAX - 1)
895 return scope.engine->throwRangeError(QString::fromLatin1("Array length out of range."));
896
897 ScopedArrayObject newArray(scope, scope.engine->newArrayObject());
898 newArray->arrayReserve(deleteCount);
899 ScopedValue v(scope);
900 for (uint i = 0; i < deleteCount; ++i) {
901 bool exists;
902 v = instance->get(start + i, &exists);
904 if (exists)
905 newArray->arrayPut(i, v);
906 }
907 newArray->setArrayLengthUnchecked(deleteCount);
908
909
910 if (itemCount < deleteCount) {
911 for (uint k = start; k < len - deleteCount; ++k) {
912 bool exists;
913 v = instance->get(k + deleteCount, &exists);
915 bool ok;
916 if (exists)
917 ok = instance->put(k + itemCount, v);
918 else
919 ok = instance->deleteProperty(PropertyKey::fromArrayIndex(k + itemCount));
920 if (!ok)
921 return scope.engine->throwTypeError();
922 }
923 for (uint k = len; k > len - deleteCount + itemCount; --k) {
924 if (!instance->deleteProperty(PropertyKey::fromArrayIndex(k - 1)))
925 return scope.engine->throwTypeError();
926 }
927 } else if (itemCount > deleteCount) {
928 uint k = len - deleteCount;
929 while (k > start) {
930 bool exists;
931 v = instance->get(k + deleteCount - 1, &exists);
933 bool ok;
934 if (exists)
935 ok = instance->put(k + itemCount - 1, v);
936 else
937 ok = instance->deleteProperty(PropertyKey::fromArrayIndex(k + itemCount - 1));
938 if (!ok)
939 return scope.engine->throwTypeError();
940 --k;
941 }
942 }
943
944 for (uint i = 0; i < itemCount; ++i)
945 instance->put(start + i, argv[i + 2]);
946
947 if (!instance->put(scope.engine->id_length(), ScopedValue(scope, Value::fromDouble(len - deleteCount + itemCount))))
948 return scope.engine->throwTypeError();
949
950 return newArray->asReturnedValue();
951}
952
953ReturnedValue ArrayPrototype::method_unshift(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
954{
955 Scope scope(b);
956 ScopedObject instance(scope, thisObject->toObject(scope.engine));
957 if (!instance)
959
960 instance->arrayCreate();
961 Q_ASSERT(instance->arrayData());
962
963 uint len = instance->getLength();
964
965 if (!instance->protoHasArray() && !instance->arrayData()->attrs && instance->arrayData()->length() <= len &&
966 instance->arrayData()->type != Heap::ArrayData::Custom) {
967 instance->arrayData()->vtable()->push_front(instance, argv, argc);
968 } else {
969 ScopedValue v(scope);
970 for (uint k = len; k > 0; --k) {
971 bool exists;
972 v = instance->get(k - 1, &exists);
973 bool ok;
974 if (exists)
975 ok = instance->put(k + argc - 1, v);
976 else
977 ok = instance->deleteProperty(PropertyKey::fromArrayIndex(k + argc - 1));
978 if (!ok)
979 return scope.engine->throwTypeError();
980 }
981 for (int i = 0, ei = argc; i < ei; ++i) {
982 bool ok = instance->put(i, argv[i]);
983 if (!ok)
984 return scope.engine->throwTypeError();
985 }
986 }
987
988 uint newLen = len + argc;
989 if (instance->isArrayObject())
990 instance->setArrayLengthUnchecked(newLen);
991 else {
992 if (!instance->put(scope.engine->id_length(), ScopedValue(scope, Value::fromDouble(newLen))))
993 return scope.engine->throwTypeError();
994 }
995
996 return Encode(newLen);
997}
998
999ReturnedValue ArrayPrototype::method_includes(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1000{
1001 Scope scope(b);
1002 ScopedObject instance(scope, thisObject->toObject(scope.engine));
1003 if (!instance)
1005
1006 qint64 len = instance->getLength();
1007 if (len == 0) {
1008 return Encode(false);
1009 }
1010
1011 double n = 0;
1012 if (argc > 1 && !argv[1].isUndefined()) {
1013 n = argv[1].toInteger();
1014 }
1015
1016 double k = 0;
1017 if (n >= 0) {
1018 k = n;
1019 } else {
1020 k = len + n;
1021 if (k < 0) {
1022 k = 0;
1023 }
1024 }
1025
1026 ScopedValue val(scope);
1027 while (k < len) {
1028 val = instance->get(k);
1029 if (val->sameValueZero(argv[0])) {
1030 return Encode(true);
1031 }
1032 k++;
1033 }
1034
1035 return Encode(false);
1036}
1037
1038ReturnedValue ArrayPrototype::method_indexOf(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1039{
1040 Scope scope(b);
1041 ScopedObject instance(scope, thisObject->toObject(scope.engine));
1042 if (!instance)
1044
1045 uint len = instance->getLength();
1046 if (!len)
1047 return Encode(-1);
1048
1049 ScopedValue searchValue(scope, argc ? argv[0] : Value::undefinedValue());
1050 uint fromIndex = 0;
1051
1052 if (argc >= 2) {
1053 double f = argv[1].toInteger();
1055 if (f >= len)
1056 return Encode(-1);
1057 if (f < 0)
1058 f = qMax(len + f, 0.);
1059 fromIndex = (uint) f;
1060 }
1061
1062 if (instance->isStringObject()) {
1063 ScopedValue v(scope);
1064 for (uint k = fromIndex; k < len; ++k) {
1065 bool exists;
1066 v = instance->get(k, &exists);
1067 if (exists && RuntimeHelpers::strictEqual(v, searchValue))
1068 return Encode(k);
1069 }
1070 return Encode(-1);
1071 }
1072
1073 ScopedValue value(scope);
1074
1076 (instance->arrayType() >= Heap::ArrayData::Sparse) || instance->protoHasArray()) {
1077 // lets be safe and slow
1078 for (uint i = fromIndex; i < len; ++i) {
1079 bool exists;
1080 value = instance->get(i, &exists);
1082 if (exists && RuntimeHelpers::strictEqual(value, searchValue))
1083 return Encode(i);
1084 }
1085 } else if (!instance->arrayData()) {
1086 return Encode(-1);
1087 } else {
1088 Q_ASSERT(instance->arrayType() == Heap::ArrayData::Simple);
1089 Heap::SimpleArrayData *sa = instance->d()->arrayData.cast<Heap::SimpleArrayData>();
1090 if (len > sa->values.size)
1091 len = sa->values.size;
1092 uint idx = fromIndex;
1093 while (idx < len) {
1094 value = sa->data(idx);
1096 if (RuntimeHelpers::strictEqual(value, searchValue))
1097 return Encode(idx);
1098 ++idx;
1099 }
1100 }
1101 return Encode(-1);
1102}
1103
1105{
1106 Scope scope(f);
1107 ScopedObject O(scope, thisObject->toObject(scope.engine));
1108 if (!O)
1110
1112 ao->d()->iterationKind = IteratorKind::KeyIteratorKind;
1113 return ao->asReturnedValue();
1114}
1115
1116ReturnedValue ArrayPrototype::method_lastIndexOf(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1117{
1118 Scope scope(b);
1119 ScopedObject instance(scope, thisObject->toObject(scope.engine));
1120 if (!instance)
1122
1123 uint len = instance->getLength();
1124 if (!len)
1125 return Encode(-1);
1126
1127 ScopedValue searchValue(scope);
1128 uint fromIndex = len;
1129
1130 if (argc >= 1)
1131 searchValue = argv[0];
1132 else
1133 searchValue = Value::undefinedValue();
1134
1135 if (argc >= 2) {
1136 double f = argv[1].toInteger();
1138 if (f > 0)
1139 f = qMin(f, (double)(len - 1));
1140 else if (f < 0) {
1141 f = len + f;
1142 if (f < 0)
1143 return Encode(-1);
1144 }
1145 fromIndex = (uint) f + 1;
1146 }
1147
1148 ScopedValue v(scope);
1149 for (uint k = fromIndex; k > 0;) {
1150 --k;
1151 bool exists;
1152 v = instance->get(k, &exists);
1154 if (exists && RuntimeHelpers::strictEqual(v, searchValue))
1155 return Encode(k);
1156 }
1157 return Encode(-1);
1158}
1159
1160ReturnedValue ArrayPrototype::method_every(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1161{
1162 Scope scope(b);
1163 ScopedObject instance(scope, thisObject->toObject(scope.engine));
1164 if (!instance)
1166
1167 uint len = instance->getLength();
1168
1169 if (!argc || !argv->isFunctionObject())
1171 const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
1172
1173 ScopedValue that(scope, argc > 1 ? argv[1] : Value::undefinedValue());
1174 ScopedValue r(scope);
1175 Value *arguments = scope.alloc(3);
1176
1177 bool ok = true;
1178 for (uint k = 0; ok && k < len; ++k) {
1179 bool exists;
1180 arguments[0] = instance->get(k, &exists);
1181 if (!exists)
1182 continue;
1183
1185 arguments[2] = instance;
1186 r = callback->call(that, arguments, 3);
1188 ok = r->toBoolean();
1189 }
1190 return Encode(ok);
1191}
1192
1193ReturnedValue ArrayPrototype::method_fill(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1194{
1195 Scope scope(b);
1196 ScopedObject instance(scope, thisObject->toObject(scope.engine));
1197 if (!instance)
1199
1200 const qsizetype len = instance->getLength();
1201 Q_ASSERT(len >= 0);
1202
1203 const qsizetype relativeStart = argc > 1 ? argv[1].toInteger() : 0;
1204 qsizetype relativeEnd = len;
1205 if (argc > 2 && !argv[2].isUndefined())
1206 relativeEnd = argv[2].toInteger();
1207
1208 qsizetype k = 0;
1209 qsizetype fin = 0;
1210
1211 if (relativeStart < 0) {
1212 if (relativeStart > -len)
1213 k = std::max(len + relativeStart, qsizetype(0));
1214 } else {
1215 k = std::min(relativeStart, len);
1216 }
1217 Q_ASSERT(k >= 0);
1218
1219 if (relativeEnd < 0) {
1220 if (relativeEnd > -len)
1221 fin = std::max(len + relativeEnd, qsizetype(0));
1222 } else {
1223 fin = std::min(relativeEnd, len);
1224 }
1225 Q_ASSERT(fin >= 0);
1226
1227 if (sizeof(qsizetype) > sizeof(uint) && fin > qsizetype(std::numeric_limits<uint>::max()))
1228 return scope.engine->throwRangeError(QString::fromLatin1("Array length out of range."));
1229
1230 for (; k < fin; ++k)
1231 instance->setIndexed(uint(k), argv[0], QV4::Object::DoThrowOnRejection);
1232
1233 return instance.asReturnedValue();
1234}
1235
1236ReturnedValue ArrayPrototype::method_some(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1237{
1238 Scope scope(b);
1239 ScopedObject instance(scope, thisObject->toObject(scope.engine));
1240 if (!instance)
1242
1243 uint len = instance->getLength();
1244
1245 if (!argc || !argv->isFunctionObject())
1247 const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
1248
1249 ScopedValue that(scope, argc > 1 ? argv[1] : Value::undefinedValue());
1250 ScopedValue result(scope);
1251 Value *arguments = scope.alloc(3);
1252
1253 for (uint k = 0; k < len; ++k) {
1254 bool exists;
1255 arguments[0] = instance->get(k, &exists);
1256 if (!exists)
1257 continue;
1258
1260 arguments[2] = instance;
1261 result = callback->call(that, arguments, 3);
1263 if (result->toBoolean())
1264 return Encode(true);
1265 }
1266 return Encode(false);
1267}
1268
1269ReturnedValue ArrayPrototype::method_forEach(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1270{
1271 Scope scope(b);
1272 ScopedObject instance(scope, thisObject->toObject(scope.engine));
1273 if (!instance)
1275
1276 uint len = instance->getLength();
1277
1278 if (!argc || !argv->isFunctionObject())
1280 const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
1281
1282 ScopedValue that(scope, argc > 1 ? argv[1] : Value::undefinedValue());
1283 Value *arguments = scope.alloc(3);
1284
1285 for (uint k = 0; k < len; ++k) {
1286 bool exists;
1287 arguments[0] = instance->get(k, &exists);
1288 if (!exists)
1289 continue;
1290
1292 arguments[2] = instance;
1293 callback->call(that, arguments, 3);
1294 }
1296}
1297
1298ReturnedValue ArrayPrototype::method_map(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1299{
1300 Scope scope(b);
1301 ScopedObject instance(scope, thisObject->toObject(scope.engine));
1302 if (!instance)
1304
1305 qint64 len = instance->getLength();
1306
1307 if (!argc || !argv->isFunctionObject())
1309 const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
1310
1311 if (len > UINT_MAX - 1)
1312 return scope.engine->throwRangeError(QString::fromLatin1("Array length out of range."));
1313
1314 ScopedArrayObject a(scope, scope.engine->newArrayObject());
1315 a->arrayReserve(len);
1316 a->setArrayLengthUnchecked(len);
1317
1318 ScopedValue v(scope);
1319 ScopedValue mapped(scope);
1320 ScopedValue that(scope, argc > 1 ? argv[1] : Value::undefinedValue());
1321 Value *arguments = scope.alloc(3);
1322
1323 for (uint k = 0; k < len; ++k) {
1324 bool exists;
1325 arguments[0] = instance->get(k, &exists);
1326 if (!exists)
1327 continue;
1328
1330 arguments[2] = instance;
1331 mapped = callback->call(that, arguments, 3);
1333 a->arraySet(k, mapped);
1334 }
1335 return a.asReturnedValue();
1336}
1337
1338ReturnedValue ArrayPrototype::method_filter(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1339{
1340 Scope scope(b);
1341 ScopedObject instance(scope, thisObject->toObject(scope.engine));
1342 if (!instance)
1344
1345 uint len = instance->getLength();
1346
1347 if (!argc || !argv->isFunctionObject())
1349 const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
1350
1351 ScopedArrayObject a(scope, scope.engine->newArrayObject());
1352 a->arrayReserve(len);
1353
1354 ScopedValue selected(scope);
1355 ScopedValue that(scope, argc > 1 ? argv[1] : Value::undefinedValue());
1356 Value *arguments = scope.alloc(3);
1357
1358 uint to = 0;
1359 for (uint k = 0; k < len; ++k) {
1360 bool exists;
1361 arguments[0] = instance->get(k, &exists);
1362 if (!exists)
1363 continue;
1364
1366 arguments[2] = instance;
1367 selected = callback->call(that, arguments, 3);
1369 if (selected->toBoolean()) {
1370 a->arraySet(to, arguments[0]);
1371 ++to;
1372 }
1373 }
1374 return a.asReturnedValue();
1375}
1376
1377ReturnedValue ArrayPrototype::method_reduce(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1378{
1379 Scope scope(b);
1380 ScopedObject instance(scope, thisObject->toObject(scope.engine));
1381 if (!instance)
1383
1384 uint len = instance->getLength();
1385
1386 if (!argc || !argv->isFunctionObject())
1388 const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
1389
1390 uint k = 0;
1391 ScopedValue acc(scope);
1392 ScopedValue v(scope);
1393
1394 if (argc > 1) {
1395 acc = argv[1];
1396 } else {
1397 bool kPresent = false;
1398 while (k < len && !kPresent) {
1399 v = instance->get(k, &kPresent);
1400 if (kPresent)
1401 acc = v;
1402 ++k;
1403 }
1404 if (!kPresent)
1406 }
1407
1408 Value *arguments = scope.alloc(4);
1409
1410 while (k < len) {
1411 bool kPresent;
1412 v = instance->get(k, &kPresent);
1413 if (kPresent) {
1414 arguments[0] = acc;
1415 arguments[1] = v;
1417 arguments[3] = instance;
1418 acc = callback->call(nullptr, arguments, 4);
1420 }
1421 ++k;
1422 }
1423 return acc->asReturnedValue();
1424}
1425
1426ReturnedValue ArrayPrototype::method_reduceRight(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1427{
1428 Scope scope(b);
1429 ScopedObject instance(scope, thisObject->toObject(scope.engine));
1430 if (!instance)
1432
1433 uint len = instance->getLength();
1434
1435 if (!argc || !argv->isFunctionObject())
1437 const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
1438
1439 if (len == 0) {
1440 if (argc == 1)
1442 return argv[1].asReturnedValue();
1443 }
1444
1445 uint k = len;
1446 ScopedValue acc(scope);
1447 ScopedValue v(scope);
1448 if (argc > 1) {
1449 acc = argv[1];
1450 } else {
1451 bool kPresent = false;
1452 while (k > 0 && !kPresent) {
1453 v = instance->get(k - 1, &kPresent);
1454 if (kPresent)
1455 acc = v;
1456 --k;
1457 }
1458 if (!kPresent)
1460 }
1461
1462 Value *arguments = scope.alloc(4);
1463
1464 while (k > 0) {
1465 bool kPresent;
1466 v = instance->get(k - 1, &kPresent);
1467 if (kPresent) {
1468 arguments[0] = acc;
1469 arguments[1] = v;
1470 arguments[2] = Value::fromDouble(k - 1);
1471 arguments[3] = instance;
1472 acc = callback->call(nullptr, arguments, 4);
1474 }
1475 --k;
1476 }
1477 return acc->asReturnedValue();
1478}
1479
1481{
1482 Scope scope(b);
1483 ScopedObject O(scope, thisObject->toObject(scope.engine));
1484 if (!O)
1486
1488 ao->d()->iterationKind = IteratorKind::ValueIteratorKind;
1489 return ao->asReturnedValue();
1490}
1491
1493{
1494 return thisObject->asReturnedValue();
1495}
1496
QJSValue newObject()
Creates a JavaScript object of class Object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
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
QString str
[2]
double e
QSet< QString >::iterator it
QList< QVariant > arguments
direction
\qmltype Particle \inqmlmodule QtQuick.Particles
Scoped< FunctionObject > ScopedFunctionObject
quint64 ReturnedValue
@ KeyValueIteratorKind
@ ValueIteratorKind
@ KeyIteratorKind
ReturnedValue checkedResult(QV4::ExecutionEngine *v4, ReturnedValue result)
@ Attr_Invalid
static int arrayLength(const QString &rawType)
Definition provider.cpp:52
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
DBusConnection const char DBusError * error
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define forever
Definition qforeach.h:78
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLenum GLsizei GLsizei GLint * values
[15]
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLboolean r
[2]
GLuint GLuint end
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei count
GLfloat GLfloat f
GLenum target
GLuint start
GLuint name
GLfloat n
GLuint GLfloat * val
GLuint entry
GLenum GLsizei len
GLuint64EXT * result
[6]
GLdouble s
[6]
Definition qopenglext.h:235
GLsizei const GLchar *const * string
[0]
Definition qopenglext.h:694
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
SSL_CTX int(*) void arg)
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
unsigned int quint32
Definition qtypes.h:45
unsigned long long quint64
Definition qtypes.h:56
ptrdiff_t qsizetype
Definition qtypes.h:70
unsigned int uint
Definition qtypes.h:29
long long qint64
Definition qtypes.h:55
static ScopedObject createObjectFromCtorOrArray(Scope &scope, ScopedFunctionObject ctor, bool useLen, int len)
#define THROW_TYPE_ERROR()
#define CHECK_EXCEPTION()
#define RETURN_UNDEFINED()
#define DEFINE_OBJECT_VTABLE(classname)
QDBusArgument argument
QJSEngine engine
[0]
static bool isNonStrictArgumentsObject(Managed *m)
static void sort(ExecutionEngine *engine, Object *thisObject, const Value &comparefn, uint dataLen)
static uint append(Object *obj, ArrayObject *otherObj, uint n)
static ReturnedValue method_lastIndexOf(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_from(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_isArray(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_includes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_reduceRight(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_shift(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_indexOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_find(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_of(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_reduce(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_reverse(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLocaleString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_species(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_findIndex(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_slice(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_every(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_concat(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_values(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
void init(ExecutionEngine *engine, Object *ctor)
static ReturnedValue method_entries(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_copyWithin(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_filter(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_unshift(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_some(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_push(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_join(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_pop(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_sort(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_fill(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_map(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_keys(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_splice(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static constexpr ReturnedValue undefined()
Symbol * symbol_iterator() const
Heap::String * newString(const QString &s=QString())
ReturnedValue throwRangeError(const Value &value)
String * id_length() const
String * id_toLocaleString() const
Heap::ArrayObject * newArrayObject(int count=0)
Heap::Object * newArrayIteratorObject(Object *o)
ReturnedValue throwTypeError()
static Heap::FunctionObject * createBuiltinFunction(ExecutionEngine *engine, StringOrSymbol *nameOrSymbol, VTable::Call code, int argumentCount)
ReturnedValue call(const JSCallData &data) const
Heap::ExecutionContext * scope() const
void init(QV4::ExecutionContext *scope)
ReturnedValue asReturnedValue() const
Definition qv4value_p.h:339
const Value & data(uint index) const
ExecutionEngine * engine() const
static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
void defineDefaultProperty(StringOrSymbol *name, const Value &value, PropertyAttributes attributes=Attr_Data|Attr_NotEnumerable)
bool isArray() const
void addSymbolSpecies()
void defineReadonlyConfigurableProperty(const QString &name, const Value &value)
void defineReadonlyProperty(const QString &name, const Value &value)
static PropertyKey fromArrayIndex(uint idx)
static Bool strictEqual(const Value &x, const Value &y)
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
bool hasException() const
ExecutionEngine * engine
QML_NEARLY_ALWAYS_INLINE ReturnedValue asReturnedValue() const
bool isNumber() const
constexpr ReturnedValue asReturnedValue() const
bool isUndefined() const
static constexpr VTable::CallAsConstructor virtualCallAsConstructor
static constexpr VTable::Call virtualCall
static constexpr Value fromInt32(int i)
Definition qv4value_p.h:187
bool isFunctionObject() const
Definition qv4value_p.h:309
Heap::String * toString(ExecutionEngine *e) const
Definition qv4value_p.h:114
bool toBoolean() const
Definition qv4value_p.h:97
unsigned int toUInt32() const
Definition qv4value_p.h:361
static constexpr Value fromBoolean(bool b)
Definition qv4value_p.h:183
static constexpr Value undefinedValue()
Definition qv4value_p.h:191
static Value fromDouble(double d)
Definition qv4value_p.h:199
uint asArrayLength(bool *ok) const
Definition qv4value.cpp:275
QML_NEARLY_ALWAYS_INLINE Object * objectValue() const
Definition qv4value_p.h:70
static constexpr Value fromReturnedValue(ReturnedValue val)
Definition qv4value_p.h:165
const T * as() const
Definition qv4value_p.h:132
double toInteger() const
Definition qv4value_p.h:391
Heap::Object * toObject(ExecutionEngine *e) const
Definition qv4value_p.h:122