248ReturnedValue TypedArrayCtor::virtualCallAsConstructor(
const FunctionObject *f,
const Value *argv,
int argc,
const Value *newTarget)
250 Scope scope(f->engine());
251 const TypedArrayCtor *that =
static_cast<
const TypedArrayCtor *>(f);
253 auto updateProto = [=](Scope &scope, Scoped<TypedArray> &a) {
254 if (newTarget->heapObject() != f->heapObject() && newTarget->isFunctionObject()) {
255 const FunctionObject *nt =
static_cast<
const FunctionObject *>(newTarget);
256 ScopedObject o(scope, nt->protoProperty());
258 a->setPrototypeOf(o);
262 if (!argc || !argv[0].isObject()) {
264 const double l = argc ? argv[0].toInteger() : 0;
265 if (scope.hasException())
266 return Encode::undefined();
267 if (l < 0 || l > std::numeric_limits<
int>::max())
268 return scope.engine->throwRangeError(QLatin1String(
"Index out of range."));
270 const double byteLength = l * operations[that->d()->type].bytesPerElement;
274 if (byteLength > std::numeric_limits<uint>::max())
275 return scope.engine->throwRangeError(QLatin1String(
"Index out of range."));
277 Scoped<ArrayBuffer> buffer(scope, scope.engine->newArrayBuffer(size_t(byteLength)));
278 if (scope.hasException())
279 return Encode::undefined();
281 Scoped<TypedArray> array(scope, TypedArray::create(scope.engine, that->d()->type));
282 array->d()->buffer.set(scope.engine, buffer->d());
283 array->d()->byteLength = byteLength;
284 array->d()->byteOffset = 0;
286 updateProto(scope, array);
287 return array.asReturnedValue();
289 Scoped<TypedArray> typedArray(scope, argc ? argv[0] : Value::undefinedValue());
292 Scoped<ArrayBuffer> buffer(scope, typedArray->d()->buffer);
293 if (!buffer || buffer->hasDetachedArrayData())
294 return scope.engine->throwTypeError();
295 uint srcElementSize = typedArray->bytesPerElement();
296 uint destElementSize = operations[that->d()->type].bytesPerElement;
297 uint byteLength = typedArray->byteLength();
298 uint destByteLength = byteLength*destElementSize/srcElementSize;
300 Scoped<ArrayBuffer> newBuffer(scope, scope.engine->newArrayBuffer(destByteLength));
301 if (scope.hasException())
302 return Encode::undefined();
304 Scoped<TypedArray> array(scope, TypedArray::create(scope.engine, that->d()->type));
305 array->d()->buffer.set(scope.engine, newBuffer->d());
306 array->d()->byteLength = destByteLength;
307 array->d()->byteOffset = 0;
309 const char *src = buffer->constArrayData() + typedArray->byteOffset();
310 char *dest = newBuffer->arrayData();
313 if (srcElementSize == destElementSize) {
314 memcpy(dest, src, byteLength);
317 uint l = typedArray->length();
318 TypedArrayOperations::Read read = typedArray->d()->type->read;
319 TypedArrayOperations::Write write =array->d()->type->write;
320 for (uint i = 0; i < l; ++i) {
322 val.setRawValue(read(src + i*srcElementSize));
323 write(dest + i*destElementSize, val);
327 updateProto(scope, array);
328 return array.asReturnedValue();
330 Scoped<ArrayBuffer> buffer(scope, argc ? argv[0] : Value::undefinedValue());
334 double dbyteOffset = argc > 1 ? argv[1].toInteger() : 0;
336 if (buffer->hasDetachedArrayData())
337 return scope.engine->throwTypeError();
339 uint byteOffset = (uint)dbyteOffset;
340 uint elementSize = operations[that->d()->type].bytesPerElement;
341 if (dbyteOffset < 0 || (byteOffset % elementSize) || dbyteOffset > buffer->arrayDataLength())
342 return scope.engine->throwRangeError(QStringLiteral(
"new TypedArray: invalid byteOffset"));
345 if (argc < 3 || argv[2].isUndefined()) {
346 byteLength = buffer->arrayDataLength() - byteOffset;
347 if (buffer->arrayDataLength() < byteOffset || byteLength % elementSize)
348 return scope.engine->throwRangeError(QStringLiteral(
"new TypedArray: invalid length"));
350 double l = qBound(0., argv[2].toInteger(), (
double)UINT_MAX);
351 if (scope.hasException())
352 return Encode::undefined();
353 if (buffer->hasDetachedArrayData())
354 return scope.engine->throwTypeError();
356 if (buffer->arrayDataLength() - byteOffset < l)
357 return scope.engine->throwRangeError(QStringLiteral(
"new TypedArray: invalid length"));
358 byteLength = (uint)l;
361 Scoped<TypedArray> array(scope, TypedArray::create(scope.engine, that->d()->type));
362 array->d()->buffer.set(scope.engine, buffer->d());
363 array->d()->byteLength = byteLength;
364 array->d()->byteOffset = byteOffset;
366 updateProto(scope, array);
367 return array.asReturnedValue();
372 ScopedObject o(scope, argc ? argv[0] : Value::undefinedValue());
373 uint l = (uint) qBound(0., ScopedValue(scope, o->get(scope.engine->id_length()))->toInteger(), (
double)UINT_MAX);
374 if (scope.hasException())
375 return scope.engine->throwTypeError();
377 uint elementSize = operations[that->d()->type].bytesPerElement;
379 if (qMulOverflow(size_t(l), size_t(elementSize), &bufferSize))
380 return scope.engine->throwRangeError(QLatin1String(
"new TypedArray: invalid length"));
381 Scoped<ArrayBuffer> newBuffer(scope, scope.engine->newArrayBuffer(bufferSize));
382 if (scope.hasException())
383 return Encode::undefined();
385 Scoped<TypedArray> array(scope, TypedArray::create(scope.engine, that->d()->type));
386 array->d()->buffer.set(scope.engine, newBuffer->d());
387 array->d()->byteLength = l * elementSize;
388 array->d()->byteOffset = 0;
391 char *b = newBuffer->arrayData();
392 ScopedValue val(scope);
395 val = val->convertedToNumber();
396 if (scope.hasException())
397 return Encode::undefined();
398 array->d()->type->write(b, val);
399 if (scope.hasException())
400 return Encode::undefined();
405 updateProto(scope, array);
406 return array.asReturnedValue();
480bool TypedArray::virtualPut(Managed *m, PropertyKey id,
const Value &value, Value *receiver)
482 const bool isArrayIndex = id.isArrayIndex();
483 if (!isArrayIndex && !id.isCanonicalNumericIndexString())
484 return Object::virtualPut(m, id, value, receiver);
486 ExecutionEngine *v4 =
static_cast<Object *>(m)->engine();
487 if (v4->hasException)
491 Scoped<TypedArray> a(scope,
static_cast<TypedArray *>(m));
492 if (a->hasDetachedArrayData())
493 return scope.engine->throwTypeError();
498 const uint index = id.asArrayIndex();
499 if (index >= a->length())
502 uint bytesPerElement = a->bytesPerElement();
503 uint byteOffset = a->byteOffset() + index * bytesPerElement;
504 Q_ASSERT(byteOffset + bytesPerElement <= a->arrayDataLength());
506 Value v = Value::fromReturnedValue(value.convertedToNumber());
507 if (scope.hasException() || a->hasDetachedArrayData())
508 return scope.engine->throwTypeError();
509 a->d()->type->write(a->arrayData() + byteOffset, v);
513bool TypedArray::virtualDefineOwnProperty(Managed *m, PropertyKey id,
const Property *p, PropertyAttributes attrs)
515 if (!id.isArrayIndex()) {
516 return !id.isCanonicalNumericIndexString()
517 && Object::virtualDefineOwnProperty(m, id, p, attrs);
520 const uint index = id.asArrayIndex();
521 TypedArray *a =
static_cast<TypedArray *>(m);
522 if (index >= a->length() || attrs.isAccessor())
525 if (attrs.hasConfigurable() && attrs.isConfigurable())
527 if (attrs.hasEnumerable() && !attrs.isEnumerable())
529 if (attrs.hasWritable() && !attrs.isWritable())
531 if (!p->value.isEmpty()) {
532 ExecutionEngine *engine = a->engine();
534 Value v = Value::fromReturnedValue(p->value.convertedToNumber());
535 if (engine->hasException || a->hasDetachedArrayData())
536 return engine->throwTypeError();
537 uint bytesPerElement = a->bytesPerElement();
538 uint byteOffset = a->byteOffset() + index * bytesPerElement;
539 Q_ASSERT(byteOffset + bytesPerElement <= a->arrayDataLength());
540 a->d()->type->write(a->arrayData() + byteOffset, v);
643ReturnedValue IntrinsicTypedArrayPrototype::method_copyWithin(
const FunctionObject *f,
const Value *thisObject,
const Value *argv,
int argc)
646 Scoped<TypedArray> instance(scope, thisObject);
647 if (!instance || instance->hasDetachedArrayData())
648 return scope.engine->throwTypeError();
651 return instance->asReturnedValue();
653 const double len = instance->length();
654 Q_ASSERT(std::isfinite(len));
656 const double target = argv[0].toInteger();
658 const double start = (argc > 1)
659 ? argv[1].toInteger()
662 const double end = (argc > 2 && !argv[2].isUndefined())
663 ? argv[2].toInteger()
666 const double fin = end < 0
667 ? std::max(len + end, 0.0)
668 : std::min(end, len);
670 const qsizetype from = start < 0
671 ? std::max(len + start, 0.0)
672 : std::min(start, len);
674 const qsizetype to = target < 0
675 ? std::max(len + target, 0.0)
676 : std::min(target, len);
678 const qsizetype count = std::min(fin - from, len - to);
681 return instance->asReturnedValue();
684 int elementSize = instance->bytesPerElement();
685 char *data = instance->arrayData() + instance->byteOffset();
686 memmove(data + to * elementSize, data + from * elementSize, count * elementSize);
689 return instance->asReturnedValue();
704ReturnedValue IntrinsicTypedArrayPrototype::method_every(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
707 Scoped<TypedArray> v(scope, thisObject);
708 if (!v || v->hasDetachedArrayData())
709 return scope.engine->throwTypeError();
711 uint len = v->length();
713 if (!argc || !argv->isFunctionObject())
715 const FunctionObject *callback =
static_cast<
const FunctionObject *>(argv);
717 ScopedValue that(scope, argc > 1 ? argv[1] : Value::undefinedValue());
718 ScopedValue r(scope);
719 Value *arguments = scope.constructUndefined(3);
721 const char *data = v->constArrayData();
722 uint bytesPerElement = v->bytesPerElement();
723 uint byteOffset = v->byteOffset();
726 for (uint k = 0; ok && k < len; ++k) {
727 if (v->hasDetachedArrayData())
728 return scope.engine->throwTypeError();
730 arguments[0] = v->d()->type->read(data + byteOffset + k * bytesPerElement);
732 arguments[1] = Value::fromDouble(k);
734 r = callback->call(that, arguments, 3);
741ReturnedValue IntrinsicTypedArrayPrototype::method_fill(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
744 Scoped<TypedArray> v(scope, thisObject);
745 if (!v || v->hasDetachedArrayData())
746 return scope.engine->throwTypeError();
748 uint len = v->length();
750 double relativeStart = argc > 1 ? argv[1].toInteger() : 0.;
751 double relativeEnd = len;
752 if (argc > 2 && !argv[2].isUndefined())
753 relativeEnd = argv[2].toInteger();
758 if (relativeStart < 0) {
759 k =
static_cast<uint>(std::max(len+relativeStart, 0.));
761 k =
static_cast<uint>(std::min(relativeStart, dlen));
764 if (relativeEnd < 0) {
765 fin =
static_cast<uint>(std::max(len + relativeEnd, 0.));
767 fin =
static_cast<uint>(std::min(relativeEnd, dlen));
770 if (scope.hasException() || v->hasDetachedArrayData())
771 return scope.engine->throwTypeError();
773 char *data = v->arrayData();
774 uint bytesPerElement = v->bytesPerElement();
775 uint byteOffset = v->byteOffset();
779 value.setDouble(std::numeric_limits<
double>::quiet_NaN());
780 else if (argv[0].isNumber())
783 value.setDouble(argv[0].toNumber());
786 v->d()->type->write(data + byteOffset + k * bytesPerElement, value);
790 return v.asReturnedValue();
811ReturnedValue IntrinsicTypedArrayPrototype::method_filter(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
814 Scoped<TypedArray> instance(scope, thisObject);
815 if (!instance || instance->hasDetachedArrayData())
816 return scope.engine->throwTypeError();
818 uint len = instance->length();
820 if (!argc || !argv->isFunctionObject())
822 const FunctionObject *callback =
static_cast<
const FunctionObject *>(argv);
824 ScopedValue selected(scope);
825 ScopedValue that(scope, argc > 1 ? argv[1] : Value::undefinedValue());
826 Value *arguments = scope.constructUndefined(3);
827 Value *list = arguments;
830 for (uint k = 0; k < len; ++k) {
831 if (instance->hasDetachedArrayData())
832 return scope.engine->throwTypeError();
834 arguments[0] = instance->get(k, &exists);
838 arguments[1] = Value::fromDouble(k);
839 arguments[2] = instance;
840 selected = callback->call(that, arguments, 3);
842 if (selected->toBoolean()) {
844 scope.constructUndefined(1);
849 TypedArray *a = typedArraySpeciesCreate(scope, instance, to);
851 return Encode::undefined();
853 for (uint i = 0; i < to; ++i)
856 return a->asReturnedValue();
1048ReturnedValue IntrinsicTypedArrayPrototype::method_join(
1049 const FunctionObject *functionObject,
const Value *thisObject,
const Value *argv,
int argc)
1051 Scope scope(functionObject);
1052 Scoped<TypedArray> typedArray(scope, thisObject);
1053 if (!typedArray || typedArray->hasDetachedArrayData())
1054 return scope.engine->throwTypeError();
1058 ScopedValue argument(scope, argc ? argv[0] : Value::undefinedValue());
1059 const QString separator = argument->isUndefined()
1060 ? QStringLiteral(
",")
1061 : argument->toQString();
1063 const quint32 length = typedArray->length();
1065 return Encode(scope.engine->newString());
1069 ScopedString name(scope, scope.engine->newString(QStringLiteral(
"0")));
1070 ScopedValue value(scope, typedArray->get(name));
1071 if (!value->isNullOrUndefined())
1072 result = value->toQString();
1074 for (quint32 i = 1; i < length; ++i) {
1075 result += separator;
1077 name = Value::fromDouble(i).toString(scope.engine);
1078 value = typedArray->get(name);
1081 if (!value->isNullOrUndefined())
1082 result += value->toQString();
1085 return Encode(scope.engine->newString(result));
1144ReturnedValue IntrinsicTypedArrayPrototype::method_map(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
1147 Scoped<TypedArray> instance(scope, thisObject);
1148 if (!instance || instance->hasDetachedArrayData())
1149 return scope.engine->throwTypeError();
1151 uint len = instance->length();
1153 if (!argc || !argv->isFunctionObject())
1155 const FunctionObject *callback =
static_cast<
const FunctionObject *>(argv);
1157 TypedArray *a = typedArraySpeciesCreate(scope, instance, len);
1159 return Encode::undefined();
1161 ScopedValue v(scope);
1162 ScopedValue mapped(scope);
1163 ScopedValue that(scope, argc > 1 ? argv[1] : Value::undefinedValue());
1164 Value *arguments = scope.constructUndefined(3);
1166 for (uint k = 0; k < len; ++k) {
1167 if (instance->hasDetachedArrayData())
1168 return scope.engine->throwTypeError();
1169 arguments[0] = instance->get(k);
1171 arguments[1] = Value::fromDouble(k);
1172 arguments[2] = instance;
1173 mapped = callback->call(that, arguments, 3);
1177 return a->asReturnedValue();
1314ReturnedValue IntrinsicTypedArrayPrototype::method_some(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
1317 Scoped<TypedArray> instance(scope, thisObject);
1318 if (!instance || instance->hasDetachedArrayData())
1319 return scope.engine->throwTypeError();
1321 uint len = instance->length();
1323 if (!argc || !argv->isFunctionObject())
1325 const FunctionObject *callback =
static_cast<
const FunctionObject *>(argv);
1327 ScopedValue that(scope, argc > 1 ? argv[1] : Value::undefinedValue());
1328 ScopedValue result(scope);
1329 Value *arguments = scope.constructUndefined(3);
1331 for (uint k = 0; k < len; ++k) {
1332 if (instance->hasDetachedArrayData())
1333 return scope.engine->throwTypeError();
1335 arguments[0] = instance->get(k, &exists);
1339 arguments[1] = Value::fromDouble(k);
1340 arguments[2] = instance;
1341 result = callback->call(that, arguments, 3);
1343 if (result->toBoolean())
1344 return Encode(
true);
1346 return Encode(
false);
1362ReturnedValue IntrinsicTypedArrayPrototype::method_set(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
1365 Scoped<TypedArray> a(scope, *thisObject);
1367 return scope.engine->throwTypeError();
1368 Scoped<ArrayBuffer> buffer(scope, a->d()->buffer);
1370 double doffset = argc >= 2 ? argv[1].toInteger() : 0;
1371 if (scope.hasException())
1373 if (!buffer || buffer->hasDetachedArrayData())
1374 return scope.engine->throwTypeError();
1376 if (doffset < 0 || doffset >= UINT_MAX)
1377 RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral(
"TypedArray.set: out of range")));
1378 uint offset = (uint)doffset;
1379 uint elementSize = a->bytesPerElement();
1381 Scoped<TypedArray> srcTypedArray(scope, argv[0]);
1382 if (!srcTypedArray) {
1384 ScopedObject o(scope, argv[0].toObject(scope.engine));
1385 if (scope.hasException() || !o)
1386 return scope.engine->throwTypeError();
1388 double len = ScopedValue(scope, o->get(scope.engine->id_length()))->toNumber();
1390 if (scope.hasException() || l != len)
1391 return scope.engine->throwTypeError();
1393 const uint aLength = a->length();
1394 if (offset > aLength || l > aLength - offset)
1395 RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral(
"TypedArray.set: out of range")));
1398 if (buffer->hasDetachedArrayData())
1399 return scope.engine->throwTypeError();
1400 char *b = buffer->arrayData() + a->byteOffset() + offset*elementSize;
1401 ScopedValue val(scope);
1404 if (scope.hasException())
1405 return Encode::undefined();
1406 val = val->convertedToNumber();
1407 if (scope.hasException() || buffer->hasDetachedArrayData())
1408 return scope.engine->throwTypeError();
1409 a->d()->type->write(b, val);
1410 if (scope.hasException())
1419 Scoped<ArrayBuffer> srcBuffer(scope, srcTypedArray->d()->buffer);
1420 if (!srcBuffer || srcBuffer->hasDetachedArrayData())
1421 return scope.engine->throwTypeError();
1423 uint l = srcTypedArray->length();
1425 const uint aLength = a->length();
1426 if (offset > aLength || l > aLength - offset)
1427 RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral(
"TypedArray.set: out of range")));
1429 char *dest = buffer->arrayData() + a->byteOffset() + offset*elementSize;
1430 const char *src = srcBuffer->d()->constArrayData() + srcTypedArray->byteOffset();
1431 if (srcTypedArray->d()->type == a->d()->type) {
1433 memmove(dest, src, srcTypedArray->byteLength());
1437 char *srcCopy =
nullptr;
1438 if (buffer->d() == srcBuffer->d()) {
1440 srcCopy =
new char[srcTypedArray->byteLength()];
1441 memcpy(srcCopy, src, srcTypedArray->byteLength());
1446 uint srcElementSize = srcTypedArray->bytesPerElement();
1447 TypedArrayOperations::Read read = srcTypedArray->d()->type->read;
1448 TypedArrayOperations::Write write = a->d()->type->write;
1449 for (uint i = 0; i < l; ++i) {
1451 val.setRawValue(read(src + i*srcElementSize));
1452 write(dest + i*elementSize, val);
1461ReturnedValue IntrinsicTypedArrayPrototype::method_slice(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
1464 Scoped<TypedArray> instance(scope, thisObject);
1465 if (!instance || instance->hasDetachedArrayData())
1466 return scope.engine->throwTypeError();
1468 uint len = instance->length();
1470 double s = (argc ? argv[0] : Value::undefinedValue()).toInteger();
1473 start = (uint)qMax(len + s, 0.);
1479 if (argc > 1 && !argv[1].isUndefined()) {
1480 double e = argv[1].toInteger();
1482 end = (uint)qMax(len + e, 0.);
1488 uint count = start > end ? 0 : end - start;
1490 TypedArray *a = typedArraySpeciesCreate(scope, instance, count);
1492 return Encode::undefined();
1494 ScopedValue v(scope);
1496 for (uint i = start; i < end; ++i) {
1497 if (instance->hasDetachedArrayData())
1498 return scope.engine->throwTypeError();
1499 v = instance->get(i);
1500 if (a->hasDetachedArrayData())
1501 return scope.engine->throwTypeError();
1505 return a->asReturnedValue();
1508ReturnedValue IntrinsicTypedArrayPrototype::method_subarray(
const FunctionObject *builtin,
const Value *thisObject,
const Value *argv,
int argc)
1510 Scope scope(builtin);
1511 Scoped<TypedArray> a(scope, *thisObject);
1514 return scope.engine->throwTypeError();
1516 Scoped<ArrayBuffer> buffer(scope, a->d()->buffer);
1519 int len = a->length();
1520 double b = argc > 0 ? argv[0].toInteger() : 0;
1523 uint begin = (uint)qBound(0., b, (
double)len);
1525 double e = argc < 2 || argv[1].isUndefined() ? len : argv[1].toInteger();
1528 uint end = (uint)qBound(0., e, (
double)len);
1532 if (scope.hasException())
1535 int newLen = end - begin;
1537 ScopedFunctionObject constructor(scope, a->speciesConstructor(scope, scope.engine->typedArrayCtors + a->d()->arrayType));
1539 return scope.engine->throwTypeError();
1541 Value *arguments = scope.constructUndefined(3);
1542 arguments[0] = buffer;
1543 arguments[1] = Encode(a->byteOffset() + begin * a->bytesPerElement());
1544 arguments[2] = Encode(newLen);
1545 a = constructor->callAsConstructor(arguments, 3);
1546 if (!a || a->hasDetachedArrayData())
1547 return scope.engine->throwTypeError();
1548 return a->asReturnedValue();
1551ReturnedValue IntrinsicTypedArrayPrototype::method_toLocaleString(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
1554 Scoped<TypedArray> instance(scope, thisObject);
1555 if (!instance || instance->hasDetachedArrayData())
1556 return scope.engine->throwTypeError();
1558 uint len = instance->length();
1559 const QString separator = QStringLiteral(
",");
1563 ScopedValue v(scope);
1564 ScopedString s(scope);
1566 ScopedPropertyKey tolocaleString(scope, scope.engine->id_toLocaleString()->toPropertyKey());
1567 Q_ASSERT(!scope.engine->hasException);
1569 for (uint k = 0; k < len; ++k) {
1570 if (instance->hasDetachedArrayData())
1571 return scope.engine->throwTypeError();
1575 v = instance->get(k);
1576 Q_ASSERT(!v->isNullOrUndefined());
1578 ScopedObject valueAsObject(scope, v->toObject(scope.engine));
1579 Q_ASSERT(valueAsObject);
1581 ScopedFunctionObject function(scope, valueAsObject->get(tolocaleString));
1583 return scope.engine->throwTypeError();
1585 v = function->call(valueAsObject,
nullptr, 0);
1586 if (scope.hasException())
1587 return Encode::undefined();
1589 s = v->toString(scope.engine);
1590 if (scope.hasException())
1591 return Encode::undefined();
1593 R += s->toQString();
1595 return scope.engine->newString(R)->asReturnedValue();
1643ReturnedValue IntrinsicTypedArrayCtor::method_from(
const FunctionObject *f,
const Value *thisObject,
const Value *argv,
int argc)
1646 ScopedObject itemsObject(scope, argv[0]);
1647 bool usingIterator =
false;
1649 ScopedFunctionObject mapfn(scope, Value::undefinedValue());
1650 Value *mapArguments =
nullptr;
1652 mapfn = ScopedFunctionObject(scope, argv[1]);
1654 return scope.engine->throwTypeError(QString::fromLatin1(
"%1 is not a function").arg(argv[1].toQStringNoThrow()));
1655 mapArguments = scope.constructUndefined(2);
1661 ScopedValue it(scope, itemsObject->get(scope.engine->symbol_iterator()));
1663 if (!it->isNullOrUndefined()) {
1664 ScopedFunctionObject itfunc(scope, it);
1666 return scope.engine->throwTypeError();
1667 usingIterator =
true;
1671 ScopedValue thisArg(scope);
1675 const FunctionObject *C = thisObject->as<FunctionObject>();
1677 if (usingIterator) {
1681 qint64 iterableLength = 0;
1682 Value *nextValue = scope.constructUndefined(1);
1683 ScopedValue done(scope);
1685 ScopedObject lengthIterator(scope, Runtime::GetIterator::call(scope.engine, itemsObject,
true));
1687 if (!lengthIterator) {
1688 return scope.engine->throwTypeError();
1693 if (iterableLength > (
static_cast<qint64>(1) << 53) - 1) {
1694 ScopedValue error(scope, scope.engine->throwTypeError());
1695 return Runtime::IteratorClose::call(scope.engine, lengthIterator);
1698 done = Value::fromReturnedValue(Runtime::IteratorNext::call(scope.engine, lengthIterator, nextValue));
1699 if (scope.hasException())
1700 return Runtime::IteratorClose::call(scope.engine, lengthIterator);
1701 if (done->toBoolean()) {
1709 if (!C || !C->isConstructor())
1710 return scope.engine->throwTypeError();
1712 ScopedObject iterator(scope, Runtime::GetIterator::call(scope.engine, itemsObject,
true));
1715 return scope.engine->throwTypeError();
1718 ScopedObject a(scope, Value::undefinedValue());
1719 ScopedValue ctorArgument(scope, Value::fromReturnedValue(QV4::Encode(
int(iterableLength))));
1720 a = C->callAsConstructor(ctorArgument, 1);
1724 if (!::validateTypedArray(a) || (a->getLength() < iterableLength))
1725 return scope.engine->throwTypeError();
1729 ScopedValue mappedValue(scope, Value::undefinedValue());
1730 for (qint64 k = 0; k < iterableLength; ++k) {
1731 done = Value::fromReturnedValue(Runtime::IteratorNext::call(scope.engine, iterator, nextValue));
1732 if (scope.hasException())
1733 return Runtime::IteratorClose::call(scope.engine, iterator);
1736 mapArguments[0] = *nextValue;
1737 mapArguments[1] = Value::fromDouble(k);
1738 mappedValue = mapfn->call(thisArg, mapArguments, 2);
1739 if (scope.hasException())
1740 return Runtime::IteratorClose::call(scope.engine, iterator);
1742 mappedValue = *nextValue;
1745 a->put(k, mappedValue);
1746 if (scope.hasException())
1747 return Runtime::IteratorClose::call(scope.engine, iterator);
1749 return a.asReturnedValue();
1752 ScopedObject arrayLike(scope, argv[0].toObject(scope.engine));
1754 return scope.engine->throwTypeError(QString::fromLatin1(
"Cannot convert %1 to object").arg(argv[0].toQStringNoThrow()));
1756 int len = arrayLike->getLength();
1760 if (!C || !C->isConstructor())
1761 return scope.engine->throwTypeError();
1763 ScopedObject a(scope, Value::undefinedValue());
1764 ScopedValue ctorArgument(scope, Value::fromReturnedValue(QV4::Encode(len)));
1765 a = C->callAsConstructor(ctorArgument, 1);
1769 if (!::validateTypedArray(a) || (a->getLength() < len))
1770 return scope.engine->throwTypeError();
1772 ScopedValue mappedValue(scope, Value::undefinedValue());
1773 ScopedValue kValue(scope);
1774 for (
int k = 0; k < len; ++k) {
1775 kValue = arrayLike->get(k);
1779 mapArguments[0] = kValue;
1780 mapArguments[1] = Value::fromDouble(k);
1781 mappedValue = mapfn->call(thisArg, mapArguments, 2);
1784 mappedValue = kValue;
1787 a->put(k, mappedValue);
1790 return a.asReturnedValue();
1794void IntrinsicTypedArrayPrototype::init(ExecutionEngine *engine, IntrinsicTypedArrayCtor *ctor)
1796 Scope scope(engine);
1797 ctor->defineReadonlyProperty(engine->id_prototype(), *
this);
1798 ctor->defineReadonlyConfigurableProperty(engine->id_length(), Value::fromInt32(0));
1799 ScopedString s(scope, engine->newString(QStringLiteral(
"TypedArray")));
1800 ctor->defineReadonlyConfigurableProperty(engine->id_name(), s);
1801 s = scope.engine->newString(QStringLiteral(
"of"));
1802 ctor->defineDefaultProperty(s, IntrinsicTypedArrayCtor::method_of);
1803 s = scope.engine->newString(QStringLiteral(
"from"));
1804 ctor->defineDefaultProperty(s, IntrinsicTypedArrayCtor::method_from, 1);
1805 ctor->addSymbolSpecies();
1807 defineAccessorProperty(QStringLiteral(
"buffer"), method_get_buffer,
nullptr);
1808 defineAccessorProperty(QStringLiteral(
"byteLength"), method_get_byteLength,
nullptr);
1809 defineAccessorProperty(QStringLiteral(
"byteOffset"), method_get_byteOffset,
nullptr);
1810 defineAccessorProperty(QStringLiteral(
"length"), method_get_length,
nullptr);
1812 defineDefaultProperty(QStringLiteral(
"copyWithin"), method_copyWithin, 2);
1813 defineDefaultProperty(QStringLiteral(
"entries"), method_entries, 0);
1814 defineDefaultProperty(QStringLiteral(
"every"), method_every, 1);
1815 defineDefaultProperty(QStringLiteral(
"fill"), method_fill, 1);
1816 defineDefaultProperty(QStringLiteral(
"filter"), method_filter, 1);
1817 defineDefaultProperty(QStringLiteral(
"find"), method_find, 1);
1818 defineDefaultProperty(QStringLiteral(
"findIndex"), method_findIndex, 1);
1819 defineDefaultProperty(QStringLiteral(
"forEach"), method_forEach, 1);
1820 defineDefaultProperty(QStringLiteral(
"includes"), method_includes, 1);
1821 defineDefaultProperty(QStringLiteral(
"indexOf"), method_indexOf, 1);
1822 defineDefaultProperty(QStringLiteral(
"join"), method_join, 1);
1823 defineDefaultProperty(QStringLiteral(
"keys"), method_keys, 0);
1824 defineDefaultProperty(QStringLiteral(
"lastIndexOf"), method_lastIndexOf, 1);
1825 defineDefaultProperty(QStringLiteral(
"map"), method_map, 1);
1826 defineDefaultProperty(QStringLiteral(
"reduce"), method_reduce, 1);
1827 defineDefaultProperty(QStringLiteral(
"reduceRight"), method_reduceRight, 1);
1828 defineDefaultProperty(QStringLiteral(
"reverse"), method_reverse, 0);
1829 defineDefaultProperty(QStringLiteral(
"some"), method_some, 1);
1830 defineDefaultProperty(QStringLiteral(
"set"), method_set, 1);
1831 defineDefaultProperty(QStringLiteral(
"slice"), method_slice, 2);
1832 defineDefaultProperty(QStringLiteral(
"subarray"), method_subarray, 2);
1833 defineDefaultProperty(engine->id_toLocaleString(), method_toLocaleString, 0);
1834 ScopedObject f(scope, engine->arrayPrototype()->get(engine->id_toString()));
1835 defineDefaultProperty(engine->id_toString(), f);
1837 ScopedString valuesString(scope, engine->newIdentifier(QStringLiteral(
"values")));
1838 ScopedObject values(scope, FunctionObject::createBuiltinFunction(engine, valuesString, method_values, 0));
1839 defineDefaultProperty(QStringLiteral(
"values"), values);
1840 defineDefaultProperty(engine->symbol_iterator(), values);
1842 defineAccessorProperty(engine->symbol_toStringTag(), method_get_toStringTag,
nullptr);