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();
1049ReturnedValue IntrinsicTypedArrayPrototype::method_join(
1050 const FunctionObject *functionObject,
const Value *thisObject,
const Value *argv,
int argc)
1052 Scope scope(functionObject);
1053 Scoped<TypedArray> typedArray(scope, thisObject);
1054 if (!typedArray || typedArray->hasDetachedArrayData())
1055 return scope.engine->throwTypeError();
1059 ScopedValue argument(scope, argc ? argv[0] : Value::undefinedValue());
1060 const QString separator = argument->isUndefined()
1061 ? QStringLiteral(
",")
1062 : argument->toQString();
1064 const quint32 length = typedArray->length();
1066 return Encode(scope.engine->newString());
1070 ScopedString name(scope, scope.engine->newString(QStringLiteral(
"0")));
1071 ScopedValue value(scope, typedArray->get(name));
1072 if (!value->isNullOrUndefined())
1073 result = value->toQString();
1075 for (quint32 i = 1; i < length; ++i) {
1076 result += separator;
1078 name = Value::fromDouble(i).toString(scope.engine);
1079 value = typedArray->get(name);
1082 if (!value->isNullOrUndefined())
1083 result += value->toQString();
1086 return Encode(scope.engine->newString(result));
1145ReturnedValue IntrinsicTypedArrayPrototype::method_map(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
1148 Scoped<TypedArray> instance(scope, thisObject);
1149 if (!instance || instance->hasDetachedArrayData())
1150 return scope.engine->throwTypeError();
1152 uint len = instance->length();
1154 if (!argc || !argv->isFunctionObject())
1156 const FunctionObject *callback =
static_cast<
const FunctionObject *>(argv);
1158 TypedArray *a = typedArraySpeciesCreate(scope, instance, len);
1160 return Encode::undefined();
1162 ScopedValue v(scope);
1163 ScopedValue mapped(scope);
1164 ScopedValue that(scope, argc > 1 ? argv[1] : Value::undefinedValue());
1165 Value *arguments = scope.constructUndefined(3);
1167 for (uint k = 0; k < len; ++k) {
1168 if (instance->hasDetachedArrayData())
1169 return scope.engine->throwTypeError();
1170 arguments[0] = instance->get(k);
1172 arguments[1] = Value::fromDouble(k);
1173 arguments[2] = instance;
1174 mapped = callback->call(that, arguments, 3);
1178 return a->asReturnedValue();
1315ReturnedValue IntrinsicTypedArrayPrototype::method_some(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
1318 Scoped<TypedArray> instance(scope, thisObject);
1319 if (!instance || instance->hasDetachedArrayData())
1320 return scope.engine->throwTypeError();
1322 uint len = instance->length();
1324 if (!argc || !argv->isFunctionObject())
1326 const FunctionObject *callback =
static_cast<
const FunctionObject *>(argv);
1328 ScopedValue that(scope, argc > 1 ? argv[1] : Value::undefinedValue());
1329 ScopedValue result(scope);
1330 Value *arguments = scope.constructUndefined(3);
1332 for (uint k = 0; k < len; ++k) {
1333 if (instance->hasDetachedArrayData())
1334 return scope.engine->throwTypeError();
1336 arguments[0] = instance->get(k, &exists);
1340 arguments[1] = Value::fromDouble(k);
1341 arguments[2] = instance;
1342 result = callback->call(that, arguments, 3);
1344 if (result->toBoolean())
1345 return Encode(
true);
1347 return Encode(
false);
1363ReturnedValue IntrinsicTypedArrayPrototype::method_set(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
1366 Scoped<TypedArray> a(scope, *thisObject);
1368 return scope.engine->throwTypeError();
1369 Scoped<ArrayBuffer> buffer(scope, a->d()->buffer);
1371 double doffset = argc >= 2 ? argv[1].toInteger() : 0;
1372 if (scope.hasException())
1374 if (!buffer || buffer->hasDetachedArrayData())
1375 return scope.engine->throwTypeError();
1377 if (doffset < 0 || doffset >= UINT_MAX)
1378 RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral(
"TypedArray.set: out of range")));
1379 uint offset = (uint)doffset;
1380 uint elementSize = a->bytesPerElement();
1382 Scoped<TypedArray> srcTypedArray(scope, argv[0]);
1383 if (!srcTypedArray) {
1385 ScopedObject o(scope, argv[0].toObject(scope.engine));
1386 if (scope.hasException() || !o)
1387 return scope.engine->throwTypeError();
1389 double len = ScopedValue(scope, o->get(scope.engine->id_length()))->toNumber();
1391 if (scope.hasException() || l != len)
1392 return scope.engine->throwTypeError();
1394 const uint aLength = a->length();
1395 if (offset > aLength || l > aLength - offset)
1396 RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral(
"TypedArray.set: out of range")));
1399 if (buffer->hasDetachedArrayData())
1400 return scope.engine->throwTypeError();
1401 char *b = buffer->arrayData() + a->byteOffset() + offset*elementSize;
1402 ScopedValue val(scope);
1405 if (scope.hasException())
1406 return Encode::undefined();
1407 val = val->convertedToNumber();
1408 if (scope.hasException() || buffer->hasDetachedArrayData())
1409 return scope.engine->throwTypeError();
1410 a->d()->type->write(b, val);
1411 if (scope.hasException())
1420 Scoped<ArrayBuffer> srcBuffer(scope, srcTypedArray->d()->buffer);
1421 if (!srcBuffer || srcBuffer->hasDetachedArrayData())
1422 return scope.engine->throwTypeError();
1424 uint l = srcTypedArray->length();
1426 const uint aLength = a->length();
1427 if (offset > aLength || l > aLength - offset)
1428 RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral(
"TypedArray.set: out of range")));
1430 char *dest = buffer->arrayData() + a->byteOffset() + offset*elementSize;
1431 const char *src = srcBuffer->d()->constArrayData() + srcTypedArray->byteOffset();
1432 if (srcTypedArray->d()->type == a->d()->type) {
1434 memmove(dest, src, srcTypedArray->byteLength());
1438 char *srcCopy =
nullptr;
1439 if (buffer->d() == srcBuffer->d()) {
1441 srcCopy =
new char[srcTypedArray->byteLength()];
1442 memcpy(srcCopy, src, srcTypedArray->byteLength());
1447 uint srcElementSize = srcTypedArray->bytesPerElement();
1448 TypedArrayOperations::Read read = srcTypedArray->d()->type->read;
1449 TypedArrayOperations::Write write = a->d()->type->write;
1450 for (uint i = 0; i < l; ++i) {
1452 val.setRawValue(read(src + i*srcElementSize));
1453 write(dest + i*elementSize, val);
1462ReturnedValue IntrinsicTypedArrayPrototype::method_slice(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
1465 Scoped<TypedArray> instance(scope, thisObject);
1466 if (!instance || instance->hasDetachedArrayData())
1467 return scope.engine->throwTypeError();
1469 uint len = instance->length();
1471 double s = (argc ? argv[0] : Value::undefinedValue()).toInteger();
1474 start = (uint)qMax(len + s, 0.);
1480 if (argc > 1 && !argv[1].isUndefined()) {
1481 double e = argv[1].toInteger();
1483 end = (uint)qMax(len + e, 0.);
1489 uint count = start > end ? 0 : end - start;
1491 TypedArray *a = typedArraySpeciesCreate(scope, instance, count);
1493 return Encode::undefined();
1495 ScopedValue v(scope);
1497 for (uint i = start; i < end; ++i) {
1498 if (instance->hasDetachedArrayData())
1499 return scope.engine->throwTypeError();
1500 v = instance->get(i);
1501 if (a->hasDetachedArrayData())
1502 return scope.engine->throwTypeError();
1506 return a->asReturnedValue();
1509ReturnedValue IntrinsicTypedArrayPrototype::method_subarray(
const FunctionObject *builtin,
const Value *thisObject,
const Value *argv,
int argc)
1511 Scope scope(builtin);
1512 Scoped<TypedArray> a(scope, *thisObject);
1515 return scope.engine->throwTypeError();
1517 Scoped<ArrayBuffer> buffer(scope, a->d()->buffer);
1520 int len = a->length();
1521 double b = argc > 0 ? argv[0].toInteger() : 0;
1524 uint begin = (uint)qBound(0., b, (
double)len);
1526 double e = argc < 2 || argv[1].isUndefined() ? len : argv[1].toInteger();
1529 uint end = (uint)qBound(0., e, (
double)len);
1533 if (scope.hasException())
1536 int newLen = end - begin;
1538 ScopedFunctionObject constructor(scope, a->speciesConstructor(scope, scope.engine->typedArrayCtors + a->d()->arrayType));
1540 return scope.engine->throwTypeError();
1542 Value *arguments = scope.constructUndefined(3);
1543 arguments[0] = buffer;
1544 arguments[1] = Encode(a->byteOffset() + begin * a->bytesPerElement());
1545 arguments[2] = Encode(newLen);
1546 a = constructor->callAsConstructor(arguments, 3);
1547 if (!a || a->hasDetachedArrayData())
1548 return scope.engine->throwTypeError();
1549 return a->asReturnedValue();
1552ReturnedValue IntrinsicTypedArrayPrototype::method_toLocaleString(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
1555 Scoped<TypedArray> instance(scope, thisObject);
1556 if (!instance || instance->hasDetachedArrayData())
1557 return scope.engine->throwTypeError();
1559 uint len = instance->length();
1560 const QString separator = QStringLiteral(
",");
1564 ScopedValue v(scope);
1565 ScopedString s(scope);
1567 ScopedPropertyKey tolocaleString(scope, scope.engine->id_toLocaleString()->toPropertyKey());
1568 Q_ASSERT(!scope.engine->hasException);
1570 ScopedObject valueAsObject(scope);
1571 ScopedFunctionObject function(scope);
1572 for (uint k = 0; k < len; ++k) {
1573 if (instance->hasDetachedArrayData())
1574 return scope.engine->throwTypeError();
1578 v = instance->get(k);
1579 Q_ASSERT(!v->isNullOrUndefined());
1581 valueAsObject = v->toObject(scope.engine);
1582 Q_ASSERT(valueAsObject);
1584 function = valueAsObject->get(tolocaleString);
1586 return scope.engine->throwTypeError();
1588 v = function->call(valueAsObject,
nullptr, 0);
1589 if (scope.hasException())
1590 return Encode::undefined();
1592 s = v->toString(scope.engine);
1593 if (scope.hasException())
1594 return Encode::undefined();
1596 R += s->toQString();
1598 return scope.engine->newString(R)->asReturnedValue();
1646ReturnedValue IntrinsicTypedArrayCtor::method_from(
const FunctionObject *f,
const Value *thisObject,
const Value *argv,
int argc)
1649 ScopedObject itemsObject(scope, argv[0]);
1650 bool usingIterator =
false;
1652 ScopedFunctionObject mapfn(scope, Value::undefinedValue());
1653 Value *mapArguments =
nullptr;
1655 mapfn = ScopedFunctionObject(scope, argv[1]);
1657 return scope.engine->throwTypeError(QString::fromLatin1(
"%1 is not a function").arg(argv[1].toQStringNoThrow()));
1658 mapArguments = scope.constructUndefined(2);
1664 ScopedValue it(scope, itemsObject->get(scope.engine->symbol_iterator()));
1666 if (!it->isNullOrUndefined()) {
1667 ScopedFunctionObject itfunc(scope, it);
1669 return scope.engine->throwTypeError();
1670 usingIterator =
true;
1674 ScopedValue thisArg(scope);
1678 const FunctionObject *C = thisObject->as<FunctionObject>();
1680 if (usingIterator) {
1684 qint64 iterableLength = 0;
1685 Value *nextValue = scope.constructUndefined(1);
1686 ScopedValue done(scope);
1688 ScopedObject lengthIterator(scope, Runtime::GetIterator::call(scope.engine, itemsObject,
true));
1690 if (!lengthIterator) {
1691 return scope.engine->throwTypeError();
1696 if (iterableLength > (
static_cast<qint64>(1) << 53) - 1) {
1697 ScopedValue error(scope, scope.engine->throwTypeError());
1698 return Runtime::IteratorClose::call(scope.engine, lengthIterator);
1701 done = Value::fromReturnedValue(Runtime::IteratorNext::call(scope.engine, lengthIterator, nextValue));
1702 if (scope.hasException())
1703 return Runtime::IteratorClose::call(scope.engine, lengthIterator);
1704 if (done->toBoolean()) {
1712 if (!C || !C->isConstructor())
1713 return scope.engine->throwTypeError();
1715 ScopedObject iterator(scope, Runtime::GetIterator::call(scope.engine, itemsObject,
true));
1718 return scope.engine->throwTypeError();
1721 ScopedObject a(scope, Value::undefinedValue());
1722 ScopedValue ctorArgument(scope, Value::fromReturnedValue(QV4::Encode(
int(iterableLength))));
1723 a = C->callAsConstructor(ctorArgument, 1);
1727 if (!::validateTypedArray(a) || (a->getLength() < iterableLength))
1728 return scope.engine->throwTypeError();
1732 ScopedValue mappedValue(scope, Value::undefinedValue());
1733 for (qint64 k = 0; k < iterableLength; ++k) {
1734 done = Value::fromReturnedValue(Runtime::IteratorNext::call(scope.engine, iterator, nextValue));
1735 if (scope.hasException())
1736 return Runtime::IteratorClose::call(scope.engine, iterator);
1739 mapArguments[0] = *nextValue;
1740 mapArguments[1] = Value::fromDouble(k);
1741 mappedValue = mapfn->call(thisArg, mapArguments, 2);
1742 if (scope.hasException())
1743 return Runtime::IteratorClose::call(scope.engine, iterator);
1745 mappedValue = *nextValue;
1748 a->put(k, mappedValue);
1749 if (scope.hasException())
1750 return Runtime::IteratorClose::call(scope.engine, iterator);
1752 return a.asReturnedValue();
1755 ScopedObject arrayLike(scope, argv[0].toObject(scope.engine));
1757 return scope.engine->throwTypeError(QString::fromLatin1(
"Cannot convert %1 to object").arg(argv[0].toQStringNoThrow()));
1759 qint64 len = arrayLike->getLength();
1763 if (!C || !C->isConstructor())
1764 return scope.engine->throwTypeError();
1766 ScopedObject a(scope, Value::undefinedValue());
1767 ScopedValue ctorArgument(scope, Value::fromReturnedValue(QV4::Encode(
double(len))));
1768 a = C->callAsConstructor(ctorArgument, 1);
1772 if (!::validateTypedArray(a) || (a->getLength() < len))
1773 return scope.engine->throwTypeError();
1775 ScopedValue mappedValue(scope, Value::undefinedValue());
1776 ScopedValue kValue(scope);
1777 for (qint64 k = 0; k < len; ++k) {
1778 kValue = arrayLike->get(k);
1782 mapArguments[0] = kValue;
1783 mapArguments[1] = Value::fromDouble(k);
1784 mappedValue = mapfn->call(thisArg, mapArguments, 2);
1787 mappedValue = kValue;
1790 a->put(k, mappedValue);
1793 return a.asReturnedValue();
1797void IntrinsicTypedArrayPrototype::init(ExecutionEngine *engine, IntrinsicTypedArrayCtor *ctor)
1799 Scope scope(engine);
1800 ctor->defineReadonlyProperty(engine->id_prototype(), *
this);
1801 ctor->defineReadonlyConfigurableProperty(engine->id_length(), Value::fromInt32(0));
1802 ScopedString s(scope, engine->newString(QStringLiteral(
"TypedArray")));
1803 ctor->defineReadonlyConfigurableProperty(engine->id_name(), s);
1804 s = scope.engine->newString(QStringLiteral(
"of"));
1805 ctor->defineDefaultProperty(s, IntrinsicTypedArrayCtor::method_of);
1806 s = scope.engine->newString(QStringLiteral(
"from"));
1807 ctor->defineDefaultProperty(s, IntrinsicTypedArrayCtor::method_from, 1);
1808 ctor->addSymbolSpecies();
1810 defineAccessorProperty(QStringLiteral(
"buffer"), method_get_buffer,
nullptr);
1811 defineAccessorProperty(QStringLiteral(
"byteLength"), method_get_byteLength,
nullptr);
1812 defineAccessorProperty(QStringLiteral(
"byteOffset"), method_get_byteOffset,
nullptr);
1813 defineAccessorProperty(QStringLiteral(
"length"), method_get_length,
nullptr);
1815 defineDefaultProperty(QStringLiteral(
"copyWithin"), method_copyWithin, 2);
1816 defineDefaultProperty(QStringLiteral(
"entries"), method_entries, 0);
1817 defineDefaultProperty(QStringLiteral(
"every"), method_every, 1);
1818 defineDefaultProperty(QStringLiteral(
"fill"), method_fill, 1);
1819 defineDefaultProperty(QStringLiteral(
"filter"), method_filter, 1);
1820 defineDefaultProperty(QStringLiteral(
"find"), method_find, 1);
1821 defineDefaultProperty(QStringLiteral(
"findIndex"), method_findIndex, 1);
1822 defineDefaultProperty(QStringLiteral(
"forEach"), method_forEach, 1);
1823 defineDefaultProperty(QStringLiteral(
"includes"), method_includes, 1);
1824 defineDefaultProperty(QStringLiteral(
"indexOf"), method_indexOf, 1);
1825 defineDefaultProperty(QStringLiteral(
"join"), method_join, 1);
1826 defineDefaultProperty(QStringLiteral(
"keys"), method_keys, 0);
1827 defineDefaultProperty(QStringLiteral(
"lastIndexOf"), method_lastIndexOf, 1);
1828 defineDefaultProperty(QStringLiteral(
"map"), method_map, 1);
1829 defineDefaultProperty(QStringLiteral(
"reduce"), method_reduce, 1);
1830 defineDefaultProperty(QStringLiteral(
"reduceRight"), method_reduceRight, 1);
1831 defineDefaultProperty(QStringLiteral(
"reverse"), method_reverse, 0);
1832 defineDefaultProperty(QStringLiteral(
"some"), method_some, 1);
1833 defineDefaultProperty(QStringLiteral(
"set"), method_set, 1);
1834 defineDefaultProperty(QStringLiteral(
"slice"), method_slice, 2);
1835 defineDefaultProperty(QStringLiteral(
"subarray"), method_subarray, 2);
1836 defineDefaultProperty(engine->id_toLocaleString(), method_toLocaleString, 0);
1837 ScopedObject f(scope, engine->arrayPrototype()->get(engine->id_toString()));
1838 defineDefaultProperty(engine->id_toString(), f);
1840 ScopedString valuesString(scope, engine->newIdentifier(QStringLiteral(
"values")));
1841 ScopedObject values(scope, FunctionObject::createBuiltinFunction(engine, valuesString, method_values, 0));
1842 defineDefaultProperty(QStringLiteral(
"values"), values);
1843 defineDefaultProperty(engine->symbol_iterator(), values);
1845 defineAccessorProperty(engine->symbol_toStringTag(), method_get_toStringTag,
nullptr);