aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-08-24 01:00:36 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-08-24 01:00:36 +0200
commit444d645706d1f0cf287f8f8fc7aa90eb3482a8ea (patch)
tree850df67a76283eaf687f1934ef92c2e4b339ed58
parentb974b6249a2dce1af8b549fc0d0a5c6dd28d6292 (diff)
parent732c25029ec95feb27a607ef19bb3b7423a955a1 (diff)
Merge remote-tracking branch 'origin/5.12' into dev
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp27
-rw-r--r--src/qml/jit/qv4jithelpers.cpp4
-rw-r--r--src/qml/jsruntime/qv4arraybuffer.cpp13
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp51
-rw-r--r--src/qml/jsruntime/qv4dataview.cpp168
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp2
-rw-r--r--src/qml/jsruntime/qv4engine_p.h2
-rw-r--r--src/qml/jsruntime/qv4enginebase_p.h1
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp15
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h13
-rw-r--r--src/qml/jsruntime/qv4generatorobject.cpp10
-rw-r--r--src/qml/jsruntime/qv4generatorobject_p.h3
-rw-r--r--src/qml/jsruntime/qv4jscall_p.h6
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4object.cpp32
-rw-r--r--src/qml/jsruntime/qv4object_p.h3
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp2
-rw-r--r--src/qml/jsruntime/qv4proxy.cpp90
-rw-r--r--src/qml/jsruntime/qv4proxy_p.h33
-rw-r--r--src/qml/jsruntime/qv4reflect.cpp8
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp22
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp3
-rw-r--r--src/qml/jsruntime/qv4symbol.cpp5
-rw-r--r--src/qml/jsruntime/qv4symbol_p.h1
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp966
-rw-r--r--src/qml/jsruntime/qv4typedarray_p.h25
-rw-r--r--src/qml/jsruntime/qv4value_p.h10
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp4
-rw-r--r--src/qml/qml/qqmllocale.cpp4
-rw-r--r--src/qml/qml/qqmlmetatype.cpp8
-rw-r--r--src/quick/items/qquickflickable.cpp4
-rw-r--r--src/quick/items/qquicktableview.cpp26
-rw-r--r--src/quick/items/qquicktableview_p_p.h5
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations489
m---------tests/auto/qml/ecmascripttests/test2620
-rw-r--r--tests/auto/quick/pointerhandlers/pointerhandlers.pro6
-rw-r--r--tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml164
-rw-r--r--tests/auto/quick/pointerhandlers/qquickhoverhandler/qquickhoverhandler.pro15
-rw-r--r--tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp234
-rw-r--r--tests/auto/quick/qquicklistview/data/snapOneItemWrongDirection.qml18
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp19
-rw-r--r--tests/auto/quick/qquicktableview/data/changemodelfromdelegate.qml97
-rw-r--r--tests/auto/quick/qquicktableview/testmodel.h5
-rw-r--r--tests/auto/quick/qquicktableview/tst_qquicktableview.cpp29
45 files changed, 1886 insertions, 760 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 624e3c42e7..88accc2f49 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -1618,36 +1618,37 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
// No more new strings after this point, we're calculating offsets.
output.jsGenerator.stringTable.freeze();
- const int importSize = sizeof(QV4::CompiledData::Import) * output.imports.count();
- const int objectOffsetTableSize = output.objects.count() * sizeof(quint32);
+ const uint importSize = sizeof(QV4::CompiledData::Import) * output.imports.count();
+ const uint objectOffsetTableSize = output.objects.count() * sizeof(quint32);
QHash<const Object*, quint32> objectOffsets;
- int objectsSize = 0;
+ const unsigned int objectOffset = sizeof(QV4::CompiledData::QmlUnit) + importSize;
+ uint nextOffset = objectOffset + objectOffsetTableSize;
for (Object *o : qAsConst(output.objects)) {
- objectOffsets.insert(o, sizeof(QV4::CompiledData::QmlUnit) + importSize + objectOffsetTableSize + objectsSize);
- objectsSize += QV4::CompiledData::Object::calculateSizeExcludingSignalsAndEnums(o->functionCount(), o->propertyCount(), o->aliasCount(), o->enumCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.count);
+ objectOffsets.insert(o, nextOffset);
+ nextOffset += QV4::CompiledData::Object::calculateSizeExcludingSignalsAndEnums(o->functionCount(), o->propertyCount(), o->aliasCount(), o->enumCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.count);
int signalTableSize = 0;
for (const Signal *s = o->firstSignal(); s; s = s->next)
signalTableSize += QV4::CompiledData::Signal::calculateSize(s->parameters->count);
- objectsSize += signalTableSize;
+ nextOffset += signalTableSize;
int enumTableSize = 0;
for (const Enum *e = o->firstEnum(); e; e = e->next)
enumTableSize += QV4::CompiledData::Enum::calculateSize(e->enumValues->count);
- objectsSize += enumTableSize;
+ nextOffset += enumTableSize;
}
- const uint totalSize = sizeof(QV4::CompiledData::QmlUnit) + importSize + objectOffsetTableSize + objectsSize;
+ const uint totalSize = nextOffset;
char *data = (char*)malloc(totalSize);
memset(data, 0, totalSize);
QV4::CompiledData::QmlUnit *qmlUnit = reinterpret_cast<QV4::CompiledData::QmlUnit *>(data);
qmlUnit->offsetToImports = sizeof(*qmlUnit);
qmlUnit->nImports = output.imports.count();
- qmlUnit->offsetToObjects = qmlUnit->offsetToImports + importSize;
+ qmlUnit->offsetToObjects = objectOffset;
qmlUnit->nObjects = output.objects.count();
// write imports
@@ -1660,9 +1661,9 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
// write objects
quint32_le *objectTable = reinterpret_cast<quint32_le*>(data + qmlUnit->offsetToObjects);
- char *objectPtr = data + qmlUnit->offsetToObjects + objectOffsetTableSize;
for (int i = 0; i < output.objects.count(); ++i) {
const Object *o = output.objects.at(i);
+ char * const objectPtr = data + objectOffsets.value(o);
*objectTable++ = objectOffsets.value(o);
QV4::CompiledData::Object *objectToWrite = reinterpret_cast<QV4::CompiledData::Object*>(objectPtr);
@@ -1776,10 +1777,6 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
for (int i = 0; i < o->namedObjectsInComponent.count; ++i) {
*namedObjectInComponentPtr++ = o->namedObjectsInComponent.at(i);
}
-
- objectPtr += QV4::CompiledData::Object::calculateSizeExcludingSignalsAndEnums(o->functionCount(), o->propertyCount(), o->aliasCount(), o->enumCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.count);
- objectPtr += signalTableSize;
- objectPtr += enumTableSize;
}
qmlUnit = unitFinalizer(qmlUnit, totalSize);
@@ -1790,7 +1787,7 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
qDebug() << " " << jsUnit->functionTableSize << "functions";
qDebug() << " " << jsUnit->unitSize << "for JS unit";
qDebug() << " " << importSize << "for imports";
- qDebug() << " " << objectsSize << "for" << qmlUnit->nObjects << "objects";
+ qDebug() << " " << nextOffset - objectOffset - objectOffsetTableSize << "for" << qmlUnit->nObjects << "objects";
quint32 totalBindingCount = 0;
for (quint32 i = 0; i < qmlUnit->nObjects; ++i)
totalBindingCount += qmlUnit->objectAt(i)->nBindings;
diff --git a/src/qml/jit/qv4jithelpers.cpp b/src/qml/jit/qv4jithelpers.cpp
index 23e3095a85..9e057dd33d 100644
--- a/src/qml/jit/qv4jithelpers.cpp
+++ b/src/qml/jit/qv4jithelpers.cpp
@@ -42,6 +42,7 @@
#include "qv4function_p.h"
#include "qv4value_p.h"
#include "qv4object_p.h"
+#include "qv4functionobject_p.h"
#include "qv4lookup_p.h"
#include <QtCore/private/qnumeric_p.h>
@@ -71,7 +72,8 @@ ReturnedValue loadGlobalLookup(ExecutionEngine *engine, Function *f, int index)
ReturnedValue loadSuperConstructor(ExecutionEngine *engine, const Value *t)
{
- if (!t->isObject()) {
+ const FunctionObject *f = t->as<FunctionObject>();
+ if (!f || !f->isConstructor()) {
engine->throwTypeError();
return Encode::undefined();
}
diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp
index c52e9bf24e..dc8bce12a0 100644
--- a/src/qml/jsruntime/qv4arraybuffer.cpp
+++ b/src/qml/jsruntime/qv4arraybuffer.cpp
@@ -74,9 +74,9 @@ ReturnedValue ArrayBufferCtor::virtualCallAsConstructor(const FunctionObject *f,
}
-ReturnedValue ArrayBufferCtor::virtualCall(const FunctionObject *f, const Value *, const Value *argv, int argc)
+ReturnedValue ArrayBufferCtor::virtualCall(const FunctionObject *f, const Value *, const Value *, int)
{
- return virtualCallAsConstructor(f, argv, argc, f);
+ return f->engine()->throwTypeError();
}
ReturnedValue ArrayBufferCtor::method_isView(const FunctionObject *, const Value *, const Value *argv, int argc)
@@ -188,18 +188,21 @@ ReturnedValue ArrayBufferPrototype::method_slice(const FunctionObject *b, const
double final = (end < 0) ? qMax(a->d()->data->size + end, 0.) : qMin(end, (double)a->d()->data->size);
Scope scope(v4);
- ScopedFunctionObject constructor(scope, a->get(scope.engine->id_constructor()));
+ const FunctionObject *constructor = a->speciesConstructor(scope, scope.engine->arrayBufferCtor());
if (!constructor)
return v4->throwTypeError();
double newLen = qMax(final - first, 0.);
ScopedValue argument(scope, QV4::Encode(newLen));
QV4::Scoped<ArrayBuffer> newBuffer(scope, constructor->callAsConstructor(argument, 1));
- if (!newBuffer || newBuffer->d()->data->size < (int)newLen)
+ if (!newBuffer || newBuffer->d()->data->size < (int)newLen ||
+ newBuffer->isDetachedBuffer() || newBuffer->isSharedArrayBuffer() ||
+ newBuffer->sameValue(*a) ||
+ a->isDetachedBuffer())
return v4->throwTypeError();
memcpy(newBuffer->d()->data->data(), a->d()->data->data() + (uint)first, newLen);
- return Encode::undefined();
+ return newBuffer->asReturnedValue();
}
ReturnedValue ArrayBufferPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index 450916fbf7..c162a38e9d 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -104,7 +104,7 @@ void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor)
ScopedString name(scope);
defineDefaultProperty(QStringLiteral("constructor"), (o = ctor));
defineDefaultProperty(engine->id_toString(), method_toString, 0);
- defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString, 0);
+ defineDefaultProperty(engine->id_toLocaleString(), method_toLocaleString, 0);
defineDefaultProperty(QStringLiteral("concat"), method_concat, 1);
name = engine->newIdentifier(QStringLiteral("copyWithin"));
unscopables->put(name, Primitive::fromBoolean(true));
@@ -165,23 +165,13 @@ ScopedObject createObjectFromCtorOrArray(Scope &scope, ScopedFunctionObject ctor
{
ScopedObject a(scope, Primitive::undefinedValue());
- if (ctor) {
- // ### the spec says that we should only call constructors if
- // IsConstructor(that), but we have no way of knowing if a builtin is a
- // constructor. so for the time being, just try call it, and silence any
- // exceptions-- this is not ideal, as the spec also says that we should
- // return on exception.
- //
- // this also isn't completely kosher. for instance:
+ if (ctor && ctor->isConstructor()) {
+ // this isn't completely kosher. for instance:
// Array.from.call(Object, []).constructor == Object
// is expected by the tests, but naturally, we get Number.
ScopedValue argument(scope, useLen ? QV4::Encode(len) : Primitive::undefinedValue());
a = ctor->callAsConstructor(argument, useLen ? 1 : 0);
- if (scope.engine->hasException)
- scope.engine->catchException(); // probably not a constructor, then.
- }
-
- if (!a) {
+ } else {
a = scope.engine->newArrayObject(len);
}
@@ -369,9 +359,36 @@ ReturnedValue ArrayPrototype::method_toString(const FunctionObject *builtin, con
return ObjectPrototype::method_toString(builtin, that, argv, argc);
}
-ReturnedValue ArrayPrototype::method_toLocaleString(const FunctionObject *builtin, const Value *thisObject, const Value *argv, int argc)
+ReturnedValue ArrayPrototype::method_toLocaleString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- return method_toString(builtin, thisObject, argv, argc);
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject);
+ if (!instance)
+ return scope.engine->throwTypeError();
+
+ uint len = instance->getLength();
+ const QString separator = QStringLiteral(",");
+
+ QString R;
+
+ ScopedValue v(scope);
+ ScopedString s(scope);
+
+ for (uint k = 0; k < len; ++k) {
+ if (k)
+ R += separator;
+
+ v = instance->get(k);
+ if (v->isNullOrUndefined())
+ continue;
+ v = Runtime::method_callElement(scope.engine, v, *scope.engine->id_toLocaleString(), nullptr, 0);
+ s = v->toString(scope.engine);
+ if (scope.hasException())
+ return Encode::undefined();
+
+ R += s->toQString();
+ }
+ return scope.engine->newString(R)->asReturnedValue();
}
ReturnedValue ArrayPrototype::method_concat(const FunctionObject *b, const Value *that, const Value *argv, int argc)
@@ -432,7 +449,7 @@ ReturnedValue ArrayPrototype::method_copyWithin(const FunctionObject *b, const V
double len = instance->getLength();
double target = argv[0].toInteger();
- double start = argv[1].toInteger();
+ double start = argc > 1 ? argv[1].toInteger() : 0;
double end = len;
if (argc > 2 && !argv[2].isUndefined()) {
diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp
index d959b1667b..3f0e2fd1a7 100644
--- a/src/qml/jsruntime/qv4dataview.cpp
+++ b/src/qml/jsruntime/qv4dataview.cpp
@@ -55,38 +55,63 @@ void Heap::DataViewCtor::init(QV4::ExecutionContext *scope)
Heap::FunctionObject::init(scope, QStringLiteral("DataView"));
}
-ReturnedValue DataViewCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *)
+static uint toIndex(ExecutionEngine *e, const Value &v)
+{
+ if (v.isUndefined())
+ return 0;
+ double index = v.toInteger();
+ if (index < 0) {
+ e->throwRangeError(QStringLiteral("index out of range"));
+ return 0;
+ }
+ uint idx = static_cast<uint>(index);
+ if (idx != index) {
+ e->throwRangeError(QStringLiteral("index out of range"));
+ return 0;
+ }
+ return idx;
+}
+
+ReturnedValue DataViewCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget)
{
Scope scope(f->engine());
Scoped<ArrayBuffer> buffer(scope, argc ? argv[0] : Primitive::undefinedValue());
- if (!buffer || buffer->isDetachedBuffer())
+ if (!newTarget || !buffer)
+ return scope.engine->throwTypeError();
+
+ uint offset = ::toIndex(scope.engine, argc > 1 ? argv[1]: Primitive::undefinedValue());
+ if (scope.hasException())
+ return Encode::undefined();
+ if (buffer->isDetachedBuffer())
return scope.engine->throwTypeError();
- double bo = argc > 1 ? argv[1].toNumber() : 0;
- uint byteOffset = (uint)bo;
uint bufferLength = buffer->d()->data->size;
- double bl = argc < 3 || argv[2].isUndefined() ? (bufferLength - bo) : argv[2].toNumber();
- uint byteLength = (uint)bl;
- if (bo != byteOffset || bl != byteLength || byteOffset + byteLength > bufferLength)
+ if (offset > bufferLength)
+ return scope.engine->throwRangeError(QStringLiteral("DataView: constructor arguments out of range"));
+
+ uint byteLength = (argc < 3 || argv[2].isUndefined()) ? (bufferLength - offset) : ::toIndex(scope.engine, argv[2]);
+ if (scope.hasException())
+ return Encode::undefined();
+ if (offset + byteLength > bufferLength)
return scope.engine->throwRangeError(QStringLiteral("DataView: constructor arguments out of range"));
Scoped<DataView> a(scope, scope.engine->memoryManager->allocate<DataView>());
a->d()->buffer.set(scope.engine, buffer->d());
a->d()->byteLength = byteLength;
- a->d()->byteOffset = byteOffset;
+ a->d()->byteOffset = offset;
return a.asReturnedValue();
}
-ReturnedValue DataViewCtor::virtualCall(const FunctionObject *f, const Value *, const Value *argv, int argc)
+ReturnedValue DataViewCtor::virtualCall(const FunctionObject *f, const Value *, const Value *, int)
{
- return virtualCallAsConstructor(f, argv, argc, f);
+ return f->engine()->throwTypeError();
}
void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor)
{
Scope scope(engine);
ScopedObject o(scope);
- ctor->defineReadonlyConfigurableProperty(engine->id_length(), Primitive::fromInt32(3));
+ ctor->defineReadonlyConfigurableProperty(engine->id_length(), Primitive::fromInt32(1));
ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
defineDefaultProperty(engine->id_constructor(), (o = ctor));
defineAccessorProperty(QStringLiteral("buffer"), method_get_buffer, nullptr);
@@ -138,6 +163,9 @@ ReturnedValue DataViewPrototype::method_get_byteLength(const FunctionObject *b,
if (!v)
return b->engine()->throwTypeError();
+ if (v->d()->buffer->isDetachedBuffer())
+ return b->engine()->throwTypeError();
+
return Encode(v->d()->byteLength);
}
@@ -147,23 +175,28 @@ ReturnedValue DataViewPrototype::method_get_byteOffset(const FunctionObject *b,
if (!v)
return b->engine()->throwTypeError();
+ if (v->d()->buffer->isDetachedBuffer())
+ return b->engine()->throwTypeError();
+
return Encode(v->d()->byteOffset);
}
template <typename T>
ReturnedValue DataViewPrototype::method_getChar(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
+ ExecutionEngine *e = b->engine();
const DataView *v = thisObject->as<DataView>();
- if (!v || argc < 1)
- return b->engine()->throwTypeError();
- double l = argv[0].toNumber();
- uint idx = (uint)l;
- if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return b->engine()->throwTypeError();
+ if (!v)
+ return e->throwTypeError();
+ uint idx = ::toIndex(e, argc ? argv[0] : Primitive::undefinedValue());
+ if (e->hasException)
+ return Encode::undefined();
+ if (v->d()->buffer->isDetachedBuffer())
+ return e->throwTypeError();
+ if (idx + sizeof(T) > v->d()->byteLength)
+ return e->throwRangeError(QStringLiteral("index out of range"));
idx += v->d()->byteOffset;
- if (v->d()->buffer->isDetachedBuffer())
- return b->engine()->throwTypeError();
T t = T(v->d()->buffer->data->data()[idx]);
return Encode((int)t);
@@ -172,19 +205,21 @@ ReturnedValue DataViewPrototype::method_getChar(const FunctionObject *b, const V
template <typename T>
ReturnedValue DataViewPrototype::method_get(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
+ ExecutionEngine *e = b->engine();
const DataView *v = thisObject->as<DataView>();
- if (!v || argc < 1)
- return b->engine()->throwTypeError();
- double l = argv[0].toNumber();
- uint idx = (uint)l;
- if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return b->engine()->throwTypeError();
+ if (!v)
+ return e->throwTypeError();
+ uint idx = ::toIndex(e, argc ? argv[0] : Primitive::undefinedValue());
+ if (e->hasException)
+ return Encode::undefined();
+ if (v->d()->buffer->isDetachedBuffer())
+ return e->throwTypeError();
+ if (idx + sizeof(T) > v->d()->byteLength)
+ return e->throwRangeError(QStringLiteral("index out of range"));
idx += v->d()->byteOffset;
bool littleEndian = argc < 2 ? false : argv[1].toBoolean();
- if (v->d()->buffer->isDetachedBuffer())
- return b->engine()->throwTypeError();
T t = littleEndian
? qFromLittleEndian<T>((uchar *)v->d()->buffer->data->data() + idx)
: qFromBigEndian<T>((uchar *)v->d()->buffer->data->data() + idx);
@@ -195,20 +230,21 @@ ReturnedValue DataViewPrototype::method_get(const FunctionObject *b, const Value
template <typename T>
ReturnedValue DataViewPrototype::method_getFloat(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
+ ExecutionEngine *e = b->engine();
const DataView *v = thisObject->as<DataView>();
- if (!v || argc < 1)
- return b->engine()->throwTypeError();
- double l = argv[0].toNumber();
- uint idx = (uint)l;
- if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return b->engine()->throwTypeError();
+ if (!v)
+ return e->throwTypeError();
+ uint idx = ::toIndex(e, argc ? argv[0] : Primitive::undefinedValue());
+ if (e->hasException)
+ return Encode::undefined();
+ if (v->d()->buffer->isDetachedBuffer())
+ return e->throwTypeError();
+ if (idx + sizeof(T) > v->d()->byteLength)
+ return e->throwRangeError(QStringLiteral("index out of range"));
idx += v->d()->byteOffset;
bool littleEndian = argc < 2 ? false : argv[1].toBoolean();
- if (v->d()->buffer->isDetachedBuffer())
- return b->engine()->throwTypeError();
-
if (sizeof(T) == 4) {
// float
union {
@@ -235,19 +271,22 @@ ReturnedValue DataViewPrototype::method_getFloat(const FunctionObject *b, const
template <typename T>
ReturnedValue DataViewPrototype::method_setChar(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
+ ExecutionEngine *e = b->engine();
const DataView *v = thisObject->as<DataView>();
- if (!v || argc < 1)
- return b->engine()->throwTypeError();
- double l = argv[0].toNumber();
- uint idx = (uint)l;
- if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return b->engine()->throwTypeError();
- idx += v->d()->byteOffset;
+ if (!v)
+ return e->throwTypeError();
+ uint idx = ::toIndex(e, argc ? argv[0] : Primitive::undefinedValue());
+ if (e->hasException)
+ return Encode::undefined();
int val = argc >= 2 ? argv[1].toInt32() : 0;
if (v->d()->buffer->isDetachedBuffer())
- return b->engine()->throwTypeError();
+ return e->throwTypeError();
+
+ if (idx + sizeof(T) > v->d()->byteLength)
+ return e->throwRangeError(QStringLiteral("index out of range"));
+ idx += v->d()->byteOffset;
v->d()->buffer->data->data()[idx] = (char)val;
@@ -257,21 +296,24 @@ ReturnedValue DataViewPrototype::method_setChar(const FunctionObject *b, const V
template <typename T>
ReturnedValue DataViewPrototype::method_set(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
+ ExecutionEngine *e = b->engine();
const DataView *v = thisObject->as<DataView>();
- if (!v || argc < 1)
- return b->engine()->throwTypeError();
- double l = argv[0].toNumber();
- uint idx = (uint)l;
- if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return b->engine()->throwTypeError();
- idx += v->d()->byteOffset;
+ if (!v)
+ return e->throwTypeError();
+ uint idx = ::toIndex(e, argc ? argv[0] : Primitive::undefinedValue());
+ if (e->hasException)
+ return Encode::undefined();
int val = argc >= 2 ? argv[1].toInt32() : 0;
-
bool littleEndian = argc < 3 ? false : argv[2].toBoolean();
if (v->d()->buffer->isDetachedBuffer())
- return b->engine()->throwTypeError();
+ return e->throwTypeError();
+
+ if (idx + sizeof(T) > v->d()->byteLength)
+ return e->throwRangeError(QStringLiteral("index out of range"));
+ idx += v->d()->byteOffset;
+
if (littleEndian)
qToLittleEndian<T>(val, (uchar *)v->d()->buffer->data->data() + idx);
@@ -284,19 +326,23 @@ ReturnedValue DataViewPrototype::method_set(const FunctionObject *b, const Value
template <typename T>
ReturnedValue DataViewPrototype::method_setFloat(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
+ ExecutionEngine *e = b->engine();
const DataView *v = thisObject->as<DataView>();
- if (!v || argc < 1)
- return b->engine()->throwTypeError();
- double l = argv[0].toNumber();
- uint idx = (uint)l;
- if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return b->engine()->throwTypeError();
- idx += v->d()->byteOffset;
+ if (!v)
+ return e->throwTypeError();
+ uint idx = ::toIndex(e, argc ? argv[0] : Primitive::undefinedValue());
+ if (e->hasException)
+ return Encode::undefined();
double val = argc >= 2 ? argv[1].toNumber() : qt_qnan();
bool littleEndian = argc < 3 ? false : argv[2].toBoolean();
+
if (v->d()->buffer->isDetachedBuffer())
- return b->engine()->throwTypeError();
+ return e->throwTypeError();
+
+ if (idx + sizeof(T) > v->d()->byteLength)
+ return e->throwRangeError(QStringLiteral("index out of range"));
+ idx += v->d()->byteOffset;
if (sizeof(T) == 4) {
// float
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index 3efd626685..7335dd1ba0 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -806,7 +806,7 @@ void DatePrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(engine->id_toString(), method_toString, 0);
defineDefaultProperty(QStringLiteral("toDateString"), method_toDateString, 0);
defineDefaultProperty(QStringLiteral("toTimeString"), method_toTimeString, 0);
- defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString, 0);
+ defineDefaultProperty(engine->id_toLocaleString(), method_toLocaleString, 0);
defineDefaultProperty(QStringLiteral("toLocaleDateString"), method_toLocaleDateString, 0);
defineDefaultProperty(QStringLiteral("toLocaleTimeString"), method_toLocaleTimeString, 0);
defineDefaultProperty(engine->id_valueOf(), method_valueOf, 0);
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index ea17f3423c..5ccf3d4f6e 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -275,6 +275,7 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
jsStrings[String_index] = newIdentifier(QStringLiteral("index"));
jsStrings[String_input] = newIdentifier(QStringLiteral("input"));
jsStrings[String_toString] = newIdentifier(QStringLiteral("toString"));
+ jsStrings[String_toLocaleString] = newIdentifier(QStringLiteral("toLocaleString"));
jsStrings[String_destroy] = newIdentifier(QStringLiteral("destroy"));
jsStrings[String_valueOf] = newIdentifier(QStringLiteral("valueOf"));
jsStrings[String_byteLength] = newIdentifier(QStringLiteral("byteLength"));
@@ -401,6 +402,7 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
Q_ASSERT(index == ErrorPrototype::Index_Name);
classes[Class_ProxyObject] = classes[Class_Empty]->changeVTable(ProxyObject::staticVTable());
+ classes[Class_ProxyFunctionObject] = classes[Class_Empty]->changeVTable(ProxyFunctionObject::staticVTable());
jsObjects[GetStack_Function] = FunctionObject::createBuiltinFunction(this, str = newIdentifier(QStringLiteral("stack")), ErrorObject::method_get_stack, 0);
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 7608c04800..e11e607bd1 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -315,6 +315,7 @@ public:
String_index,
String_input,
String_toString,
+ String_toLocaleString,
String_destroy,
String_valueOf,
String_byteLength,
@@ -385,6 +386,7 @@ public:
String *id_index() const { return reinterpret_cast<String *>(jsStrings + String_index); }
String *id_input() const { return reinterpret_cast<String *>(jsStrings + String_input); }
String *id_toString() const { return reinterpret_cast<String *>(jsStrings + String_toString); }
+ String *id_toLocaleString() const { return reinterpret_cast<String *>(jsStrings + String_toLocaleString); }
String *id_destroy() const { return reinterpret_cast<String *>(jsStrings + String_destroy); }
String *id_valueOf() const { return reinterpret_cast<String *>(jsStrings + String_valueOf); }
String *id_byteLength() const { return reinterpret_cast<String *>(jsStrings + String_byteLength); }
diff --git a/src/qml/jsruntime/qv4enginebase_p.h b/src/qml/jsruntime/qv4enginebase_p.h
index 189208e731..789ec5d970 100644
--- a/src/qml/jsruntime/qv4enginebase_p.h
+++ b/src/qml/jsruntime/qv4enginebase_p.h
@@ -118,6 +118,7 @@ struct Q_QML_EXPORT EngineBase {
Class_ErrorProto,
Class_QmlContextWrapper,
Class_ProxyObject,
+ Class_ProxyFunctionObject,
Class_Symbol,
NClasses
};
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 35d8fe18e0..a5dc0ba567 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -73,7 +73,7 @@ DEFINE_OBJECT_VTABLE(FunctionObject);
void Heap::FunctionObject::init(QV4::ExecutionContext *scope, QV4::String *name, VTable::Call call)
{
jsCall = call;
- jsConstruct = QV4::FunctionObject::virtualCallAsConstructor;
+ jsConstruct = nullptr;
Object::init();
this->scope.set(scope->engine(), scope->d());
@@ -165,11 +165,6 @@ ReturnedValue FunctionObject::name() const
return get(scope()->internalClass->engine->id_name());
}
-ReturnedValue FunctionObject::virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *)
-{
- return f->engine()->throwTypeError();
-}
-
ReturnedValue FunctionObject::virtualCall(const FunctionObject *, const Value *, const Value *, int)
{
return Encode::undefined();
@@ -587,11 +582,6 @@ ReturnedValue ConstructorFunction::virtualCall(const FunctionObject *f, const Va
DEFINE_OBJECT_VTABLE(MemberFunction);
-ReturnedValue MemberFunction::virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *)
-{
- return f->engine()->throwTypeError(QStringLiteral("Function is not a constructor."));
-}
-
DEFINE_OBJECT_VTABLE(DefaultClassConstructorFunction);
ReturnedValue DefaultClassConstructorFunction::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget)
@@ -652,6 +642,9 @@ void Heap::BoundFunction::init(QV4::ExecutionContext *scope, QV4::FunctionObject
this->boundArgs.set(s.engine, boundArgs ? boundArgs->d() : nullptr);
this->boundThis.set(scope->engine(), boundThis);
+ if (!target->isConstructor())
+ jsConstruct = nullptr;
+
ScopedObject f(s, this);
ScopedValue l(s, target->get(s.engine->id_length()));
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index 8482189bb3..54964b9bbd 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -80,6 +80,10 @@ DECLARE_HEAP_OBJECT(FunctionObject, Object) {
Index_ProtoConstructor = 0
};
+ bool isConstructor() const {
+ return jsConstruct != nullptr;
+ }
+
Q_QML_PRIVATE_EXPORT void init(QV4::ExecutionContext *scope, QV4::String *name, VTable::Call call);
void init(QV4::ExecutionContext *scope, QV4::String *name = nullptr, bool createProto = false);
void init(QV4::ExecutionContext *scope, QV4::Function *function, QV4::String *n = nullptr);
@@ -170,13 +174,16 @@ struct Q_QML_EXPORT FunctionObject: Object {
inline ReturnedValue callAsConstructor(const JSCallData &data) const;
ReturnedValue callAsConstructor(const Value *argv, int argc, const Value *newTarget = nullptr) const {
+ if (!d()->jsConstruct)
+ return engine()->throwTypeError(QStringLiteral("Function is not a constructor."));
return d()->jsConstruct(this, argv, argc, newTarget ? newTarget : this);
}
inline ReturnedValue call(const JSCallData &data) const;
ReturnedValue call(const Value *thisObject, const Value *argv, int argc) const {
+ if (!d()->jsCall)
+ return engine()->throwTypeError(QStringLiteral("Function can only be called with |new|."));
return d()->jsCall(this, thisObject, argv, argc);
}
- static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *);
static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
static Heap::FunctionObject *createScriptFunction(ExecutionContext *scope, Function *function);
@@ -187,6 +194,9 @@ struct Q_QML_EXPORT FunctionObject: Object {
bool strictMode() const { return d()->function ? d()->function->isStrict() : false; }
bool isBinding() const;
bool isBoundFunction() const;
+ bool isConstructor() const {
+ return d()->isConstructor();
+ }
ReturnedValue protoProperty() const { return get(engine()->id_prototype()); }
@@ -261,7 +271,6 @@ struct ConstructorFunction : ScriptFunction {
struct MemberFunction : ScriptFunction {
V4_OBJECT2(MemberFunction, ScriptFunction)
V4_INTERNALCLASS(MemberFunction)
- static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc, const Value *);
};
diff --git a/src/qml/jsruntime/qv4generatorobject.cpp b/src/qml/jsruntime/qv4generatorobject.cpp
index 4a784bff35..bab0cfbfb1 100644
--- a/src/qml/jsruntime/qv4generatorobject.cpp
+++ b/src/qml/jsruntime/qv4generatorobject.cpp
@@ -84,11 +84,6 @@ Heap::FunctionObject *GeneratorFunction::create(ExecutionContext *context, Funct
return g->d();
}
-ReturnedValue GeneratorFunction::virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *)
-{
- return f->engine()->throwTypeError();
-}
-
ReturnedValue GeneratorFunction::virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
{
const GeneratorFunction *gf = static_cast<const GeneratorFunction *>(f);
@@ -245,8 +240,3 @@ Heap::FunctionObject *MemberGeneratorFunction::create(ExecutionContext *context,
g->setPrototypeOf(ScopedObject(scope, scope.engine->generatorFunctionCtor()->get(scope.engine->id_prototype())));
return g->d();
}
-
-ReturnedValue MemberGeneratorFunction::virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *)
-{
- return f->engine()->throwTypeError(QStringLiteral("Function is not a constructor."));
-}
diff --git a/src/qml/jsruntime/qv4generatorobject_p.h b/src/qml/jsruntime/qv4generatorobject_p.h
index 017580e1a1..f00f730344 100644
--- a/src/qml/jsruntime/qv4generatorobject_p.h
+++ b/src/qml/jsruntime/qv4generatorobject_p.h
@@ -109,7 +109,7 @@ struct GeneratorFunction : ScriptFunction
V4_INTERNALCLASS(GeneratorFunction)
static Heap::FunctionObject *create(ExecutionContext *scope, Function *function);
- static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *);
+ static constexpr VTable::CallAsConstructor virtualCallAsConstructor = nullptr;
static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
};
@@ -119,7 +119,6 @@ struct MemberGeneratorFunction : GeneratorFunction
V4_INTERNALCLASS(MemberGeneratorFunction)
static Heap::FunctionObject *create(ExecutionContext *scope, Function *function, String *name);
- static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *);
};
struct GeneratorPrototype : Object
diff --git a/src/qml/jsruntime/qv4jscall_p.h b/src/qml/jsruntime/qv4jscall_p.h
index 307eec9111..55cedf50aa 100644
--- a/src/qml/jsruntime/qv4jscall_p.h
+++ b/src/qml/jsruntime/qv4jscall_p.h
@@ -102,15 +102,13 @@ struct JSCallData {
inline
ReturnedValue FunctionObject::callAsConstructor(const JSCallData &data) const
{
- if (!d()->jsConstruct)
- return engine()->throwTypeError(QStringLiteral("Object is not a constructor."));
- return d()->jsConstruct(this, data.args, data.argc, this);
+ return callAsConstructor(data.args, data.argc, this);
}
inline
ReturnedValue FunctionObject::call(const JSCallData &data) const
{
- return d()->jsCall(this, data.thisObject, data.args, data.argc);
+ return call(data.thisObject, data.args, data.argc);
}
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index d103f65d47..d552948e95 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -117,7 +117,7 @@ QT_WARNING_POP
defineDefaultProperty(QStringLiteral("constructor"), (o = ctor));
defineDefaultProperty(engine->id_toString(), method_toString, 1);
- defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString);
+ defineDefaultProperty(engine->id_toLocaleString(), method_toLocaleString);
defineDefaultProperty(engine->id_valueOf(), method_valueOf);
defineDefaultProperty(QStringLiteral("toFixed"), method_toFixed, 1);
defineDefaultProperty(QStringLiteral("toExponential"), method_toExponential, 1);
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 6a6687661c..eb4e392c0f 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -308,16 +308,6 @@ PropertyIndex Object::getValueOrSetter(PropertyKey id, PropertyAttributes *attrs
return { nullptr, nullptr };
}
-ReturnedValue Object::virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *)
-{
- return f->engine()->throwTypeError();
-}
-
-ReturnedValue Object::virtualCall(const FunctionObject *f, const Value *, const Value *, int)
-{
- return f->engine()->throwTypeError();
-}
-
ReturnedValue Object::virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty)
{
if (id.isArrayIndex())
@@ -960,6 +950,28 @@ bool Object::isArray() const
return false;
}
+const FunctionObject *Object::speciesConstructor(Scope &scope, const FunctionObject *defaultConstructor) const
+{
+ ScopedValue C(scope, get(scope.engine->id_constructor()));
+ if (C->isUndefined())
+ return defaultConstructor;
+ const Object *c = C->objectValue();
+ if (!c) {
+ scope.engine->throwTypeError();
+ return nullptr;
+ }
+ ScopedValue S(scope, c->get(scope.engine->symbol_species()));
+ if (S->isNullOrUndefined())
+ return defaultConstructor;
+ const FunctionObject *f = S->as<FunctionObject>();
+ if (!f || !f->isConstructor()) {
+ scope.engine->throwTypeError();
+ return nullptr;
+ }
+ Q_ASSERT(f->isFunctionObject());
+ return static_cast<const FunctionObject *>(f);
+}
+
DEFINE_OBJECT_VTABLE(ArrayObject);
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 431c378334..70fee128b6 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -361,10 +361,9 @@ public:
bool isConcatSpreadable() const;
bool isArray() const;
+ const FunctionObject *speciesConstructor(Scope &scope, const FunctionObject *defaultConstructor) const;
protected:
- static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *);
- static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver,bool *hasProperty);
static bool virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver);
static bool virtualDeleteProperty(Managed *m, PropertyKey id);
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index ed810cb456..c968bff0fe 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -119,7 +119,7 @@ void ObjectPrototype::init(ExecutionEngine *v4, Object *ctor)
defineDefaultProperty(QStringLiteral("constructor"), (o = ctor));
defineDefaultProperty(v4->id_toString(), method_toString, 0);
- defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString, 0);
+ defineDefaultProperty(v4->id_toLocaleString(), method_toLocaleString, 0);
defineDefaultProperty(v4->id_valueOf(), method_valueOf, 0);
defineDefaultProperty(QStringLiteral("hasOwnProperty"), method_hasOwnProperty, 1);
defineDefaultProperty(QStringLiteral("isPrototypeOf"), method_isPrototypeOf, 1);
diff --git a/src/qml/jsruntime/qv4proxy.cpp b/src/qml/jsruntime/qv4proxy.cpp
index e26c51b473..d4f342c50e 100644
--- a/src/qml/jsruntime/qv4proxy.cpp
+++ b/src/qml/jsruntime/qv4proxy.cpp
@@ -48,6 +48,7 @@
using namespace QV4;
DEFINE_OBJECT_VTABLE(ProxyObject);
+DEFINE_OBJECT_VTABLE(ProxyFunctionObject);
void Heap::ProxyObject::init(const QV4::Object *target, const QV4::Object *handler)
{
@@ -57,6 +58,18 @@ void Heap::ProxyObject::init(const QV4::Object *target, const QV4::Object *handl
this->handler.set(e, handler->d());
}
+void Heap::ProxyFunctionObject::init(const QV4::FunctionObject *target, const QV4::Object *handler)
+{
+ ExecutionEngine *e = internalClass->engine;
+ FunctionObject::init(e->rootContext());
+ this->target.set(e, target->d());
+ this->handler.set(e, handler->d());
+
+ if (!target->isConstructor())
+ jsConstruct = nullptr;
+}
+
+
ReturnedValue ProxyObject::virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty)
{
Scope scope(m);
@@ -631,15 +644,68 @@ OwnPropertyKeyIterator *ProxyObject::virtualOwnPropertyKeys(const Object *m)
}
-//ReturnedValue ProxyObject::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *)
-//{
+ReturnedValue ProxyFunctionObject::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget)
+{
+ Scope scope(f);
+ const ProxyObject *o = static_cast<const ProxyObject *>(f);
+ if (!o->d()->handler)
+ return scope.engine->throwTypeError();
-//}
+ ScopedFunctionObject target(scope, o->d()->target);
+ Q_ASSERT(target);
+ ScopedObject handler(scope, o->d()->handler);
+ ScopedString name(scope, scope.engine->newString(QStringLiteral("construct")));
+ ScopedValue trap(scope, handler->get(name));
-//ReturnedValue ProxyObject::call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
-//{
+ if (scope.hasException())
+ return Encode::undefined();
+ if (trap->isNullOrUndefined()) {
+ Q_ASSERT(target->isConstructor());
+ return target->callAsConstructor(argv, argc, newTarget);
+ }
+ if (!trap->isFunctionObject())
+ return scope.engine->throwTypeError();
-//}
+ ScopedFunctionObject trapFunction(scope, trap);
+ Value *arguments = scope.alloc(3);
+ arguments[0] = target;
+ arguments[1] = scope.engine->newArrayObject(argv, argc);
+ arguments[2] = newTarget ? *newTarget : Primitive::undefinedValue();
+ ScopedObject result(scope, trapFunction->call(handler, arguments, 3));
+
+ if (!result)
+ return scope.engine->throwTypeError();
+ return result->asReturnedValue();
+}
+
+ReturnedValue ProxyFunctionObject::virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(f);
+
+ const ProxyObject *o = static_cast<const ProxyObject *>(f);
+ if (!o->d()->handler)
+ return scope.engine->throwTypeError();
+
+ ScopedFunctionObject target(scope, o->d()->target);
+ Q_ASSERT(target);
+ ScopedObject handler(scope, o->d()->handler);
+ ScopedString name(scope, scope.engine->newString(QStringLiteral("apply")));
+ ScopedValue trap(scope, handler->get(name));
+
+ if (scope.hasException())
+ return Encode::undefined();
+ if (trap->isNullOrUndefined())
+ return target->call(thisObject, argv, argc);
+ if (!trap->isFunctionObject())
+ return scope.engine->throwTypeError();
+
+ ScopedFunctionObject trapFunction(scope, trap);
+ Value *arguments = scope.alloc(3);
+ arguments[0] = target;
+ arguments[1] = thisObject ? *thisObject : Primitive::undefinedValue();
+ arguments[2] = scope.engine->newArrayObject(argv, argc);
+ return trapFunction->call(handler, arguments, 3);
+}
DEFINE_OBJECT_VTABLE(Proxy);
@@ -668,8 +734,10 @@ ReturnedValue Proxy::virtualCallAsConstructor(const FunctionObject *f, const Val
if (!phandler->d()->handler)
return scope.engine->throwTypeError();
- ScopedObject o(scope, scope.engine->memoryManager->allocate<ProxyObject>(target, handler));
- return o->asReturnedValue();
+ const FunctionObject *targetFunction = target->as<FunctionObject>();
+ if (targetFunction)
+ return scope.engine->memoryManager->allocate<ProxyFunctionObject>(targetFunction, handler)->asReturnedValue();
+ return scope.engine->memoryManager->allocate<ProxyObject>(target, handler)->asReturnedValue();
}
ReturnedValue Proxy::virtualCall(const FunctionObject *f, const Value *, const Value *, int)
@@ -683,6 +751,7 @@ ReturnedValue Proxy::method_revocable(const FunctionObject *f, const Value *, co
ScopedObject proxy(scope, Proxy::virtualCallAsConstructor(f, argv, argc, f));
if (scope.hasException())
return Encode::undefined();
+ Q_ASSERT(proxy);
ScopedString revoke(scope, scope.engine->newString(QStringLiteral("revoke")));
ScopedFunctionObject revoker(scope, createBuiltinFunction(scope.engine, revoke, method_revoke, 0));
@@ -698,8 +767,9 @@ ReturnedValue Proxy::method_revocable(const FunctionObject *f, const Value *, co
ReturnedValue Proxy::method_revoke(const FunctionObject *f, const Value *, const Value *, int)
{
Scope scope(f);
- Scoped<ProxyObject> proxy(scope, f->get(scope.engine->symbol_revokableProxy()));
- Q_ASSERT(proxy);
+ ScopedObject o(scope, f->get(scope.engine->symbol_revokableProxy()));
+ Q_ASSERT(o);
+ ProxyObject *proxy = o->cast<ProxyObject>();
proxy->d()->target.set(scope.engine, nullptr);
proxy->d()->handler.set(scope.engine, nullptr);
diff --git a/src/qml/jsruntime/qv4proxy_p.h b/src/qml/jsruntime/qv4proxy_p.h
index bad4d040c7..7c10b91b13 100644
--- a/src/qml/jsruntime/qv4proxy_p.h
+++ b/src/qml/jsruntime/qv4proxy_p.h
@@ -63,12 +63,16 @@ namespace Heap {
Member(class, Pointer, Object *, target) \
Member(class, Pointer, Object *, handler)
-DECLARE_HEAP_OBJECT(ProxyObject, Object) {
+DECLARE_HEAP_OBJECT(ProxyObject, FunctionObject) {
DECLARE_MARKOBJECTS(ProxyObject)
void init(const QV4::Object *target, const QV4::Object *handler);
};
+struct ProxyFunctionObject : ProxyObject {
+ void init(const QV4::FunctionObject *target, const QV4::Object *handler);
+};
+
#define ProxyMembers(class, Member) \
Member(class, Pointer, Symbol *, revokableProxySymbol) \
@@ -80,10 +84,21 @@ DECLARE_HEAP_OBJECT(Proxy, FunctionObject) {
}
-struct ProxyObject: Object {
+/*
+ * The inheritance from FunctionObject is a hack. Regular proxy objects are no function objects.
+ * But this helps implement the proxy for function objects, where we need this and thus gives us
+ * all the virtual methods from ProxyObject without having to duplicate them.
+ *
+ * But it does require a few hacks to make sure we don't recognize regular proxy objects as function
+ * objects in the runtime.
+ */
+struct ProxyObject : FunctionObject {
V4_OBJECT2(ProxyObject, Object)
Q_MANAGED_TYPE(ProxyObject)
V4_INTERNALCLASS(ProxyObject)
+ enum {
+ IsFunctionObject = false
+ };
static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
static bool virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver);
@@ -96,10 +111,18 @@ struct ProxyObject: Object {
static Heap::Object *virtualGetPrototypeOf(const Managed *);
static bool virtualSetPrototypeOf(Managed *, const Object *);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m);
+};
- // those might require a second proxy object that derives from FunctionObject...
-// static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *);
-// static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
+struct ProxyFunctionObject : ProxyObject {
+ V4_OBJECT2(ProxyFunctionObject, FunctionObject)
+ Q_MANAGED_TYPE(ProxyObject)
+ V4_INTERNALCLASS(ProxyFunctionObject)
+ enum {
+ IsFunctionObject = true
+ };
+
+ static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *);
+ static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
};
struct Proxy : FunctionObject
diff --git a/src/qml/jsruntime/qv4reflect.cpp b/src/qml/jsruntime/qv4reflect.cpp
index 90c39f7c37..3dc0956e0c 100644
--- a/src/qml/jsruntime/qv4reflect.cpp
+++ b/src/qml/jsruntime/qv4reflect.cpp
@@ -103,7 +103,11 @@ ReturnedValue Reflect::method_apply(const FunctionObject *f, const Value *, cons
ReturnedValue Reflect::method_construct(const FunctionObject *f, const Value *, const Value *argv, int argc)
{
Scope scope(f);
- if (argc < 2 || !argv[0].isFunctionObject() || !argv[1].isObject())
+ if (argc < 2 || !argv[1].isObject())
+ return scope.engine->throwTypeError();
+ const FunctionObject *target = argv[0].as<FunctionObject>();
+ const FunctionObject *newTarget = argc == 3 ? argv[2].as<FunctionObject>() : target;
+ if (!target || !target->isConstructor() || !newTarget || !newTarget->isConstructor())
return scope.engine->throwTypeError();
const Object *o = static_cast<const Object *>(argv + 1);
@@ -111,7 +115,7 @@ ReturnedValue Reflect::method_construct(const FunctionObject *f, const Value *,
if (scope.hasException())
return Encode::undefined();
- return static_cast<const FunctionObject &>(argv[0]).callAsConstructor(arguments.argv, arguments.argc);
+ return target->callAsConstructor(arguments.argv, arguments.argc, newTarget);
}
ReturnedValue Reflect::method_defineProperty(const FunctionObject *f, const Value *, const Value *argv, int argc)
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index dd33a9fc41..dd16110c28 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -765,26 +765,6 @@ ReturnedValue RegExpPrototype::method_get_source(const FunctionObject *f, const
return scope.engine->newString(re->toString())->asReturnedValue();
}
-static const FunctionObject *speciesConstructor(Scope &scope, const Object *o, const FunctionObject *defaultConstructor)
-{
- ScopedValue C(scope, o->get(scope.engine->id_constructor()));
- if (C->isUndefined())
- return defaultConstructor;
- const Object *c = C->objectValue();
- if (!c) {
- scope.engine->throwTypeError();
- return nullptr;
- }
- ScopedValue S(scope, c->get(scope.engine->symbol_species()));
- if (S->isNullOrUndefined())
- return defaultConstructor;
- if (!S->isFunctionObject()) {
- scope.engine->throwTypeError();
- return nullptr;
- }
- return static_cast<const FunctionObject *>(S.ptr);
-}
-
ReturnedValue RegExpPrototype::method_split(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(f);
@@ -805,7 +785,7 @@ ReturnedValue RegExpPrototype::method_split(const FunctionObject *f, const Value
flags = scope.engine->newString(flagsString + QLatin1Char('y'));
bool unicodeMatching = flagsString.contains(QLatin1Char('u'));
- const FunctionObject *C = speciesConstructor(scope, rx, scope.engine->regExpCtor());
+ const FunctionObject *C = rx->speciesConstructor(scope, scope.engine->regExpCtor());
if (!C)
return Encode::undefined();
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 82e1284289..9180108a0c 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1550,8 +1550,9 @@ ReturnedValue Runtime::method_createClass(ExecutionEngine *engine, int classInde
if (superClass.isNull()) {
protoParent = Encode::null();
} else {
+ const FunctionObject *superFunction = superClass.as<FunctionObject>();
// ### check that the heritage object is a constructor
- if (!superClass.isFunctionObject())
+ if (!superFunction || !superFunction->isConstructor())
return engine->throwTypeError(QStringLiteral("The superclass is not a function object."));
const FunctionObject *s = static_cast<const FunctionObject *>(&superClass);
ScopedValue result(scope, s->get(scope.engine->id_prototype()));
diff --git a/src/qml/jsruntime/qv4symbol.cpp b/src/qml/jsruntime/qv4symbol.cpp
index bdefe1eb9e..d5ae094e1f 100644
--- a/src/qml/jsruntime/qv4symbol.cpp
+++ b/src/qml/jsruntime/qv4symbol.cpp
@@ -80,6 +80,11 @@ ReturnedValue QV4::SymbolCtor::virtualCall(const QV4::FunctionObject *f, const Q
return Symbol::create(scope.engine, desc)->asReturnedValue();
}
+ReturnedValue SymbolCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *)
+{
+ return f->engine()->throwTypeError(QStringLiteral("Symbol can't be used together with |new|."));
+}
+
ReturnedValue SymbolCtor::method_for(const FunctionObject *f, const Value *, const Value *argv, int argc)
{
Scope scope(f);
diff --git a/src/qml/jsruntime/qv4symbol_p.h b/src/qml/jsruntime/qv4symbol_p.h
index cb60f748de..c7e12b512b 100644
--- a/src/qml/jsruntime/qv4symbol_p.h
+++ b/src/qml/jsruntime/qv4symbol_p.h
@@ -83,6 +83,7 @@ struct SymbolCtor : FunctionObject
V4_OBJECT2(SymbolCtor, FunctionObject)
static ReturnedValue virtualCall(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv, int argc, const Value *newTarget);
static ReturnedValue method_for(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_keyFor(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index bdede94d46..456a577b52 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -43,6 +43,7 @@
#include "qv4string_p.h"
#include "qv4jscall_p.h"
#include "qv4symbol_p.h"
+#include "qv4runtime_p.h"
#include <cmath>
@@ -56,16 +57,31 @@ DEFINE_OBJECT_VTABLE(TypedArray);
Q_STATIC_ASSERT((int)ExecutionEngine::NTypedArrayTypes == (int)Heap::TypedArray::NTypes);
+static inline int toInt32(Value v)
+{
+ Q_ASSERT(v.isNumber());
+ if (v.isInteger())
+ return v.integerValue();
+ return Double::toInt32(v.doubleValue());
+}
+
+static inline double toDouble(Value v)
+{
+ Q_ASSERT(v.isNumber());
+ if (v.isInteger())
+ return v.integerValue();
+ return v.doubleValue();
+}
+
ReturnedValue Int8ArrayRead(const char *data, int index)
{
return Encode((int)(signed char)data[index]);
}
-void Int8ArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value)
+void Int8ArrayWrite(char *data, int index, const Value &value)
{
- signed char v = (signed char)value.toUInt32();
- if (e->hasException)
- return;
+ int n = toInt32(value);
+ signed char v = static_cast<signed char>(n);
data[index] = v;
}
@@ -74,23 +90,22 @@ ReturnedValue UInt8ArrayRead(const char *data, int index)
return Encode((int)(unsigned char)data[index]);
}
-void UInt8ArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value)
+void UInt8ArrayWrite(char *data, int index, const Value &value)
{
- unsigned char v = (unsigned char)value.toUInt32();
- if (e->hasException)
- return;
+ int n = toInt32(value);
+ unsigned char v = static_cast<unsigned char>(uint(n));
data[index] = v;
}
-void UInt8ClampedArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value)
+void UInt8ClampedArrayWrite(char *data, int index, const Value &value)
{
+ Q_ASSERT(value.isNumber());
if (value.isInteger()) {
data[index] = (char)(unsigned char)qBound(0, value.integerValue(), 255);
return;
}
- double d = value.toNumber();
- if (e->hasException)
- return;
+ Q_ASSERT(value.isDouble());
+ double d = value.doubleValue();
// ### is there a way to optimise this?
if (d <= 0 || std::isnan(d)) {
data[index] = 0;
@@ -122,11 +137,10 @@ ReturnedValue Int16ArrayRead(const char *data, int index)
return Encode((int)*(const short *)(data + index));
}
-void Int16ArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value)
+void Int16ArrayWrite(char *data, int index, const Value &value)
{
- short v = (short)value.toInt32();
- if (e->hasException)
- return;
+ int n = toInt32(value);
+ short v = static_cast<short>(n);
*(short *)(data + index) = v;
}
@@ -135,11 +149,10 @@ ReturnedValue UInt16ArrayRead(const char *data, int index)
return Encode((int)*(const unsigned short *)(data + index));
}
-void UInt16ArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value)
+void UInt16ArrayWrite(char *data, int index, const Value &value)
{
- unsigned short v = (unsigned short)value.toInt32();
- if (e->hasException)
- return;
+ int n = toInt32(value);
+ unsigned short v = static_cast<unsigned short>(n);
*(unsigned short *)(data + index) = v;
}
@@ -148,11 +161,9 @@ ReturnedValue Int32ArrayRead(const char *data, int index)
return Encode(*(const int *)(data + index));
}
-void Int32ArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value)
+void Int32ArrayWrite(char *data, int index, const Value &value)
{
- int v = (int)value.toInt32();
- if (e->hasException)
- return;
+ int v = toInt32(value);
*(int *)(data + index) = v;
}
@@ -161,11 +172,10 @@ ReturnedValue UInt32ArrayRead(const char *data, int index)
return Encode(*(const unsigned int *)(data + index));
}
-void UInt32ArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value)
+void UInt32ArrayWrite(char *data, int index, const Value &value)
{
- unsigned int v = (unsigned int)value.toUInt32();
- if (e->hasException)
- return;
+ int n = toInt32(value);
+ unsigned v = static_cast<unsigned>(n);
*(unsigned int *)(data + index) = v;
}
@@ -174,11 +184,9 @@ ReturnedValue Float32ArrayRead(const char *data, int index)
return Encode(*(const float *)(data + index));
}
-void Float32ArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value)
+void Float32ArrayWrite(char *data, int index, const Value &value)
{
- float v = value.toNumber();
- if (e->hasException)
- return;
+ float v = toDouble(value);
*(float *)(data + index) = v;
}
@@ -187,11 +195,9 @@ ReturnedValue Float64ArrayRead(const char *data, int index)
return Encode(*(const double *)(data + index));
}
-void Float64ArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value)
+void Float64ArrayWrite(char *data, int index, const Value &value)
{
- double v = value.toNumber();
- if (e->hasException)
- return;
+ double v = toDouble(value);
*(double *)(data + index) = v;
}
@@ -276,7 +282,7 @@ ReturnedValue TypedArrayCtor::virtualCallAsConstructor(const FunctionObject *f,
for (uint i = 0; i < l; ++i) {
Primitive val;
val.setRawValue(read(src, i*srcElementSize));
- write(scope.engine, dest, i*destElementSize, val);
+ write(dest, i*destElementSize, val);
}
}
@@ -345,7 +351,10 @@ ReturnedValue TypedArrayCtor::virtualCallAsConstructor(const FunctionObject *f,
ScopedValue val(scope);
while (idx < l) {
val = o->get(idx);
- array->d()->type->write(scope.engine, b, 0, val);
+ val = val->convertedToNumber();
+ if (scope.engine->hasException)
+ return Encode::undefined();
+ array->d()->type->write(b, 0, val);
if (scope.engine->hasException)
return Encode::undefined();
++idx;
@@ -383,6 +392,8 @@ ReturnedValue TypedArray::virtualGet(const Managed *m, PropertyKey id, const Val
uint index = id.asArrayIndex();
Scope scope(static_cast<const Object *>(m)->engine());
Scoped<TypedArray> a(scope, static_cast<const TypedArray *>(m));
+ if (a->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
uint bytesPerElement = a->d()->type->bytesPerElement;
uint byteOffset = a->d()->byteOffset + index * bytesPerElement;
@@ -408,13 +419,18 @@ bool TypedArray::virtualPut(Managed *m, PropertyKey id, const Value &value, Valu
Scope scope(v4);
Scoped<TypedArray> a(scope, static_cast<TypedArray *>(m));
+ if (a->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
uint bytesPerElement = a->d()->type->bytesPerElement;
uint byteOffset = a->d()->byteOffset + index * bytesPerElement;
if (byteOffset + bytesPerElement > (uint)a->d()->buffer->byteLength())
return false;
- a->d()->type->write(scope.engine, a->d()->buffer->data->data(), byteOffset, value);
+ Value v = Primitive::fromReturnedValue(value.convertedToNumber());
+ if (scope.hasException() || a->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+ a->d()->type->write(a->d()->buffer->data->data(), byteOffset, v);
return true;
}
@@ -450,6 +466,9 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_get_byteLength(const Function
if (!v)
return v4->throwTypeError();
+ if (v->d()->buffer->isDetachedBuffer())
+ return Encode(0);
+
return Encode(v->d()->byteLength);
}
@@ -460,6 +479,9 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_get_byteOffset(const Function
if (!v)
return v4->throwTypeError();
+ if (v->d()->buffer->isDetachedBuffer())
+ return Encode(0);
+
return Encode(v->d()->byteOffset);
}
@@ -470,41 +492,723 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_get_length(const FunctionObje
if (!v)
return v4->throwTypeError();
+ if (v->d()->buffer->isDetachedBuffer())
+ return Encode(0);
+
return Encode(v->d()->byteLength/v->d()->type->bytesPerElement);
}
+ReturnedValue IntrinsicTypedArrayPrototype::method_copyWithin(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(f);
+ Scoped<TypedArray> O(scope, thisObject);
+ if (!O || O->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ if (!argc)
+ return O->asReturnedValue();
+
+ qint64 len = static_cast<uint>(O->length());
+
+ qint64 to = static_cast<qint64>(argv[0].toInteger());
+ if (to < 0)
+ to = qMax(len + to, 0ll);
+ else
+ to = qMin(to, len);
+
+ qint64 from = (argc > 1) ? static_cast<qint64>(argv[1].toInteger()) : 0ll;
+ if (from < 0)
+ from = qMax(len + from, 0ll);
+ else
+ from = qMin(from, len);
+
+ double fend = argv[2].toInteger();
+ if (fend > len)
+ fend = len;
+ qint64 end = (argc > 2 && !argv[2].isUndefined()) ? static_cast<qint64>(fend) : len;
+ if (end < 0)
+ end = qMax(len + end, 0ll);
+ else
+ end = qMin(end, len);
+
+ qint64 count = qMin(end - from, len - to);
+
+ if (count <= 0)
+ return O->asReturnedValue();
+
+ if (O->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ if (from != to) {
+ int elementSize = O->d()->type->bytesPerElement;
+ char *data = O->d()->buffer->data->data() + O->d()->byteOffset;
+ memmove(data + to*elementSize, data + from*elementSize, count*elementSize);
+ }
+
+ return O->asReturnedValue();
+}
+
ReturnedValue IntrinsicTypedArrayPrototype::method_entries(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
Scope scope(b);
- Scoped<TypedArray> O(scope, thisObject);
- if (!O)
- THROW_TYPE_ERROR();
+ Scoped<TypedArray> v(scope, thisObject);
+ if (!v || v->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
- Scoped<ArrayIteratorObject> ao(scope, scope.engine->newArrayIteratorObject(O));
+ Scoped<ArrayIteratorObject> ao(scope, scope.engine->newArrayIteratorObject(v));
ao->d()->iterationKind = IteratorKind::KeyValueIteratorKind;
return ao->asReturnedValue();
}
-ReturnedValue IntrinsicTypedArrayPrototype::method_keys(const FunctionObject *b, const Value *thisObject, const Value *, int)
+ReturnedValue IntrinsicTypedArrayPrototype::method_every(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
- Scoped<TypedArray> O(scope, thisObject);
- if (!O)
+ Scoped<TypedArray> v(scope, thisObject);
+ if (!v || v->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint len = v->length();
+
+ if (!argc || !argv->isFunctionObject())
+ THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
+
+ ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
+ ScopedValue r(scope);
+ Value *arguments = scope.alloc(3);
+
+ const char *data = v->d()->buffer->data->data();
+ uint bytesPerElement = v->d()->type->bytesPerElement;
+ uint byteOffset = v->d()->byteOffset;
+
+ bool ok = true;
+ for (uint k = 0; ok && k < len; ++k) {
+ if (v->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ arguments[0] = v->d()->type->read(data, byteOffset + k * bytesPerElement);
+
+ arguments[1] = Primitive::fromDouble(k);
+ arguments[2] = v;
+ r = callback->call(that, arguments, 3);
+ ok = r->toBoolean();
+ }
+ return Encode(ok);
+}
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_fill(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ Scoped<TypedArray> v(scope, thisObject);
+ if (!v || v->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint len = v->length();
+ double dlen = len;
+ double relativeStart = argc > 1 ? argv[1].toInteger() : 0.;
+ double relativeEnd = len;
+ if (argc > 2 && !argv[2].isUndefined())
+ relativeEnd = argv[2].toInteger();
+
+ uint k = 0;
+ uint fin = 0;
+
+ if (relativeStart < 0) {
+ k = static_cast<uint>(std::max(len+relativeStart, 0.));
+ } else {
+ k = static_cast<uint>(std::min(relativeStart, dlen));
+ }
+
+ if (relativeEnd < 0) {
+ fin = static_cast<uint>(std::max(len + relativeEnd, 0.));
+ } else {
+ fin = static_cast<uint>(std::min(relativeEnd, dlen));
+ }
+
+ double val = argc ? argv[0].toNumber() : std::numeric_limits<double>::quiet_NaN();
+ Value value = Primitive::fromDouble(val);
+ if (scope.hasException() || v->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ char *data = v->d()->buffer->data->data();
+ uint bytesPerElement = v->d()->type->bytesPerElement;
+ uint byteOffset = v->d()->byteOffset;
+
+ while (k < fin) {
+ v->d()->type->write(data, byteOffset + k * bytesPerElement, value);
+ k++;
+ }
+
+ return v.asReturnedValue();
+}
+
+static TypedArray *typedArraySpeciesCreate(Scope &scope, const TypedArray *instance, uint len)
+{
+ const FunctionObject *constructor = instance->speciesConstructor(scope, scope.engine->typedArrayCtors + instance->d()->arrayType);
+ if (!constructor) {
+ scope.engine->throwTypeError();
+ return nullptr;
+ }
+
+ Value *arguments = scope.alloc(1);
+ arguments[0] = Encode(len);
+ Scoped<TypedArray> a(scope, constructor->callAsConstructor(arguments, 1));
+ if (!a || a->d()->buffer->isDetachedBuffer() || a->length() < len) {
+ scope.engine->throwTypeError();
+ return nullptr;
+ }
+ return a;
+}
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_filter(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ Scoped<TypedArray> instance(scope, thisObject);
+ if (!instance || instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint len = instance->length();
+
+ if (!argc || !argv->isFunctionObject())
+ THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
+
+ ScopedValue selected(scope);
+ ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
+ Value *arguments = scope.alloc(3);
+ Value *list = arguments;
+
+ uint to = 0;
+ for (uint k = 0; k < len; ++k) {
+ if (instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+ bool exists;
+ arguments[0] = instance->get(k, &exists);
+ if (!exists)
+ continue;
+
+ arguments[1] = Primitive::fromDouble(k);
+ arguments[2] = instance;
+ selected = callback->call(that, arguments, 3);
+ if (selected->toBoolean()) {
+ ++arguments;
+ scope.alloc(1);
+ ++to;
+ }
+ }
+
+ TypedArray *a = typedArraySpeciesCreate(scope, instance, to);
+ if (!a)
+ return Encode::undefined();
+
+ for (uint i = 0; i < to; ++i)
+ a->put(i, list[i]);
+
+ return a->asReturnedValue();
+}
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_find(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ Scoped<TypedArray> v(scope, thisObject);
+ if (!v || v->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint len = v->length();
+
+ if (!argc || !argv[0].isFunctionObject())
THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
+
+ ScopedValue result(scope);
+ Value *arguments = scope.alloc(3);
+
+ ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
- Scoped<ArrayIteratorObject> ao(scope, scope.engine->newArrayIteratorObject(O));
+ for (uint k = 0; k < len; ++k) {
+ if (v->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+ arguments[0] = v->get(k);
+ CHECK_EXCEPTION();
+
+ arguments[1] = Primitive::fromDouble(k);
+ arguments[2] = v;
+ result = callback->call(that, arguments, 3);
+
+ CHECK_EXCEPTION();
+ if (result->toBoolean())
+ return arguments[0].asReturnedValue();
+ }
+
+ RETURN_UNDEFINED();
+}
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_findIndex(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ Scoped<TypedArray> v(scope, thisObject);
+ if (!v || v->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint len = v->length();
+
+ if (!argc || !argv[0].isFunctionObject())
+ THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
+
+ ScopedValue result(scope);
+ Value *arguments = scope.alloc(3);
+
+ ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
+
+ for (uint k = 0; k < len; ++k) {
+ if (v->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+ arguments[0] = v->get(k);
+ CHECK_EXCEPTION();
+
+ arguments[1] = Primitive::fromDouble(k);
+ arguments[2] = v;
+ result = callback->call(that, arguments, 3);
+
+ CHECK_EXCEPTION();
+ if (result->toBoolean())
+ return Encode(k);
+ }
+
+ return Encode(-1);
+}
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_forEach(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ Scoped<TypedArray> v(scope, thisObject);
+ if (!v || v->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint len = v->length();
+
+ if (!argc || !argv->isFunctionObject())
+ THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
+
+ ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
+ Value *arguments = scope.alloc(3);
+
+ for (uint k = 0; k < len; ++k) {
+ if (v->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+ bool exists;
+ arguments[0] = v->get(k, &exists);
+ if (!exists)
+ continue;
+
+ arguments[1] = Primitive::fromDouble(k);
+ arguments[2] = v;
+ callback->call(that, arguments, 3);
+ }
+ RETURN_UNDEFINED();
+}
+
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_includes(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ Scoped<TypedArray> v(scope, thisObject);
+ if (!v || v->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint len = v->length();
+ if (len == 0) {
+ return Encode(false);
+ }
+
+ double n = 0;
+ if (argc > 1 && !argv[1].isUndefined()) {
+ n = argv[1].toInteger();
+ }
+
+ double k = 0;
+ if (n >= 0) {
+ k = n;
+ } else {
+ k = len + n;
+ if (k < 0) {
+ k = 0;
+ }
+ }
+
+ while (k < len) {
+ ScopedValue val(scope, v->get(k));
+ if (val->sameValueZero(argv[0])) {
+ return Encode(true);
+ }
+ k++;
+ }
+
+ return Encode(false);
+}
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_indexOf(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ Scoped<TypedArray> v(scope, thisObject);
+ if (!v || v->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint len = v->length();
+ if (!len)
+ return Encode(-1);
+
+ ScopedValue searchValue(scope, argc ? argv[0] : Primitive::undefinedValue());
+ uint fromIndex = 0;
+
+ if (argc >= 2) {
+ double f = argv[1].toInteger();
+ CHECK_EXCEPTION();
+ if (f >= len)
+ return Encode(-1);
+ if (f < 0)
+ f = qMax(len + f, 0.);
+ fromIndex = (uint) f;
+ }
+
+ if (v->isStringObject()) {
+ ScopedValue value(scope);
+ for (uint k = fromIndex; k < len; ++k) {
+ bool exists;
+ value = v->get(k, &exists);
+ if (exists && RuntimeHelpers::strictEqual(value, searchValue))
+ return Encode(k);
+ }
+ return Encode(-1);
+ }
+
+ ScopedValue value(scope);
+
+ for (uint i = fromIndex; i < len; ++i) {
+ bool exists;
+ value = v->get(i, &exists);
+ CHECK_EXCEPTION();
+ if (exists && RuntimeHelpers::strictEqual(value, searchValue))
+ return Encode(i);
+ }
+ return Encode(-1);
+}
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_join(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ Scoped<TypedArray> v(scope, thisObject);
+ if (!v || v->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint len = v->length();
+
+ ScopedValue arg(scope, argc ? argv[0] : Primitive::undefinedValue());
+
+ QString r4;
+ if (arg->isUndefined())
+ r4 = QStringLiteral(",");
+ else
+ r4 = arg->toQString();
+
+ const quint32 r2 = len;
+
+ if (!r2)
+ return Encode(scope.engine->newString());
+
+ QString R;
+
+ //
+ // crazy!
+ //
+ ScopedString name(scope, scope.engine->newString(QStringLiteral("0")));
+ ScopedValue r6(scope, v->get(name));
+ if (!r6->isNullOrUndefined())
+ R = r6->toQString();
+
+ ScopedValue r12(scope);
+ for (quint32 k = 1; k < r2; ++k) {
+ R += r4;
+
+ name = Primitive::fromDouble(k).toString(scope.engine);
+ r12 = v->get(name);
+ CHECK_EXCEPTION();
+
+ if (!r12->isNullOrUndefined())
+ R += r12->toQString();
+ }
+
+ return Encode(scope.engine->newString(R));
+}
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_keys(const FunctionObject *b, const Value *thisObject, const Value *, int)
+{
+ Scope scope(b);
+ Scoped<TypedArray> v(scope, thisObject);
+ if (!v || v->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ Scoped<ArrayIteratorObject> ao(scope, scope.engine->newArrayIteratorObject(v));
ao->d()->iterationKind = IteratorKind::KeyIteratorKind;
return ao->asReturnedValue();
}
-ReturnedValue IntrinsicTypedArrayPrototype::method_values(const FunctionObject *b, const Value *thisObject, const Value *, int)
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_lastIndexOf(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
- Scoped<TypedArray> O(scope, thisObject);
- if (!O)
+ Scoped<TypedArray> instance(scope, thisObject);
+ if (!instance || instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint len = instance->length();
+ if (!len)
+ return Encode(-1);
+
+ ScopedValue searchValue(scope);
+ uint fromIndex = len;
+
+ if (argc >= 1)
+ searchValue = argv[0];
+ else
+ searchValue = Primitive::undefinedValue();
+
+ if (argc >= 2) {
+ double f = argv[1].toInteger();
+ CHECK_EXCEPTION();
+ if (f > 0)
+ f = qMin(f, (double)(len - 1));
+ else if (f < 0) {
+ f = len + f;
+ if (f < 0)
+ return Encode(-1);
+ }
+ fromIndex = (uint) f + 1;
+ }
+
+ ScopedValue value(scope);
+ for (uint k = fromIndex; k > 0;) {
+ --k;
+ bool exists;
+ value = instance->get(k, &exists);
+ if (exists && RuntimeHelpers::strictEqual(value, searchValue))
+ return Encode(k);
+ }
+ return Encode(-1);
+}
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_map(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ Scoped<TypedArray> instance(scope, thisObject);
+ if (!instance || instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint len = instance->length();
+
+ if (!argc || !argv->isFunctionObject())
THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
+
+ TypedArray *a = typedArraySpeciesCreate(scope, instance, len);
+ if (!a)
+ return Encode::undefined();
- Scoped<ArrayIteratorObject> ao(scope, scope.engine->newArrayIteratorObject(O));
+ ScopedValue v(scope);
+ ScopedValue mapped(scope);
+ ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
+ Value *arguments = scope.alloc(3);
+
+ for (uint k = 0; k < len; ++k) {
+ if (instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+ arguments[0] = instance->get(k);
+
+ arguments[1] = Primitive::fromDouble(k);
+ arguments[2] = instance;
+ mapped = callback->call(that, arguments, 3);
+ a->put(k, mapped);
+ }
+ return a->asReturnedValue();
+}
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_reduce(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ Scoped<TypedArray> instance(scope, thisObject);
+ if (!instance || instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint len = instance->length();
+
+ if (!argc || !argv->isFunctionObject())
+ THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
+
+ uint k = 0;
+ ScopedValue acc(scope);
+ ScopedValue v(scope);
+
+ if (argc > 1) {
+ acc = argv[1];
+ } else {
+ bool kPresent = false;
+ while (k < len && !kPresent) {
+ v = instance->get(k, &kPresent);
+ if (kPresent)
+ acc = v;
+ ++k;
+ }
+ if (!kPresent)
+ THROW_TYPE_ERROR();
+ }
+
+ Value *arguments = scope.alloc(4);
+
+ while (k < len) {
+ if (instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+ bool kPresent;
+ v = instance->get(k, &kPresent);
+ if (kPresent) {
+ arguments[0] = acc;
+ arguments[1] = v;
+ arguments[2] = Primitive::fromDouble(k);
+ arguments[3] = instance;
+ acc = callback->call(nullptr, arguments, 4);
+ }
+ ++k;
+ }
+ return acc->asReturnedValue();
+}
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_reduceRight(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ Scoped<TypedArray> instance(scope, thisObject);
+ if (!instance || instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint len = instance->length();
+
+ if (!argc || !argv->isFunctionObject())
+ THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
+
+ if (len == 0) {
+ if (argc == 1)
+ THROW_TYPE_ERROR();
+ return argv[1].asReturnedValue();
+ }
+
+ uint k = len;
+ ScopedValue acc(scope);
+ ScopedValue v(scope);
+ if (argc > 1) {
+ acc = argv[1];
+ } else {
+ bool kPresent = false;
+ while (k > 0 && !kPresent) {
+ v = instance->get(k - 1, &kPresent);
+ if (kPresent)
+ acc = v;
+ --k;
+ }
+ if (!kPresent)
+ THROW_TYPE_ERROR();
+ }
+
+ Value *arguments = scope.alloc(4);
+
+ while (k > 0) {
+ if (instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+ bool kPresent;
+ v = instance->get(k - 1, &kPresent);
+ if (kPresent) {
+ arguments[0] = acc;
+ arguments[1] = v;
+ arguments[2] = Primitive::fromDouble(k - 1);
+ arguments[3] = instance;
+ acc = callback->call(nullptr, arguments, 4);
+ }
+ --k;
+ }
+ return acc->asReturnedValue();
+}
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_reverse(const FunctionObject *b, const Value *thisObject, const Value *, int)
+{
+ Scope scope(b);
+ Scoped<TypedArray> instance(scope, thisObject);
+ if (!instance || instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint length = instance->length();
+
+ int lo = 0, hi = length - 1;
+
+ ScopedValue lval(scope);
+ ScopedValue hval(scope);
+ for (; lo < hi; ++lo, --hi) {
+ bool loExists, hiExists;
+ lval = instance->get(lo, &loExists);
+ hval = instance->get(hi, &hiExists);
+ Q_ASSERT(hiExists && loExists);
+ bool ok;
+ ok = instance->put(lo, hval);
+ Q_ASSERT(ok);
+ ok = instance->put(hi, lval);
+ Q_ASSERT(ok);
+ }
+ return instance->asReturnedValue();
+}
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_some(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ Scoped<TypedArray> instance(scope, thisObject);
+ if (!instance || instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint len = instance->length();
+
+ if (!argc || !argv->isFunctionObject())
+ THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
+
+ ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
+ ScopedValue result(scope);
+ Value *arguments = scope.alloc(3);
+
+ for (uint k = 0; k < len; ++k) {
+ if (instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+ bool exists;
+ arguments[0] = instance->get(k, &exists);
+ if (!exists)
+ continue;
+
+ arguments[1] = Primitive::fromDouble(k);
+ arguments[2] = instance;
+ result = callback->call(that, arguments, 3);
+ if (result->toBoolean())
+ return Encode(true);
+ }
+ return Encode(false);
+}
+
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_values(const FunctionObject *b, const Value *thisObject, const Value *, int)
+{
+ Scope scope(b);
+ Scoped<TypedArray> v(scope, thisObject);
+ if (!v || v->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ Scoped<ArrayIteratorObject> ao(scope, scope.engine->newArrayIteratorObject(v));
ao->d()->iterationKind = IteratorKind::ValueIteratorKind;
return ao->asReturnedValue();
}
@@ -550,7 +1254,12 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_set(const FunctionObject *b,
ScopedValue val(scope);
while (idx < l) {
val = o->get(idx);
- a->d()->type->write(scope.engine, b, 0, val);
+ if (scope.hasException())
+ return Encode::undefined();
+ val = val->convertedToNumber();
+ if (scope.hasException() || buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+ a->d()->type->write(b, 0, val);
if (scope.engine->hasException)
RETURN_UNDEFINED();
++idx;
@@ -591,7 +1300,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_set(const FunctionObject *b,
for (uint i = 0; i < l; ++i) {
Primitive val;
val.setRawValue(read(src, i*srcElementSize));
- write(scope.engine, dest, i*elementSize, val);
+ write(dest, i*elementSize, val);
}
if (srcCopy)
@@ -600,6 +1309,53 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_set(const FunctionObject *b,
RETURN_UNDEFINED();
}
+ReturnedValue IntrinsicTypedArrayPrototype::method_slice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ Scoped<TypedArray> instance(scope, thisObject);
+ if (!instance || instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint len = instance->length();
+
+ double s = (argc ? argv[0] : Primitive::undefinedValue()).toInteger();
+ uint start;
+ if (s < 0)
+ start = (uint)qMax(len + s, 0.);
+ else if (s > len)
+ start = len;
+ else
+ start = (uint) s;
+ uint end = len;
+ if (argc > 1 && !argv[1].isUndefined()) {
+ double e = argv[1].toInteger();
+ if (e < 0)
+ end = (uint)qMax(len + e, 0.);
+ else if (e > len)
+ end = len;
+ else
+ end = (uint) e;
+ }
+ uint count = start > end ? 0 : end - start;
+
+ TypedArray *a = typedArraySpeciesCreate(scope, instance, count);
+ if (!a)
+ return Encode::undefined();
+
+ ScopedValue v(scope);
+ uint n = 0;
+ for (uint i = start; i < end; ++i) {
+ if (instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+ v = instance->get(i);
+ if (a->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+ a->put(n, v);
+ ++n;
+ }
+ return a->asReturnedValue();
+}
+
ReturnedValue IntrinsicTypedArrayPrototype::method_subarray(const FunctionObject *builtin, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(builtin);
@@ -609,8 +1365,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_subarray(const FunctionObject
return scope.engine->throwTypeError();
Scoped<ArrayBuffer> buffer(scope, a->d()->buffer);
- if (!buffer || buffer->isDetachedBuffer())
- return scope.engine->throwTypeError();
+ Q_ASSERT(buffer);
int len = a->length();
double b = argc > 0 ? argv[0].toInteger() : 0;
@@ -630,7 +1385,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_subarray(const FunctionObject
int newLen = end - begin;
- ScopedFunctionObject constructor(scope, a->get(scope.engine->id_constructor()));
+ ScopedFunctionObject constructor(scope, a->speciesConstructor(scope, scope.engine->typedArrayCtors + a->d()->arrayType));
if (!constructor)
return scope.engine->throwTypeError();
@@ -638,7 +1393,42 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_subarray(const FunctionObject
arguments[0] = buffer;
arguments[1] = Encode(a->d()->byteOffset + begin*a->d()->type->bytesPerElement);
arguments[2] = Encode(newLen);
- return constructor->callAsConstructor(arguments, 3);
+ a = constructor->callAsConstructor(arguments, 3);
+ if (!a || a->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+ return a->asReturnedValue();
+}
+
+ReturnedValue IntrinsicTypedArrayPrototype::method_toLocaleString(const FunctionObject *b, const Value *thisObject, const Value *, int)
+{
+ Scope scope(b);
+ Scoped<TypedArray> instance(scope, thisObject);
+ if (!instance || instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+
+ uint len = instance->length();
+ const QString separator = QStringLiteral(",");
+
+ QString R;
+
+ ScopedValue v(scope);
+ ScopedString s(scope);
+
+ for (uint k = 0; k < len; ++k) {
+ if (instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+ if (k)
+ R += separator;
+
+ v = instance->get(k);
+ v = Runtime::method_callElement(scope.engine, v, *scope.engine->id_toLocaleString(), nullptr, 0);
+ s = v->toString(scope.engine);
+ if (scope.hasException())
+ return Encode::undefined();
+
+ R += s->toQString();
+ }
+ return scope.engine->newString(R)->asReturnedValue();
}
ReturnedValue IntrinsicTypedArrayPrototype::method_get_toStringTag(const FunctionObject *, const Value *thisObject, const Value *, int)
@@ -650,20 +1440,51 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_get_toStringTag(const Functio
return a->engine()->newString(QString::fromLatin1(a->d()->type->name))->asReturnedValue();
}
-ReturnedValue IntrinsicTypedArrayCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *)
+static bool validateTypedArray(const Object *o)
{
- return f->engine()->throwTypeError();
+ const TypedArray *a = o->as<TypedArray>();
+ if (!a)
+ return false;
+ if (a->d()->buffer->isDetachedBuffer())
+ return false;
+ return true;
}
-ReturnedValue IntrinsicTypedArrayCtor::virtualCall(const FunctionObject *f, const Value *, const Value *, int)
+ReturnedValue IntrinsicTypedArrayCtor::method_of(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
{
- return f->engine()->throwTypeError();
+ Scope scope(f);
+ int len = argc;
+ const Value *items = argv;
+ const FunctionObject *C = thisObject->as<FunctionObject>();
+ if (!C || !C->isConstructor())
+ return scope.engine->throwTypeError();
+
+ Value lenValue = Primitive::fromInt32(len);
+ ScopedObject newObj(scope, C->callAsConstructor(&lenValue, 1));
+ if (scope.hasException())
+ return Encode::undefined();
+ if (!::validateTypedArray(newObj))
+ return scope.engine->throwTypeError();
+ TypedArray *a = newObj->as<TypedArray>();
+ Q_ASSERT(a);
+ if (a->length() < static_cast<uint>(len))
+ return scope.engine->throwTypeError();
+
+ for (int k = 0; k < len; ++k) {
+ newObj->put(PropertyKey::fromArrayIndex(k), items[k]);
+ }
+ return newObj->asReturnedValue();
}
void IntrinsicTypedArrayPrototype::init(ExecutionEngine *engine, IntrinsicTypedArrayCtor *ctor)
{
+ Scope scope(engine);
ctor->defineReadonlyProperty(engine->id_prototype(), *this);
ctor->defineReadonlyConfigurableProperty(engine->id_length(), Primitive::fromInt32(0));
+ ScopedString s(scope, engine->newString(QStringLiteral("TypedArray")));
+ ctor->defineReadonlyConfigurableProperty(engine->id_name(), s);
+ s = scope.engine->newString(QStringLiteral("of"));
+ ctor->defineDefaultProperty(s, IntrinsicTypedArrayCtor::method_of);
ctor->addSymbolSpecies();
defineAccessorProperty(QStringLiteral("buffer"), method_get_buffer, nullptr);
@@ -671,12 +1492,31 @@ void IntrinsicTypedArrayPrototype::init(ExecutionEngine *engine, IntrinsicTypedA
defineAccessorProperty(QStringLiteral("byteOffset"), method_get_byteOffset, nullptr);
defineAccessorProperty(QStringLiteral("length"), method_get_length, nullptr);
+ defineDefaultProperty(QStringLiteral("copyWithin"), method_copyWithin, 2);
defineDefaultProperty(QStringLiteral("entries"), method_entries, 0);
+ defineDefaultProperty(QStringLiteral("every"), method_every, 1);
+ defineDefaultProperty(QStringLiteral("fill"), method_fill, 1);
+ defineDefaultProperty(QStringLiteral("filter"), method_filter, 1);
+ defineDefaultProperty(QStringLiteral("find"), method_find, 1);
+ defineDefaultProperty(QStringLiteral("findIndex"), method_findIndex, 1);
+ defineDefaultProperty(QStringLiteral("forEach"), method_forEach, 1);
+ defineDefaultProperty(QStringLiteral("includes"), method_includes, 1);
+ defineDefaultProperty(QStringLiteral("indexOf"), method_indexOf, 1);
+ defineDefaultProperty(QStringLiteral("join"), method_join, 1);
defineDefaultProperty(QStringLiteral("keys"), method_keys, 0);
+ defineDefaultProperty(QStringLiteral("lastIndexOf"), method_lastIndexOf, 1);
+ defineDefaultProperty(QStringLiteral("map"), method_map, 1);
+ defineDefaultProperty(QStringLiteral("reduce"), method_reduce, 1);
+ defineDefaultProperty(QStringLiteral("reduceRight"), method_reduceRight, 1);
+ defineDefaultProperty(QStringLiteral("reverse"), method_reverse, 0);
+ defineDefaultProperty(QStringLiteral("some"), method_some, 1);
defineDefaultProperty(QStringLiteral("set"), method_set, 1);
- defineDefaultProperty(QStringLiteral("subarray"), method_subarray, 0);
+ defineDefaultProperty(QStringLiteral("slice"), method_slice, 2);
+ defineDefaultProperty(QStringLiteral("subarray"), method_subarray, 2);
+ defineDefaultProperty(engine->id_toLocaleString(), method_toLocaleString, 0);
+ ScopedObject f(scope, engine->arrayPrototype()->get(engine->id_toString()));
+ defineDefaultProperty(engine->id_toString(), f);
- Scope scope(engine);
ScopedString valuesString(scope, engine->newIdentifier(QStringLiteral("values")));
ScopedObject values(scope, FunctionObject::createBuiltinFunction(engine, valuesString, method_values, 0));
defineDefaultProperty(QStringLiteral("values"), values);
diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h
index 967d3235b2..11b3a0dabf 100644
--- a/src/qml/jsruntime/qv4typedarray_p.h
+++ b/src/qml/jsruntime/qv4typedarray_p.h
@@ -61,7 +61,7 @@ namespace QV4 {
struct ArrayBuffer;
typedef ReturnedValue (*TypedArrayRead)(const char *data, int index);
-typedef void (*TypedArrayWrite)(ExecutionEngine *engine, char *data, int index, const Value &value);
+typedef void (*TypedArrayWrite)(char *data, int index, const Value &value);
struct TypedArrayOperations {
int bytesPerElement;
@@ -148,8 +148,9 @@ struct IntrinsicTypedArrayCtor: FunctionObject
{
V4_OBJECT2(IntrinsicTypedArrayCtor, FunctionObject)
- static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *);
- static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
+ static constexpr VTable::Call virtualCall = nullptr;
+
+ static ReturnedValue method_of(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
struct TypedArrayCtor: FunctionObject
@@ -172,11 +173,29 @@ struct IntrinsicTypedArrayPrototype : Object
static ReturnedValue method_get_byteOffset(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_get_length(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_entries(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_fill(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_find(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_forEach(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_indexOf(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_keys(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_lastIndexOf(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_reduce(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_reverse(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_values(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_set(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_subarray(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_get_toStringTag(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 6a6df3eb6d..e4be6b99dd 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -408,6 +408,7 @@ public:
}
static bool toBooleanImpl(Value val);
double toInteger() const;
+ inline ReturnedValue convertedToNumber() const;
inline double toNumber() const;
static double toNumberImpl(Value v);
double toNumberImpl() const { return toNumberImpl(*this); }
@@ -554,6 +555,15 @@ inline double Value::toNumber() const
return toNumberImpl();
}
+inline ReturnedValue Value::convertedToNumber() const
+{
+ if (isInteger() || isDouble())
+ return asReturnedValue();
+ Value v;
+ v.setDouble(toNumberImpl());
+ return v.asReturnedValue();
+}
+
inline
ReturnedValue Heap::Base::asReturnedValue() const
{
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 575cad70e4..aed3fce6b1 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -949,8 +949,8 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine,
MOTH_END_INSTR(ConvertThisToObject)
MOTH_BEGIN_INSTR(LoadSuperConstructor)
- const Value *f = &stack[CallData::Function];
- if (!f->isFunctionObject()) {
+ const FunctionObject *f = stack[CallData::Function].as<FunctionObject>();
+ if (!f || !f->isConstructor()) {
engine->throwTypeError();
} else {
acc = static_cast<const Object *>(f)->getPrototypeOf()->asReturnedValue();
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 42c72e0447..f9f13e7b7c 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -77,7 +77,7 @@ static bool isLocaleObject(const QV4::Value &val)
void QQmlDateExtension::registerExtension(QV4::ExecutionEngine *engine)
{
- engine->datePrototype()->defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString);
+ engine->datePrototype()->defineDefaultProperty(engine->id_toLocaleString(), method_toLocaleString);
engine->datePrototype()->defineDefaultProperty(QStringLiteral("toLocaleTimeString"), method_toLocaleTimeString);
engine->datePrototype()->defineDefaultProperty(QStringLiteral("toLocaleDateString"), method_toLocaleDateString);
engine->dateCtor()->defineDefaultProperty(QStringLiteral("fromLocaleString"), method_fromLocaleString);
@@ -360,7 +360,7 @@ ReturnedValue QQmlDateExtension::method_timeZoneUpdated(const QV4::FunctionObjec
void QQmlNumberExtension::registerExtension(QV4::ExecutionEngine *engine)
{
- engine->numberPrototype()->defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString);
+ engine->numberPrototype()->defineDefaultProperty(engine->id_toLocaleString(), method_toLocaleString);
engine->numberPrototype()->defineDefaultProperty(QStringLiteral("toLocaleCurrencyString"), method_toLocaleCurrencyString);
engine->numberCtor()->defineDefaultProperty(QStringLiteral("fromLocaleString"), method_fromLocaleString);
}
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 75241ab99c..2c22d255a4 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -503,9 +503,11 @@ QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQm
d->extraData.cd->extMetaObject = type.extensionMetaObject;
// Check if the user wants only scoped enum classes
- auto indexOfClassInfo = metaObject()->indexOfClassInfo("RegisterEnumClassesUnscoped");
- if (indexOfClassInfo != -1 && QString::fromUtf8(metaObject()->classInfo(indexOfClassInfo).value()) == QLatin1String("false"))
- d->extraData.cd->registerEnumClassesUnscoped = false;
+ if (d->baseMetaObject) {
+ auto indexOfClassInfo = d->baseMetaObject->indexOfClassInfo("RegisterEnumClassesUnscoped");
+ if (indexOfClassInfo != -1 && QString::fromUtf8(d->baseMetaObject->classInfo(indexOfClassInfo).value()) == QLatin1String("false"))
+ d->extraData.cd->registerEnumClassesUnscoped = false;
+ }
}
QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQmlPrivate::RegisterCompositeType &type)
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 8ae5ea64a7..85045be411 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -1847,8 +1847,8 @@ void QQuickFlickable::flick(qreal xVelocity, qreal yVelocity)
d->vData.velocity = yVelocity;
d->hData.vTime = d->vData.vTime = d->timeline.time();
- bool flickedX = d->flickX(xVelocity);
- bool flickedY = d->flickY(yVelocity);
+ const bool flickedX = xflick() && !qFuzzyIsNull(xVelocity) && d->flickX(xVelocity);
+ const bool flickedY = yflick() && !qFuzzyIsNull(yVelocity) && d->flickY(yVelocity);
if (flickedX)
d->hMoved = true;
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index b518ddd930..9208ea1f23 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -805,7 +805,7 @@ void QQuickTableViewPrivate::cancelLoadRequest()
loadRequest.markAsDone();
model->cancel(modelIndexAtCell(loadRequest.currentCell()));
- if (rebuildState == RebuildState::NotStarted) {
+ if (rebuildScheduled) {
// No reason to rollback already loaded edge items
// since we anyway are about to reload all items.
return;
@@ -929,7 +929,13 @@ void QQuickTableViewPrivate::beginRebuildTable()
{
Q_Q(QQuickTableView);
+ rebuildScheduled = false;
+
+ if (loadRequest.isActive())
+ cancelLoadRequest();
+
releaseLoadedItems();
+
loadedTable = QRect();
loadedTableOuterRect = QRect();
loadedTableInnerRect = QRect();
@@ -1079,9 +1085,7 @@ void QQuickTableViewPrivate::drainReusePoolAfterLoadRequest()
}
void QQuickTableViewPrivate::invalidateTable() {
- rebuildState = RebuildState::NotStarted;
- if (loadRequest.isActive())
- cancelLoadRequest();
+ rebuildScheduled = true;
q_func()->polish();
}
@@ -1108,6 +1112,11 @@ void QQuickTableViewPrivate::updatePolish()
return;
}
+ if (rebuildState != RebuildState::Done) {
+ processRebuildTable();
+ return;
+ }
+
// viewportRect describes the part of the content view that is actually visible. Since a
// negative width/height can happen (e.g during start-up), we check for this to avoid rebuilding
// the table (and e.g calculate initial row/column sizes) based on a premature viewport rect.
@@ -1115,7 +1124,8 @@ void QQuickTableViewPrivate::updatePolish()
if (!viewportRect.isValid())
return;
- if (rebuildState != RebuildState::Done) {
+ if (rebuildScheduled) {
+ rebuildState = RebuildState::Begin;
processRebuildTable();
return;
}
@@ -1560,8 +1570,7 @@ qreal QQuickTableView::explicitContentWidth() const
{
Q_D(const QQuickTableView);
- if (d->rebuildState == QQuickTableViewPrivate::RebuildState::NotStarted
- && d->explicitContentWidth.isNull) {
+ if (d->rebuildScheduled && d->explicitContentWidth.isNull) {
// The table is pending to be rebuilt. Since we don't
// know the contentWidth before this is done, we do the
// rebuild now, instead of waiting for the polish event.
@@ -1585,8 +1594,7 @@ qreal QQuickTableView::explicitContentHeight() const
{
Q_D(const QQuickTableView);
- if (d->rebuildState == QQuickTableViewPrivate::RebuildState::NotStarted
- && d->explicitContentHeight.isNull) {
+ if (d->rebuildScheduled && d->explicitContentHeight.isNull) {
// The table is pending to be rebuilt. Since we don't
// know the contentHeight before this is done, we do the
// rebuild now, instead of waiting for the polish event.
diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h
index 53fd936195..1ba18480ba 100644
--- a/src/quick/items/qquicktableview_p_p.h
+++ b/src/quick/items/qquicktableview_p_p.h
@@ -164,7 +164,7 @@ public:
};
enum class RebuildState {
- NotStarted = 0,
+ Begin = 0,
LoadInitalTable,
VerifyTable,
LayoutTable,
@@ -208,7 +208,7 @@ public:
QSize tableSize;
- RebuildState rebuildState = RebuildState::NotStarted;
+ RebuildState rebuildState = RebuildState::Done;
TableEdgeLoadRequest loadRequest;
QPoint contentSizeBenchMarkPoint = QPoint(-1, -1);
@@ -221,6 +221,7 @@ public:
bool columnRowPositionsInvalid = false;
bool layoutWarningIssued = false;
bool polishing = false;
+ bool rebuildScheduled = true;
QJSValue rowHeightProvider;
QJSValue columnWidthProvider;
diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations
index 407c2d2ab4..106b16f64a 100644
--- a/tests/auto/qml/ecmascripttests/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
@@ -26,7 +26,6 @@ language/module-code/namespace/internals/define-own-property.js strictFails
language/module-code/namespace/internals/set.js strictFails
# ----- test failures that should be fixed
-built-ins/Array/from/iter-cstm-ctor-err.js fails
built-ins/Array/from/proto-from-ctor-realm.js fails
built-ins/Array/isArray/proxy-revoked.js fails
built-ins/Array/isArray/proxy.js fails
@@ -108,8 +107,6 @@ built-ins/Array/prototype/splice/create-species.js fails
built-ins/Array/prototype/splice/length-and-deleteCount-exceeding-integer-limit.js fails
built-ins/Array/prototype/splice/length-exceeding-integer-limit-shrink-array.js fails
built-ins/Array/prototype/splice/length-near-integer-limit-grow-array.js fails
-built-ins/Array/prototype/toLocaleString/S15.4.4.3_A1_T1.js fails
-built-ins/Array/prototype/toLocaleString/S15.4.4.3_A3_T1.js fails
built-ins/Array/prototype/toLocaleString/primitive_this_value.js strictFails
built-ins/Array/prototype/toLocaleString/primitive_this_value_getter.js strictFails
built-ins/Array/prototype/unshift/clamps-to-integer-limit.js fails
@@ -118,24 +115,7 @@ built-ins/Array/prototype/unshift/throws-if-integer-limit-exceeded.js fails
built-ins/ArrayBuffer/data-allocation-after-object-creation.js fails
built-ins/ArrayBuffer/proto-from-ctor-realm.js fails
built-ins/ArrayBuffer/prototype-from-newtarget.js fails
-built-ins/ArrayBuffer/prototype/slice/end-default-if-absent.js fails
-built-ins/ArrayBuffer/prototype/slice/end-default-if-undefined.js fails
-built-ins/ArrayBuffer/prototype/slice/end-exceeds-length.js fails
-built-ins/ArrayBuffer/prototype/slice/negative-end.js fails
-built-ins/ArrayBuffer/prototype/slice/negative-start.js fails
built-ins/ArrayBuffer/prototype/slice/nonconstructor.js fails
-built-ins/ArrayBuffer/prototype/slice/species-constructor-is-undefined.js fails
-built-ins/ArrayBuffer/prototype/slice/species-is-null.js fails
-built-ins/ArrayBuffer/prototype/slice/species-is-undefined.js fails
-built-ins/ArrayBuffer/prototype/slice/species-returns-larger-arraybuffer.js fails
-built-ins/ArrayBuffer/prototype/slice/species.js fails
-built-ins/ArrayBuffer/prototype/slice/start-default-if-absent.js fails
-built-ins/ArrayBuffer/prototype/slice/start-default-if-undefined.js fails
-built-ins/ArrayBuffer/prototype/slice/start-exceeds-end.js fails
-built-ins/ArrayBuffer/prototype/slice/start-exceeds-length.js fails
-built-ins/ArrayBuffer/prototype/slice/tointeger-conversion-end.js fails
-built-ins/ArrayBuffer/prototype/slice/tointeger-conversion-start.js fails
-built-ins/ArrayBuffer/undefined-newtarget-throws.js fails
built-ins/ArrayIteratorPrototype/next/detach-typedarray-in-progress.js fails
built-ins/AsyncFunction/AsyncFunction-construct.js fails
built-ins/AsyncFunction/AsyncFunction-is-extensible.js fails
@@ -235,94 +215,7 @@ built-ins/Atomics/xor/shared-nonint-views.js fails
built-ins/Boolean/proto-from-ctor-realm.js fails
built-ins/DataView/custom-proto-access-throws.js fails
built-ins/DataView/custom-proto-if-object-is-used.js fails
-built-ins/DataView/detached-buffer.js fails
-built-ins/DataView/length.js fails
-built-ins/DataView/newtarget-undefined-throws.js fails
built-ins/DataView/proto-from-ctor-realm.js fails
-built-ins/DataView/prototype/byteLength/detached-buffer.js fails
-built-ins/DataView/prototype/byteOffset/detached-buffer.js fails
-built-ins/DataView/prototype/getFloat32/detached-buffer-after-toindex-byteoffset.js fails
-built-ins/DataView/prototype/getFloat32/index-is-out-of-range.js fails
-built-ins/DataView/prototype/getFloat32/negative-byteoffset-throws.js fails
-built-ins/DataView/prototype/getFloat32/toindex-byteoffset.js fails
-built-ins/DataView/prototype/getFloat64/detached-buffer-after-toindex-byteoffset.js fails
-built-ins/DataView/prototype/getFloat64/index-is-out-of-range.js fails
-built-ins/DataView/prototype/getFloat64/negative-byteoffset-throws.js fails
-built-ins/DataView/prototype/getFloat64/toindex-byteoffset.js fails
-built-ins/DataView/prototype/getInt16/detached-buffer-after-toindex-byteoffset.js fails
-built-ins/DataView/prototype/getInt16/index-is-out-of-range.js fails
-built-ins/DataView/prototype/getInt16/negative-byteoffset-throws.js fails
-built-ins/DataView/prototype/getInt16/toindex-byteoffset.js fails
-built-ins/DataView/prototype/getInt32/detached-buffer-after-toindex-byteoffset.js fails
-built-ins/DataView/prototype/getInt32/index-is-out-of-range.js fails
-built-ins/DataView/prototype/getInt32/negative-byteoffset-throws.js fails
-built-ins/DataView/prototype/getInt32/toindex-byteoffset.js fails
-built-ins/DataView/prototype/getInt8/detached-buffer-after-toindex-byteoffset.js fails
-built-ins/DataView/prototype/getInt8/index-is-out-of-range.js fails
-built-ins/DataView/prototype/getInt8/negative-byteoffset-throws.js fails
-built-ins/DataView/prototype/getInt8/toindex-byteoffset.js fails
-built-ins/DataView/prototype/getUint16/detached-buffer-after-toindex-byteoffset.js fails
-built-ins/DataView/prototype/getUint16/index-is-out-of-range.js fails
-built-ins/DataView/prototype/getUint16/negative-byteoffset-throws.js fails
-built-ins/DataView/prototype/getUint16/toindex-byteoffset.js fails
-built-ins/DataView/prototype/getUint32/detached-buffer-after-toindex-byteoffset.js fails
-built-ins/DataView/prototype/getUint32/index-is-out-of-range.js fails
-built-ins/DataView/prototype/getUint32/negative-byteoffset-throws.js fails
-built-ins/DataView/prototype/getUint32/toindex-byteoffset.js fails
-built-ins/DataView/prototype/getUint8/detached-buffer-after-toindex-byteoffset.js fails
-built-ins/DataView/prototype/getUint8/index-is-out-of-range.js fails
-built-ins/DataView/prototype/getUint8/negative-byteoffset-throws.js fails
-built-ins/DataView/prototype/getUint8/toindex-byteoffset.js fails
-built-ins/DataView/prototype/setFloat32/detached-buffer-after-toindex-byteoffset.js fails
-built-ins/DataView/prototype/setFloat32/index-check-before-value-conversion.js fails
-built-ins/DataView/prototype/setFloat32/index-is-out-of-range.js fails
-built-ins/DataView/prototype/setFloat32/negative-byteoffset-throws.js fails
-built-ins/DataView/prototype/setFloat32/range-check-after-value-conversion.js fails
-built-ins/DataView/prototype/setFloat32/toindex-byteoffset.js fails
-built-ins/DataView/prototype/setFloat64/detached-buffer-after-toindex-byteoffset.js fails
-built-ins/DataView/prototype/setFloat64/index-check-before-value-conversion.js fails
-built-ins/DataView/prototype/setFloat64/index-is-out-of-range.js fails
-built-ins/DataView/prototype/setFloat64/negative-byteoffset-throws.js fails
-built-ins/DataView/prototype/setFloat64/range-check-after-value-conversion.js fails
-built-ins/DataView/prototype/setFloat64/toindex-byteoffset.js fails
-built-ins/DataView/prototype/setInt16/detached-buffer-after-toindex-byteoffset.js fails
-built-ins/DataView/prototype/setInt16/index-check-before-value-conversion.js fails
-built-ins/DataView/prototype/setInt16/index-is-out-of-range.js fails
-built-ins/DataView/prototype/setInt16/negative-byteoffset-throws.js fails
-built-ins/DataView/prototype/setInt16/range-check-after-value-conversion.js fails
-built-ins/DataView/prototype/setInt16/toindex-byteoffset.js fails
-built-ins/DataView/prototype/setInt32/detached-buffer-after-toindex-byteoffset.js fails
-built-ins/DataView/prototype/setInt32/index-check-before-value-conversion.js fails
-built-ins/DataView/prototype/setInt32/index-is-out-of-range.js fails
-built-ins/DataView/prototype/setInt32/negative-byteoffset-throws.js fails
-built-ins/DataView/prototype/setInt32/range-check-after-value-conversion.js fails
-built-ins/DataView/prototype/setInt32/toindex-byteoffset.js fails
-built-ins/DataView/prototype/setInt8/detached-buffer-after-toindex-byteoffset.js fails
-built-ins/DataView/prototype/setInt8/index-check-before-value-conversion.js fails
-built-ins/DataView/prototype/setInt8/index-is-out-of-range.js fails
-built-ins/DataView/prototype/setInt8/negative-byteoffset-throws.js fails
-built-ins/DataView/prototype/setInt8/range-check-after-value-conversion.js fails
-built-ins/DataView/prototype/setInt8/toindex-byteoffset.js fails
-built-ins/DataView/prototype/setUint16/detached-buffer-after-toindex-byteoffset.js fails
-built-ins/DataView/prototype/setUint16/index-check-before-value-conversion.js fails
-built-ins/DataView/prototype/setUint16/index-is-out-of-range.js fails
-built-ins/DataView/prototype/setUint16/negative-byteoffset-throws.js fails
-built-ins/DataView/prototype/setUint16/range-check-after-value-conversion.js fails
-built-ins/DataView/prototype/setUint16/toindex-byteoffset.js fails
-built-ins/DataView/prototype/setUint32/detached-buffer-after-toindex-byteoffset.js fails
-built-ins/DataView/prototype/setUint32/index-check-before-value-conversion.js fails
-built-ins/DataView/prototype/setUint32/index-is-out-of-range.js fails
-built-ins/DataView/prototype/setUint32/negative-byteoffset-throws.js fails
-built-ins/DataView/prototype/setUint32/range-check-after-value-conversion.js fails
-built-ins/DataView/prototype/setUint32/toindex-byteoffset.js fails
-built-ins/DataView/prototype/setUint8/detached-buffer-after-toindex-byteoffset.js fails
-built-ins/DataView/prototype/setUint8/index-check-before-value-conversion.js fails
-built-ins/DataView/prototype/setUint8/index-is-out-of-range.js fails
-built-ins/DataView/prototype/setUint8/negative-byteoffset-throws.js fails
-built-ins/DataView/prototype/setUint8/range-check-after-value-conversion.js fails
-built-ins/DataView/prototype/setUint8/toindex-byteoffset.js fails
-built-ins/DataView/toindex-bytelength.js fails
-built-ins/DataView/toindex-byteoffset.js fails
built-ins/Date/UTC/infinity-make-day.js fails
built-ins/Date/UTC/nans.js fails
built-ins/Date/UTC/no-arg.js fails
@@ -369,7 +262,6 @@ built-ins/Function/prototype/toString/async-method-class-statement.js fails
built-ins/Function/prototype/toString/async-method-object.js fails
built-ins/Function/prototype/toString/intrinsics.js fails
built-ins/Function/prototype/toString/method-computed-property-name.js fails
-built-ins/Function/prototype/toString/proxy.js fails
built-ins/GeneratorFunction/proto-from-ctor-realm.js fails
built-ins/JSON/parse/revived-proxy-revoked.js fails
built-ins/JSON/parse/revived-proxy.js fails
@@ -590,24 +482,10 @@ built-ins/Promise/resolve/prop-desc.js fails
built-ins/Promise/resolve/resolve-from-promise-capability.js fails
built-ins/Promise/resolve/resolve-prms-cstm-then.js fails
built-ins/Proxy/apply/arguments-realm.js fails
-built-ins/Proxy/apply/call-parameters.js fails
-built-ins/Proxy/apply/call-result.js fails
-built-ins/Proxy/apply/return-abrupt.js fails
built-ins/Proxy/apply/trap-is-not-callable-realm.js fails
-built-ins/Proxy/apply/trap-is-null.js fails
-built-ins/Proxy/apply/trap-is-undefined-no-property.js fails
-built-ins/Proxy/apply/trap-is-undefined.js fails
built-ins/Proxy/construct/arguments-realm.js fails
-built-ins/Proxy/construct/call-parameters-new-target.js fails
-built-ins/Proxy/construct/call-parameters.js fails
-built-ins/Proxy/construct/call-result.js fails
-built-ins/Proxy/construct/return-is-abrupt.js fails
built-ins/Proxy/construct/trap-is-not-callable-realm.js fails
-built-ins/Proxy/construct/trap-is-null.js fails
-built-ins/Proxy/construct/trap-is-undefined-no-property.js fails
built-ins/Proxy/construct/trap-is-undefined-proto-from-ctor-realm.js fails
-built-ins/Proxy/construct/trap-is-undefined.js fails
-built-ins/Proxy/create-target-is-not-constructor.js fails
built-ins/Proxy/defineProperty/desc-realm.js fails
built-ins/Proxy/defineProperty/null-handler-realm.js fails
built-ins/Proxy/defineProperty/targetdesc-configurable-desc-not-configurable-realm.js fails
@@ -648,8 +526,6 @@ built-ins/Proxy/revocable/revocation-function-nonconstructor.js fails
built-ins/Proxy/set/trap-is-not-callable-realm.js fails
built-ins/Proxy/set/trap-is-undefined-receiver.js fails
built-ins/Proxy/setPrototypeOf/trap-is-not-callable-realm.js fails
-built-ins/Reflect/construct/newtarget-is-not-constructor-throws.js fails
-built-ins/Reflect/construct/return-with-newtarget-argument.js fails
built-ins/Reflect/set/creates-a-data-descriptor.js fails
built-ins/Reflect/set/different-property-descriptors.js fails
built-ins/Reflect/set/receiver-is-not-object.js fails
@@ -787,334 +663,9 @@ built-ins/TypedArray/from/iter-next-value-error.js fails
built-ins/TypedArray/from/length.js fails
built-ins/TypedArray/from/name.js fails
built-ins/TypedArray/from/prop-desc.js fails
-built-ins/TypedArray/name.js fails
-built-ins/TypedArray/of/length.js fails
-built-ins/TypedArray/of/name.js fails
-built-ins/TypedArray/of/prop-desc.js fails
-built-ins/TypedArray/prototype/byteLength/detached-buffer.js fails
-built-ins/TypedArray/prototype/byteOffset/detached-buffer.js fails
built-ins/TypedArray/prototype/constructor.js fails
-built-ins/TypedArray/prototype/copyWithin/bit-precision.js fails
-built-ins/TypedArray/prototype/copyWithin/coerced-values-end.js fails
-built-ins/TypedArray/prototype/copyWithin/coerced-values-start.js fails
-built-ins/TypedArray/prototype/copyWithin/coerced-values-target.js fails
-built-ins/TypedArray/prototype/copyWithin/get-length-ignores-length-prop.js fails
-built-ins/TypedArray/prototype/copyWithin/invoked-as-func.js fails
-built-ins/TypedArray/prototype/copyWithin/invoked-as-method.js fails
-built-ins/TypedArray/prototype/copyWithin/length.js fails
-built-ins/TypedArray/prototype/copyWithin/name.js fails
-built-ins/TypedArray/prototype/copyWithin/negative-end.js fails
-built-ins/TypedArray/prototype/copyWithin/negative-out-of-bounds-end.js fails
-built-ins/TypedArray/prototype/copyWithin/negative-out-of-bounds-start.js fails
-built-ins/TypedArray/prototype/copyWithin/negative-out-of-bounds-target.js fails
-built-ins/TypedArray/prototype/copyWithin/negative-start.js fails
-built-ins/TypedArray/prototype/copyWithin/negative-target.js fails
-built-ins/TypedArray/prototype/copyWithin/non-negative-out-of-bounds-end.js fails
-built-ins/TypedArray/prototype/copyWithin/non-negative-out-of-bounds-target-and-start.js fails
-built-ins/TypedArray/prototype/copyWithin/non-negative-target-and-start.js fails
-built-ins/TypedArray/prototype/copyWithin/non-negative-target-start-and-end.js fails
-built-ins/TypedArray/prototype/copyWithin/prop-desc.js fails
-built-ins/TypedArray/prototype/copyWithin/return-abrupt-from-end.js fails
-built-ins/TypedArray/prototype/copyWithin/return-abrupt-from-start.js fails
-built-ins/TypedArray/prototype/copyWithin/return-abrupt-from-target.js fails
-built-ins/TypedArray/prototype/copyWithin/return-this.js fails
-built-ins/TypedArray/prototype/copyWithin/undefined-end.js fails
-built-ins/TypedArray/prototype/entries/detached-buffer.js fails
-built-ins/TypedArray/prototype/every/callbackfn-arguments-with-thisarg.js fails
-built-ins/TypedArray/prototype/every/callbackfn-arguments-without-thisarg.js fails
-built-ins/TypedArray/prototype/every/callbackfn-detachbuffer.js fails
-built-ins/TypedArray/prototype/every/callbackfn-no-interaction-over-non-integer.js fails
-built-ins/TypedArray/prototype/every/callbackfn-not-called-on-empty.js fails
-built-ins/TypedArray/prototype/every/callbackfn-return-does-not-change-instance.js fails
-built-ins/TypedArray/prototype/every/callbackfn-returns-abrupt.js fails
-built-ins/TypedArray/prototype/every/callbackfn-set-value-during-interaction.js fails
-built-ins/TypedArray/prototype/every/callbackfn-this.js fails
-built-ins/TypedArray/prototype/every/get-length-uses-internal-arraylength.js fails
-built-ins/TypedArray/prototype/every/invoked-as-func.js fails
-built-ins/TypedArray/prototype/every/invoked-as-method.js fails
-built-ins/TypedArray/prototype/every/length.js fails
-built-ins/TypedArray/prototype/every/name.js fails
-built-ins/TypedArray/prototype/every/prop-desc.js fails
-built-ins/TypedArray/prototype/every/returns-false-if-any-cb-returns-false.js fails
-built-ins/TypedArray/prototype/every/returns-true-if-every-cb-returns-true.js fails
-built-ins/TypedArray/prototype/every/values-are-not-cached.js fails
-built-ins/TypedArray/prototype/fill/coerced-indexes.js fails
-built-ins/TypedArray/prototype/fill/fill-values-conversion-once.js fails
built-ins/TypedArray/prototype/fill/fill-values-conversion-operations-consistent-nan.js fails
-built-ins/TypedArray/prototype/fill/fill-values-conversion-operations.js fails
-built-ins/TypedArray/prototype/fill/fill-values-custom-start-and-end.js fails
-built-ins/TypedArray/prototype/fill/fill-values-non-numeric.js fails
-built-ins/TypedArray/prototype/fill/fill-values-relative-end.js fails
-built-ins/TypedArray/prototype/fill/fill-values-relative-start.js fails
-built-ins/TypedArray/prototype/fill/fill-values.js fails
-built-ins/TypedArray/prototype/fill/get-length-ignores-length-prop.js fails
-built-ins/TypedArray/prototype/fill/invoked-as-func.js fails
-built-ins/TypedArray/prototype/fill/invoked-as-method.js fails
-built-ins/TypedArray/prototype/fill/length.js fails
-built-ins/TypedArray/prototype/fill/name.js fails
-built-ins/TypedArray/prototype/fill/prop-desc.js fails
-built-ins/TypedArray/prototype/fill/return-abrupt-from-end.js fails
-built-ins/TypedArray/prototype/fill/return-abrupt-from-set-value.js fails
-built-ins/TypedArray/prototype/fill/return-abrupt-from-start.js fails
-built-ins/TypedArray/prototype/fill/return-this.js fails
-built-ins/TypedArray/prototype/filter/arraylength-internal.js fails
-built-ins/TypedArray/prototype/filter/callbackfn-arguments-with-thisarg.js fails
-built-ins/TypedArray/prototype/filter/callbackfn-arguments-without-thisarg.js fails
-built-ins/TypedArray/prototype/filter/callbackfn-called-before-ctor.js fails
-built-ins/TypedArray/prototype/filter/callbackfn-called-before-species.js fails
-built-ins/TypedArray/prototype/filter/callbackfn-detachbuffer.js fails
-built-ins/TypedArray/prototype/filter/callbackfn-no-iteration-over-non-integer.js fails
-built-ins/TypedArray/prototype/filter/callbackfn-not-called-on-empty.js fails
-built-ins/TypedArray/prototype/filter/callbackfn-return-does-not-change-instance.js fails
-built-ins/TypedArray/prototype/filter/callbackfn-returns-abrupt.js fails
-built-ins/TypedArray/prototype/filter/callbackfn-set-value-during-iteration.js fails
-built-ins/TypedArray/prototype/filter/callbackfn-this.js fails
-built-ins/TypedArray/prototype/filter/invoked-as-func.js fails
-built-ins/TypedArray/prototype/filter/invoked-as-method.js fails
-built-ins/TypedArray/prototype/filter/length.js fails
-built-ins/TypedArray/prototype/filter/name.js fails
-built-ins/TypedArray/prototype/filter/prop-desc.js fails
-built-ins/TypedArray/prototype/filter/result-does-not-share-buffer.js fails
-built-ins/TypedArray/prototype/filter/result-empty-callbackfn-returns-false.js fails
-built-ins/TypedArray/prototype/filter/result-full-callbackfn-returns-true.js fails
-built-ins/TypedArray/prototype/filter/speciesctor-get-ctor-abrupt.js fails
-built-ins/TypedArray/prototype/filter/speciesctor-get-ctor-inherited.js fails
-built-ins/TypedArray/prototype/filter/speciesctor-get-ctor.js fails
-built-ins/TypedArray/prototype/filter/speciesctor-get-species-abrupt.js fails
-built-ins/TypedArray/prototype/filter/speciesctor-get-species-custom-ctor-invocation.js fails
-built-ins/TypedArray/prototype/filter/speciesctor-get-species-custom-ctor-length.js fails
-built-ins/TypedArray/prototype/filter/speciesctor-get-species-custom-ctor-returns-another-instance.js fails
-built-ins/TypedArray/prototype/filter/speciesctor-get-species-custom-ctor.js fails
-built-ins/TypedArray/prototype/filter/speciesctor-get-species-use-default-ctor.js fails
-built-ins/TypedArray/prototype/filter/speciesctor-get-species.js fails
-built-ins/TypedArray/prototype/filter/values-are-not-cached.js fails
-built-ins/TypedArray/prototype/filter/values-are-set.js fails
-built-ins/TypedArray/prototype/find/get-length-ignores-length-prop.js fails
-built-ins/TypedArray/prototype/find/invoked-as-func.js fails
-built-ins/TypedArray/prototype/find/invoked-as-method.js fails
-built-ins/TypedArray/prototype/find/length.js fails
-built-ins/TypedArray/prototype/find/name.js fails
-built-ins/TypedArray/prototype/find/predicate-call-changes-value.js fails
-built-ins/TypedArray/prototype/find/predicate-call-parameters.js fails
-built-ins/TypedArray/prototype/find/predicate-call-this-non-strict.js sloppyFails
-built-ins/TypedArray/prototype/find/predicate-call-this-strict.js strictFails
-built-ins/TypedArray/prototype/find/predicate-may-detach-buffer.js fails
-built-ins/TypedArray/prototype/find/predicate-not-called-on-empty-array.js fails
-built-ins/TypedArray/prototype/find/prop-desc.js fails
-built-ins/TypedArray/prototype/find/return-abrupt-from-predicate-call.js fails
-built-ins/TypedArray/prototype/find/return-found-value-predicate-result-is-true.js fails
-built-ins/TypedArray/prototype/find/return-undefined-if-predicate-returns-false-value.js fails
-built-ins/TypedArray/prototype/findIndex/get-length-ignores-length-prop.js fails
-built-ins/TypedArray/prototype/findIndex/invoked-as-func.js fails
-built-ins/TypedArray/prototype/findIndex/invoked-as-method.js fails
-built-ins/TypedArray/prototype/findIndex/length.js fails
-built-ins/TypedArray/prototype/findIndex/name.js fails
-built-ins/TypedArray/prototype/findIndex/predicate-call-changes-value.js fails
-built-ins/TypedArray/prototype/findIndex/predicate-call-parameters.js fails
-built-ins/TypedArray/prototype/findIndex/predicate-call-this-non-strict.js sloppyFails
-built-ins/TypedArray/prototype/findIndex/predicate-call-this-strict.js strictFails
-built-ins/TypedArray/prototype/findIndex/predicate-may-detach-buffer.js fails
-built-ins/TypedArray/prototype/findIndex/predicate-not-called-on-empty-array.js fails
-built-ins/TypedArray/prototype/findIndex/prop-desc.js fails
-built-ins/TypedArray/prototype/findIndex/return-abrupt-from-predicate-call.js fails
-built-ins/TypedArray/prototype/findIndex/return-index-predicate-result-is-true.js fails
-built-ins/TypedArray/prototype/findIndex/return-negative-one-if-predicate-returns-false-value.js fails
-built-ins/TypedArray/prototype/forEach/arraylength-internal.js fails
-built-ins/TypedArray/prototype/forEach/callbackfn-arguments-with-thisarg.js fails
-built-ins/TypedArray/prototype/forEach/callbackfn-arguments-without-thisarg.js fails
-built-ins/TypedArray/prototype/forEach/callbackfn-detachbuffer.js fails
-built-ins/TypedArray/prototype/forEach/callbackfn-no-interaction-over-non-integer.js fails
-built-ins/TypedArray/prototype/forEach/callbackfn-not-called-on-empty.js fails
-built-ins/TypedArray/prototype/forEach/callbackfn-return-does-not-change-instance.js fails
-built-ins/TypedArray/prototype/forEach/callbackfn-returns-abrupt.js fails
-built-ins/TypedArray/prototype/forEach/callbackfn-set-value-during-interaction.js fails
-built-ins/TypedArray/prototype/forEach/callbackfn-this.js fails
-built-ins/TypedArray/prototype/forEach/invoked-as-func.js fails
-built-ins/TypedArray/prototype/forEach/invoked-as-method.js fails
-built-ins/TypedArray/prototype/forEach/length.js fails
-built-ins/TypedArray/prototype/forEach/name.js fails
-built-ins/TypedArray/prototype/forEach/prop-desc.js fails
-built-ins/TypedArray/prototype/forEach/returns-undefined.js fails
-built-ins/TypedArray/prototype/forEach/values-are-not-cached.js fails
-built-ins/TypedArray/prototype/includes/fromIndex-equal-or-greater-length-returns-false.js fails
-built-ins/TypedArray/prototype/includes/fromIndex-infinity.js fails
-built-ins/TypedArray/prototype/includes/fromIndex-minus-zero.js fails
-built-ins/TypedArray/prototype/includes/get-length-uses-internal-arraylength.js fails
-built-ins/TypedArray/prototype/includes/invoked-as-func.js fails
-built-ins/TypedArray/prototype/includes/invoked-as-method.js fails
-built-ins/TypedArray/prototype/includes/length-zero-returns-false.js fails
-built-ins/TypedArray/prototype/includes/length.js fails
-built-ins/TypedArray/prototype/includes/name.js fails
-built-ins/TypedArray/prototype/includes/prop-desc.js fails
-built-ins/TypedArray/prototype/includes/return-abrupt-tointeger-fromindex.js fails
-built-ins/TypedArray/prototype/includes/samevaluezero.js fails
-built-ins/TypedArray/prototype/includes/search-found-returns-true.js fails
-built-ins/TypedArray/prototype/includes/search-not-found-returns-false.js fails
-built-ins/TypedArray/prototype/includes/tointeger-fromindex.js fails
-built-ins/TypedArray/prototype/indexOf/fromIndex-equal-or-greater-length-returns-minus-one.js fails
-built-ins/TypedArray/prototype/indexOf/fromIndex-infinity.js fails
-built-ins/TypedArray/prototype/indexOf/fromIndex-minus-zero.js fails
-built-ins/TypedArray/prototype/indexOf/get-length-uses-internal-arraylength.js fails
-built-ins/TypedArray/prototype/indexOf/invoked-as-func.js fails
-built-ins/TypedArray/prototype/indexOf/invoked-as-method.js fails
-built-ins/TypedArray/prototype/indexOf/length-zero-returns-minus-one.js fails
-built-ins/TypedArray/prototype/indexOf/length.js fails
-built-ins/TypedArray/prototype/indexOf/name.js fails
-built-ins/TypedArray/prototype/indexOf/prop-desc.js fails
-built-ins/TypedArray/prototype/indexOf/return-abrupt-tointeger-fromindex.js fails
-built-ins/TypedArray/prototype/indexOf/search-found-returns-index.js fails
-built-ins/TypedArray/prototype/indexOf/search-not-found-returns-minus-one.js fails
-built-ins/TypedArray/prototype/indexOf/strict-comparison.js fails
-built-ins/TypedArray/prototype/indexOf/tointeger-fromindex.js fails
-built-ins/TypedArray/prototype/join/custom-separator-result-from-tostring-on-each-simple-value.js fails
-built-ins/TypedArray/prototype/join/custom-separator-result-from-tostring-on-each-value.js fails
-built-ins/TypedArray/prototype/join/empty-instance-empty-string.js fails
-built-ins/TypedArray/prototype/join/get-length-uses-internal-arraylength.js fails
-built-ins/TypedArray/prototype/join/invoked-as-func.js fails
-built-ins/TypedArray/prototype/join/invoked-as-method.js fails
-built-ins/TypedArray/prototype/join/length.js fails
-built-ins/TypedArray/prototype/join/name.js fails
-built-ins/TypedArray/prototype/join/prop-desc.js fails
-built-ins/TypedArray/prototype/join/result-from-tostring-on-each-simple-value.js fails
-built-ins/TypedArray/prototype/join/result-from-tostring-on-each-value.js fails
-built-ins/TypedArray/prototype/join/return-abrupt-from-separator.js fails
-built-ins/TypedArray/prototype/keys/detached-buffer.js fails
-built-ins/TypedArray/prototype/lastIndexOf/fromIndex-infinity.js fails
-built-ins/TypedArray/prototype/lastIndexOf/fromIndex-minus-zero.js fails
-built-ins/TypedArray/prototype/lastIndexOf/get-length-uses-internal-arraylength.js fails
-built-ins/TypedArray/prototype/lastIndexOf/invoked-as-func.js fails
-built-ins/TypedArray/prototype/lastIndexOf/invoked-as-method.js fails
-built-ins/TypedArray/prototype/lastIndexOf/length-zero-returns-minus-one.js fails
-built-ins/TypedArray/prototype/lastIndexOf/length.js fails
-built-ins/TypedArray/prototype/lastIndexOf/name.js fails
-built-ins/TypedArray/prototype/lastIndexOf/prop-desc.js fails
-built-ins/TypedArray/prototype/lastIndexOf/return-abrupt-tointeger-fromindex.js fails
-built-ins/TypedArray/prototype/lastIndexOf/search-found-returns-index.js fails
-built-ins/TypedArray/prototype/lastIndexOf/search-not-found-returns-minus-one.js fails
-built-ins/TypedArray/prototype/lastIndexOf/strict-comparison.js fails
-built-ins/TypedArray/prototype/lastIndexOf/tointeger-fromindex.js fails
-built-ins/TypedArray/prototype/length/detached-buffer.js fails
-built-ins/TypedArray/prototype/map/arraylength-internal.js fails
-built-ins/TypedArray/prototype/map/callbackfn-arguments-with-thisarg.js fails
-built-ins/TypedArray/prototype/map/callbackfn-arguments-without-thisarg.js fails
-built-ins/TypedArray/prototype/map/callbackfn-detachbuffer.js fails
-built-ins/TypedArray/prototype/map/callbackfn-no-interaction-over-non-integer-properties.js fails
-built-ins/TypedArray/prototype/map/callbackfn-not-called-on-empty.js fails
-built-ins/TypedArray/prototype/map/callbackfn-return-affects-returned-object.js fails
-built-ins/TypedArray/prototype/map/callbackfn-return-does-not-change-instance.js fails
-built-ins/TypedArray/prototype/map/callbackfn-return-does-not-copy-non-integer-properties.js fails
-built-ins/TypedArray/prototype/map/callbackfn-returns-abrupt.js fails
-built-ins/TypedArray/prototype/map/callbackfn-set-value-during-interaction.js fails
-built-ins/TypedArray/prototype/map/callbackfn-this.js fails
-built-ins/TypedArray/prototype/map/invoked-as-func.js fails
-built-ins/TypedArray/prototype/map/invoked-as-method.js fails
-built-ins/TypedArray/prototype/map/length.js fails
-built-ins/TypedArray/prototype/map/name.js fails
-built-ins/TypedArray/prototype/map/prop-desc.js fails
-built-ins/TypedArray/prototype/map/return-new-typedarray-conversion-operation-consistent-nan.js fails
-built-ins/TypedArray/prototype/map/return-new-typedarray-conversion-operation.js fails
-built-ins/TypedArray/prototype/map/return-new-typedarray-from-empty-length.js fails
-built-ins/TypedArray/prototype/map/return-new-typedarray-from-positive-length.js fails
-built-ins/TypedArray/prototype/map/values-are-not-cached.js fails
-built-ins/TypedArray/prototype/reduce/callbackfn-arguments-custom-accumulator.js fails
-built-ins/TypedArray/prototype/reduce/callbackfn-arguments-default-accumulator.js fails
-built-ins/TypedArray/prototype/reduce/callbackfn-detachbuffer.js fails
-built-ins/TypedArray/prototype/reduce/callbackfn-no-iteration-over-non-integer-properties.js fails
-built-ins/TypedArray/prototype/reduce/callbackfn-not-called-on-empty.js fails
-built-ins/TypedArray/prototype/reduce/callbackfn-return-does-not-change-instance.js fails
-built-ins/TypedArray/prototype/reduce/callbackfn-returns-abrupt.js fails
-built-ins/TypedArray/prototype/reduce/callbackfn-set-value-during-iteration.js fails
-built-ins/TypedArray/prototype/reduce/callbackfn-this.js fails
-built-ins/TypedArray/prototype/reduce/empty-instance-return-initialvalue.js fails
-built-ins/TypedArray/prototype/reduce/get-length-uses-internal-arraylength.js fails
-built-ins/TypedArray/prototype/reduce/invoked-as-func.js fails
-built-ins/TypedArray/prototype/reduce/invoked-as-method.js fails
-built-ins/TypedArray/prototype/reduce/length.js fails
-built-ins/TypedArray/prototype/reduce/name.js fails
-built-ins/TypedArray/prototype/reduce/prop-desc.js fails
-built-ins/TypedArray/prototype/reduce/result-is-last-callbackfn-return.js fails
-built-ins/TypedArray/prototype/reduce/result-of-any-type.js fails
-built-ins/TypedArray/prototype/reduce/return-first-value-without-callbackfn.js fails
-built-ins/TypedArray/prototype/reduce/values-are-not-cached.js fails
-built-ins/TypedArray/prototype/reduceRight/callbackfn-arguments-custom-accumulator.js fails
-built-ins/TypedArray/prototype/reduceRight/callbackfn-arguments-default-accumulator.js fails
-built-ins/TypedArray/prototype/reduceRight/callbackfn-detachbuffer.js fails
-built-ins/TypedArray/prototype/reduceRight/callbackfn-no-iteration-over-non-integer-properties.js fails
-built-ins/TypedArray/prototype/reduceRight/callbackfn-not-called-on-empty.js fails
-built-ins/TypedArray/prototype/reduceRight/callbackfn-return-does-not-change-instance.js fails
-built-ins/TypedArray/prototype/reduceRight/callbackfn-returns-abrupt.js fails
-built-ins/TypedArray/prototype/reduceRight/callbackfn-set-value-during-iteration.js fails
-built-ins/TypedArray/prototype/reduceRight/callbackfn-this.js fails
-built-ins/TypedArray/prototype/reduceRight/empty-instance-return-initialvalue.js fails
-built-ins/TypedArray/prototype/reduceRight/get-length-uses-internal-arraylength.js fails
-built-ins/TypedArray/prototype/reduceRight/invoked-as-func.js fails
-built-ins/TypedArray/prototype/reduceRight/invoked-as-method.js fails
-built-ins/TypedArray/prototype/reduceRight/length.js fails
-built-ins/TypedArray/prototype/reduceRight/name.js fails
-built-ins/TypedArray/prototype/reduceRight/prop-desc.js fails
-built-ins/TypedArray/prototype/reduceRight/result-is-last-callbackfn-return.js fails
-built-ins/TypedArray/prototype/reduceRight/result-of-any-type.js fails
-built-ins/TypedArray/prototype/reduceRight/return-first-value-without-callbackfn.js fails
-built-ins/TypedArray/prototype/reduceRight/values-are-not-cached.js fails
-built-ins/TypedArray/prototype/reverse/get-length-uses-internal-arraylength.js fails
-built-ins/TypedArray/prototype/reverse/invoked-as-func.js fails
-built-ins/TypedArray/prototype/reverse/invoked-as-method.js fails
-built-ins/TypedArray/prototype/reverse/length.js fails
-built-ins/TypedArray/prototype/reverse/name.js fails
-built-ins/TypedArray/prototype/reverse/preserves-non-numeric-properties.js fails
-built-ins/TypedArray/prototype/reverse/prop-desc.js fails
-built-ins/TypedArray/prototype/reverse/returns-original-object.js fails
-built-ins/TypedArray/prototype/reverse/reverts.js fails
-built-ins/TypedArray/prototype/set/array-arg-set-values-in-order.js fails
-built-ins/TypedArray/prototype/set/array-arg-targetbuffer-detached-on-get-src-value-throws.js fails
-built-ins/TypedArray/prototype/slice/arraylength-internal.js fails
built-ins/TypedArray/prototype/slice/bit-precision.js fails
-built-ins/TypedArray/prototype/slice/detached-buffer-zero-count-custom-ctor-other-targettype.js fails
-built-ins/TypedArray/prototype/slice/detached-buffer-zero-count-custom-ctor-same-targettype.js fails
-built-ins/TypedArray/prototype/slice/infinity.js fails
-built-ins/TypedArray/prototype/slice/invoked-as-func.js fails
-built-ins/TypedArray/prototype/slice/invoked-as-method.js fails
-built-ins/TypedArray/prototype/slice/length.js fails
-built-ins/TypedArray/prototype/slice/minus-zero.js fails
-built-ins/TypedArray/prototype/slice/name.js fails
-built-ins/TypedArray/prototype/slice/prop-desc.js fails
-built-ins/TypedArray/prototype/slice/result-does-not-copy-ordinary-properties.js fails
-built-ins/TypedArray/prototype/slice/results-with-different-length.js fails
-built-ins/TypedArray/prototype/slice/results-with-empty-length.js fails
-built-ins/TypedArray/prototype/slice/results-with-same-length.js fails
-built-ins/TypedArray/prototype/slice/return-abrupt-from-end.js fails
-built-ins/TypedArray/prototype/slice/return-abrupt-from-start.js fails
-built-ins/TypedArray/prototype/slice/set-values-from-different-ctor-type.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-ctor-abrupt.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-ctor-inherited.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-ctor.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-species-abrupt.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-species-custom-ctor-invocation.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-species-custom-ctor-length.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-species-custom-ctor-returns-another-instance.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-species-custom-ctor.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-species-use-default-ctor.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-species.js fails
-built-ins/TypedArray/prototype/slice/tointeger-end.js fails
-built-ins/TypedArray/prototype/slice/tointeger-start.js fails
-built-ins/TypedArray/prototype/some/callbackfn-arguments-with-thisarg.js fails
-built-ins/TypedArray/prototype/some/callbackfn-arguments-without-thisarg.js fails
-built-ins/TypedArray/prototype/some/callbackfn-detachbuffer.js fails
-built-ins/TypedArray/prototype/some/callbackfn-no-interaction-over-non-integer.js fails
-built-ins/TypedArray/prototype/some/callbackfn-not-called-on-empty.js fails
-built-ins/TypedArray/prototype/some/callbackfn-return-does-not-change-instance.js fails
-built-ins/TypedArray/prototype/some/callbackfn-returns-abrupt.js fails
-built-ins/TypedArray/prototype/some/callbackfn-set-value-during-interaction.js fails
-built-ins/TypedArray/prototype/some/callbackfn-this.js fails
-built-ins/TypedArray/prototype/some/get-length-uses-internal-arraylength.js fails
-built-ins/TypedArray/prototype/some/invoked-as-func.js fails
-built-ins/TypedArray/prototype/some/invoked-as-method.js fails
-built-ins/TypedArray/prototype/some/length.js fails
-built-ins/TypedArray/prototype/some/name.js fails
-built-ins/TypedArray/prototype/some/prop-desc.js fails
-built-ins/TypedArray/prototype/some/returns-false-if-every-cb-returns-false.js fails
-built-ins/TypedArray/prototype/some/returns-true-if-any-cb-returns-true.js fails
-built-ins/TypedArray/prototype/some/values-are-not-cached.js fails
built-ins/TypedArray/prototype/sort/arraylength-internal.js fails
built-ins/TypedArray/prototype/sort/comparefn-call-throws.js fails
built-ins/TypedArray/prototype/sort/comparefn-calls.js fails
@@ -1128,35 +679,6 @@ built-ins/TypedArray/prototype/sort/return-same-instance.js fails
built-ins/TypedArray/prototype/sort/sortcompare-with-no-tostring.js fails
built-ins/TypedArray/prototype/sort/sorted-values-nan.js fails
built-ins/TypedArray/prototype/sort/sorted-values.js fails
-built-ins/TypedArray/prototype/subarray/detached-buffer.js fails
-built-ins/TypedArray/prototype/subarray/length.js fails
-built-ins/TypedArray/prototype/subarray/speciesctor-get-ctor-inherited.js fails
-built-ins/TypedArray/prototype/subarray/speciesctor-get-ctor.js fails
-built-ins/TypedArray/prototype/subarray/speciesctor-get-species-abrupt.js fails
-built-ins/TypedArray/prototype/subarray/speciesctor-get-species-custom-ctor-invocation.js fails
-built-ins/TypedArray/prototype/subarray/speciesctor-get-species-custom-ctor-returns-another-instance.js fails
-built-ins/TypedArray/prototype/subarray/speciesctor-get-species-custom-ctor.js fails
-built-ins/TypedArray/prototype/subarray/speciesctor-get-species-use-default-ctor.js fails
-built-ins/TypedArray/prototype/subarray/speciesctor-get-species.js fails
-built-ins/TypedArray/prototype/toLocaleString/calls-tolocalestring-from-each-value.js fails
-built-ins/TypedArray/prototype/toLocaleString/calls-tostring-from-each-value.js fails
-built-ins/TypedArray/prototype/toLocaleString/calls-valueof-from-each-value.js fails
-built-ins/TypedArray/prototype/toLocaleString/detached-buffer.js fails
-built-ins/TypedArray/prototype/toLocaleString/empty-instance-returns-empty-string.js fails
-built-ins/TypedArray/prototype/toLocaleString/invoked-as-method.js fails
-built-ins/TypedArray/prototype/toLocaleString/prop-desc.js fails
-built-ins/TypedArray/prototype/toLocaleString/return-abrupt-from-firstelement-tolocalestring.js fails
-built-ins/TypedArray/prototype/toLocaleString/return-abrupt-from-firstelement-tostring.js fails
-built-ins/TypedArray/prototype/toLocaleString/return-abrupt-from-firstelement-valueof.js fails
-built-ins/TypedArray/prototype/toLocaleString/return-abrupt-from-nextelement-tolocalestring.js fails
-built-ins/TypedArray/prototype/toLocaleString/return-abrupt-from-nextelement-tostring.js fails
-built-ins/TypedArray/prototype/toLocaleString/return-abrupt-from-nextelement-valueof.js fails
-built-ins/TypedArray/prototype/toLocaleString/return-result.js fails
-built-ins/TypedArray/prototype/toLocaleString/this-is-not-object.js fails
-built-ins/TypedArray/prototype/toLocaleString/this-is-not-typedarray-instance.js fails
-built-ins/TypedArray/prototype/toString.js fails
-built-ins/TypedArray/prototype/toString/detached-buffer.js fails
-built-ins/TypedArray/prototype/values/detached-buffer.js fails
built-ins/TypedArrays/ctors/buffer-arg/custom-proto-access-throws.js fails
built-ins/TypedArrays/ctors/buffer-arg/defined-negative-length.js fails
built-ins/TypedArrays/ctors/buffer-arg/proto-from-ctor-realm.js fails
@@ -1249,16 +771,7 @@ built-ins/TypedArrays/internals/Set/detached-buffer.js fails
built-ins/TypedArrays/internals/Set/key-is-minus-zero.js fails
built-ins/TypedArrays/internals/Set/key-is-not-integer.js fails
built-ins/TypedArrays/internals/Set/key-is-out-of-bounds.js fails
-built-ins/TypedArrays/internals/Set/tonumber-value-detached-buffer.js fails
built-ins/TypedArrays/internals/Set/tonumber-value-throws.js strictFails
-built-ins/TypedArrays/of/argument-number-value-throws.js fails
-built-ins/TypedArrays/of/custom-ctor-returns-other-instance.js fails
-built-ins/TypedArrays/of/custom-ctor.js fails
-built-ins/TypedArrays/of/nan-conversion.js fails
-built-ins/TypedArrays/of/new-instance-empty.js fails
-built-ins/TypedArrays/of/new-instance-from-zero.js fails
-built-ins/TypedArrays/of/new-instance-using-custom-ctor.js fails
-built-ins/TypedArrays/of/new-instance.js fails
built-ins/WeakMap/constructor.js fails
built-ins/WeakMap/empty-iterable.js fails
built-ins/WeakMap/get-set-method-failure.js fails
@@ -1694,7 +1207,6 @@ language/expressions/generators/yield-identifier-non-strict.js sloppyFails
language/expressions/generators/yield-star-before-newline.js fails
language/expressions/logical-and/tco-right.js strictFails
language/expressions/logical-or/tco-right.js strictFails
-language/expressions/new.target/value-via-reflect-construct.js fails
language/expressions/new.target/value-via-super-call.js fails
language/expressions/new.target/value-via-super-property.js fails
language/expressions/new/non-ctor-err-realm.js fails
@@ -1960,7 +1472,6 @@ language/statements/class/subclass/builtin-objects/WeakSet/super-must-be-called.
language/statements/class/subclass/builtins.js fails
language/statements/class/subclass/class-definition-null-proto-super.js fails
language/statements/class/subclass/class-definition-null-proto-this.js fails
-language/statements/class/subclass/class-definition-superclass-generator.js fails
language/statements/class/subclass/default-constructor-spread-override.js fails
language/statements/class/super/in-methods.js fails
language/statements/const/block-local-closure-get-before-initialization.js fails
diff --git a/tests/auto/qml/ecmascripttests/test262 b/tests/auto/qml/ecmascripttests/test262
-Subproject 6b0c42c63c2492bd0a7a96d3179d122b5f71793
+Subproject 3c69133cc419840c1be34638039cd8c48a7ef58
diff --git a/tests/auto/quick/pointerhandlers/pointerhandlers.pro b/tests/auto/quick/pointerhandlers/pointerhandlers.pro
index df9869315f..950d6835eb 100644
--- a/tests/auto/quick/pointerhandlers/pointerhandlers.pro
+++ b/tests/auto/quick/pointerhandlers/pointerhandlers.pro
@@ -4,10 +4,10 @@ qtConfig(private_tests) {
SUBDIRS += \
flickableinterop \
multipointtoucharea_interop \
- qquickpointerhandler \
- qquickpointhandler \
qquickdraghandler \
+ qquickhoverhandler \
qquickpinchhandler \
+ qquickpointerhandler \
+ qquickpointhandler \
qquicktaphandler \
}
-
diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml
new file mode 100644
index 0000000000..9045247e94
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+
+Rectangle {
+ id: root
+ width: 640
+ height: 480
+ color: "#444"
+
+ Component {
+ id: buttonsAndStuff
+ Column {
+ anchors.fill: parent
+ anchors.margins: 8
+ spacing: 8
+
+ Rectangle {
+ objectName: "buttonWithMA"
+ width: parent.width
+ height: 30
+ color: buttonMA.pressed ? "lightsteelblue" : "#999"
+ border.color: buttonMA.containsMouse ? "cyan" : "transparent"
+
+ MouseArea {
+ id: buttonMA
+ objectName: "buttonMA"
+ hoverEnabled: true
+ anchors.fill: parent
+ onClicked: console.log("clicked MA")
+ }
+
+ Text {
+ anchors.centerIn: parent
+ text: "MouseArea"
+ }
+ }
+
+ Rectangle {
+ objectName: "buttonWithHH"
+ width: parent.width
+ height: 30
+ color: flash ? "#999" : "white"
+ border.color: buttonHH.hovered ? "cyan" : "transparent"
+ property bool flash: true
+
+ HoverHandler {
+ id: buttonHH
+ objectName: "buttonHH"
+ acceptedDevices: PointerDevice.AllDevices
+ }
+
+ TapHandler { }
+
+ Text {
+ anchors.centerIn: parent
+ text: "HoverHandler"
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ id: paddle
+ objectName: "paddle"
+ width: 100
+ height: 40
+ color: paddleHH.hovered ? "indianred" : "#888"
+ x: (parent.width - width) / 2
+ y: parent.height - 100
+ radius: 10
+
+ HoverHandler {
+ id: paddleHH
+ objectName: "paddleHH"
+ }
+ }
+
+ Rectangle {
+ objectName: "topSidebar"
+ radius: 5
+ antialiasing: true
+ x: -radius
+ y: -radius
+ width: 120
+ height: 200
+ border.color: topSidebarHH.hovered ? "cyan" : "black"
+ color: "#777"
+
+ Rectangle {
+ color: "cyan"
+ width: 10
+ height: width
+ radius: width / 2
+ visible: topSidebarHH.hovered
+ x: topSidebarHH.point.position.x - width / 2
+ y: topSidebarHH.point.position.y - height / 2
+ z: 100
+ }
+
+ HoverHandler {
+ id: topSidebarHH
+ objectName: "topSidebarHH"
+ }
+
+ Loader {
+ objectName: "topSidebarLoader"
+ sourceComponent: buttonsAndStuff
+ anchors.fill: parent
+ }
+ }
+
+ Rectangle {
+ objectName: "bottomSidebar"
+ radius: 5
+ antialiasing: true
+ x: -radius
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: -radius
+ width: 120
+ height: 200
+ border.color: bottomSidebarMA.containsMouse ? "cyan" : "black"
+ color: "#777"
+
+ MouseArea {
+ id: bottomSidebarMA
+ objectName: "bottomSidebarMA"
+ hoverEnabled: true
+ anchors.fill: parent
+ }
+
+ Loader {
+ objectName: "bottomSidebarLoader"
+ sourceComponent: buttonsAndStuff
+ anchors.fill: parent
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/qquickhoverhandler.pro b/tests/auto/quick/pointerhandlers/qquickhoverhandler/qquickhoverhandler.pro
new file mode 100644
index 0000000000..34633e2532
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/qquickhoverhandler.pro
@@ -0,0 +1,15 @@
+CONFIG += testcase
+
+TARGET = tst_qquickhoverhandler
+QT += core-private gui-private qml-private quick-private testlib
+
+macos:CONFIG -= app_bundle
+
+SOURCES += tst_qquickhoverhandler.cpp
+
+include (../../../shared/util.pri)
+include (../../shared/util.pri)
+
+TESTDATA = data/*
+
+OTHER_FILES += data/lesHoverables.qml \
diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp b/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp
new file mode 100644
index 0000000000..52074aec4f
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+
+#include <QtQuick/qquickview.h>
+#include <QtQuick/qquickitem.h>
+#include <QtQuick/private/qquickhoverhandler_p.h>
+#include <QtQuick/private/qquickmousearea_p.h>
+#include <qpa/qwindowsysteminterface.h>
+
+#include <private/qquickwindow_p.h>
+
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlproperty.h>
+
+#include "../../../shared/util.h"
+#include "../../shared/viewtestutil.h"
+
+Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests")
+
+static bool isPlatformWayland()
+{
+ return !QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive);
+}
+
+class tst_HoverHandler : public QQmlDataTest
+{
+ Q_OBJECT
+public:
+ tst_HoverHandler()
+ {}
+
+private slots:
+ void hoverHandlerAndUnderlyingHoverHandler();
+ void mouseAreaAndUnderlyingHoverHandler();
+ void hoverHandlerAndUnderlyingMouseArea();
+
+private:
+ void createView(QScopedPointer<QQuickView> &window, const char *fileName);
+};
+
+void tst_HoverHandler::createView(QScopedPointer<QQuickView> &window, const char *fileName)
+{
+ window.reset(new QQuickView);
+ window->setSource(testFileUrl(fileName));
+ QTRY_COMPARE(window->status(), QQuickView::Ready);
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QQuickViewTestUtil::moveMouseAway(window.data());
+
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
+ QVERIFY(window->rootObject() != nullptr);
+}
+
+void tst_HoverHandler::hoverHandlerAndUnderlyingHoverHandler()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "lesHoverables.qml");
+ QQuickView * window = windowPtr.data();
+ QQuickItem * topSidebar = window->rootObject()->findChild<QQuickItem *>("topSidebar");
+ QVERIFY(topSidebar);
+ QQuickItem * button = topSidebar->findChild<QQuickItem *>("buttonWithHH");
+ QVERIFY(button);
+ QQuickHoverHandler *topSidebarHH = topSidebar->findChild<QQuickHoverHandler *>("topSidebarHH");
+ QVERIFY(topSidebarHH);
+ QQuickHoverHandler *buttonHH = button->findChild<QQuickHoverHandler *>("buttonHH");
+ QVERIFY(buttonHH);
+
+ QPoint buttonCenter(button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint());
+ QPoint rightOfButton(button->mapToScene(QPointF(button->width() + 2, button->height() / 2)).toPoint());
+ QPoint outOfSidebar(topSidebar->mapToScene(QPointF(topSidebar->width() + 2, topSidebar->height() / 2)).toPoint());
+ QSignalSpy sidebarHoveredSpy(topSidebarHH, SIGNAL(hoveredChanged()));
+ QSignalSpy buttonHoveredSpy(buttonHH, SIGNAL(hoveredChanged()));
+
+ QTest::mouseMove(window, outOfSidebar);
+ QCOMPARE(topSidebarHH->isHovered(), false);
+ QCOMPARE(sidebarHoveredSpy.count(), 0);
+ QCOMPARE(buttonHH->isHovered(), false);
+ QCOMPARE(buttonHoveredSpy.count(), 0);
+
+ QTest::mouseMove(window, rightOfButton);
+ QCOMPARE(topSidebarHH->isHovered(), true);
+ QCOMPARE(sidebarHoveredSpy.count(), 1);
+ QCOMPARE(buttonHH->isHovered(), false);
+ QCOMPARE(buttonHoveredSpy.count(), 0);
+
+ QTest::mouseMove(window, buttonCenter);
+ QCOMPARE(topSidebarHH->isHovered(), true);
+ QCOMPARE(sidebarHoveredSpy.count(), 1);
+ QCOMPARE(buttonHH->isHovered(), true);
+ QCOMPARE(buttonHoveredSpy.count(), 1);
+
+ QTest::mouseMove(window, rightOfButton);
+ QCOMPARE(topSidebarHH->isHovered(), true);
+ QCOMPARE(sidebarHoveredSpy.count(), 1);
+ QCOMPARE(buttonHH->isHovered(), false);
+ QCOMPARE(buttonHoveredSpy.count(), 2);
+
+ QTest::mouseMove(window, outOfSidebar);
+ QCOMPARE(topSidebarHH->isHovered(), false);
+ QCOMPARE(sidebarHoveredSpy.count(), 2);
+ QCOMPARE(buttonHH->isHovered(), false);
+ QCOMPARE(buttonHoveredSpy.count(), 2);
+}
+
+void tst_HoverHandler::mouseAreaAndUnderlyingHoverHandler()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "lesHoverables.qml");
+ QQuickView * window = windowPtr.data();
+ QQuickItem * topSidebar = window->rootObject()->findChild<QQuickItem *>("topSidebar");
+ QVERIFY(topSidebar);
+ QQuickMouseArea * buttonMA = topSidebar->findChild<QQuickMouseArea *>("buttonMA");
+ QVERIFY(buttonMA);
+ QQuickHoverHandler *topSidebarHH = topSidebar->findChild<QQuickHoverHandler *>("topSidebarHH");
+ QVERIFY(topSidebarHH);
+
+ QPoint buttonCenter(buttonMA->mapToScene(QPointF(buttonMA->width() / 2, buttonMA->height() / 2)).toPoint());
+ QPoint rightOfButton(buttonMA->mapToScene(QPointF(buttonMA->width() + 2, buttonMA->height() / 2)).toPoint());
+ QPoint outOfSidebar(topSidebar->mapToScene(QPointF(topSidebar->width() + 2, topSidebar->height() / 2)).toPoint());
+ QSignalSpy sidebarHoveredSpy(topSidebarHH, SIGNAL(hoveredChanged()));
+ QSignalSpy buttonHoveredSpy(buttonMA, SIGNAL(hoveredChanged()));
+
+ QTest::mouseMove(window, outOfSidebar);
+ QCOMPARE(topSidebarHH->isHovered(), false);
+ QCOMPARE(sidebarHoveredSpy.count(), 0);
+ QCOMPARE(buttonMA->hovered(), false);
+ QCOMPARE(buttonHoveredSpy.count(), 0);
+
+ QTest::mouseMove(window, rightOfButton);
+ QCOMPARE(topSidebarHH->isHovered(), true);
+ QCOMPARE(sidebarHoveredSpy.count(), 1);
+ QCOMPARE(buttonMA->hovered(), false);
+ QCOMPARE(buttonHoveredSpy.count(), 0);
+
+ QTest::mouseMove(window, buttonCenter);
+ QCOMPARE(topSidebarHH->isHovered(), true);
+ QCOMPARE(sidebarHoveredSpy.count(), 1);
+ QCOMPARE(buttonMA->hovered(), true);
+ QCOMPARE(buttonHoveredSpy.count(), 1);
+
+ QTest::mouseMove(window, rightOfButton);
+ QCOMPARE(topSidebarHH->isHovered(), true);
+ QCOMPARE(sidebarHoveredSpy.count(), 1);
+ QCOMPARE(buttonMA->hovered(), false);
+ QCOMPARE(buttonHoveredSpy.count(), 2);
+
+ QTest::mouseMove(window, outOfSidebar);
+ QCOMPARE(topSidebarHH->isHovered(), false);
+ QCOMPARE(sidebarHoveredSpy.count(), 2);
+ QCOMPARE(buttonMA->hovered(), false);
+ QCOMPARE(buttonHoveredSpy.count(), 2);
+}
+
+void tst_HoverHandler::hoverHandlerAndUnderlyingMouseArea()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "lesHoverables.qml");
+ QQuickView * window = windowPtr.data();
+ QQuickItem * bottomSidebar = window->rootObject()->findChild<QQuickItem *>("bottomSidebar");
+ QVERIFY(bottomSidebar);
+ QQuickMouseArea *bottomSidebarMA = bottomSidebar->findChild<QQuickMouseArea *>("bottomSidebarMA");
+ QVERIFY(bottomSidebarMA);
+ QQuickItem * button = bottomSidebar->findChild<QQuickItem *>("buttonWithHH");
+ QVERIFY(button);
+ QQuickHoverHandler *buttonHH = button->findChild<QQuickHoverHandler *>("buttonHH");
+ QVERIFY(buttonHH);
+
+ QPoint buttonCenter(button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint());
+ QPoint rightOfButton(button->mapToScene(QPointF(button->width() + 2, button->height() / 2)).toPoint());
+ QPoint outOfSidebar(bottomSidebar->mapToScene(QPointF(bottomSidebar->width() + 2, bottomSidebar->height() / 2)).toPoint());
+ QSignalSpy sidebarHoveredSpy(bottomSidebarMA, SIGNAL(hoveredChanged()));
+ QSignalSpy buttonHoveredSpy(buttonHH, SIGNAL(hoveredChanged()));
+
+ QTest::mouseMove(window, outOfSidebar);
+ QCOMPARE(bottomSidebarMA->hovered(), false);
+ QCOMPARE(sidebarHoveredSpy.count(), 0);
+ QCOMPARE(buttonHH->isHovered(), false);
+ QCOMPARE(buttonHoveredSpy.count(), 0);
+
+ QTest::mouseMove(window, rightOfButton);
+ QCOMPARE(bottomSidebarMA->hovered(), true);
+ QCOMPARE(sidebarHoveredSpy.count(), 1);
+ QCOMPARE(buttonHH->isHovered(), false);
+ QCOMPARE(buttonHoveredSpy.count(), 0);
+
+ QTest::mouseMove(window, buttonCenter);
+ QCOMPARE(bottomSidebarMA->hovered(), false);
+ QCOMPARE(sidebarHoveredSpy.count(), 2);
+ QCOMPARE(buttonHH->isHovered(), true);
+ QCOMPARE(buttonHoveredSpy.count(), 1);
+
+ QTest::mouseMove(window, rightOfButton);
+ QCOMPARE(bottomSidebarMA->hovered(), true);
+ QCOMPARE(sidebarHoveredSpy.count(), 3);
+ QCOMPARE(buttonHH->isHovered(), false);
+ QCOMPARE(buttonHoveredSpy.count(), 2);
+
+ QTest::mouseMove(window, outOfSidebar);
+ QCOMPARE(bottomSidebarMA->hovered(), false);
+ QCOMPARE(sidebarHoveredSpy.count(), 4);
+ QCOMPARE(buttonHH->isHovered(), false);
+ QCOMPARE(buttonHoveredSpy.count(), 2);
+}
+
+QTEST_MAIN(tst_HoverHandler)
+
+#include "tst_qquickhoverhandler.moc"
diff --git a/tests/auto/quick/qquicklistview/data/snapOneItemWrongDirection.qml b/tests/auto/quick/qquicklistview/data/snapOneItemWrongDirection.qml
new file mode 100644
index 0000000000..f5b7b35d0c
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/snapOneItemWrongDirection.qml
@@ -0,0 +1,18 @@
+import QtQuick 2.0
+
+ListView {
+ width: 400
+ height: 400
+ focus: true
+
+ model: 10
+ delegate: Rectangle {
+ width: parent.width
+ height: 50
+ color: index % 2 ? "blue" : "green"
+ }
+
+ snapMode: ListView.SnapOneItem
+ Keys.onUpPressed: flick(0,500)
+ Keys.onDownPressed: flick(0,-500)
+}
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index 64a186eade..9c11957894 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -182,6 +182,7 @@ private slots:
void snapOneItem_data();
void snapOneItem();
void snapOneItemCurrentIndexRemoveAnimation();
+ void snapOneItemWrongDirection();
void QTBUG_9791();
void QTBUG_33568();
@@ -5672,6 +5673,24 @@ void tst_QQuickListView::snapOneItemCurrentIndexRemoveAnimation()
QCOMPARE(currentIndexSpy.count(), 0);
}
+void tst_QQuickListView::snapOneItemWrongDirection()
+{
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("snapOneItemWrongDirection.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QQuickListView *listview = qobject_cast<QQuickListView*>(window->rootObject());
+ QTRY_VERIFY(listview != nullptr);
+
+ QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
+ QTRY_COMPARE(listview->currentIndex(), 0);
+
+ listview->flick(0,500);
+ QTRY_VERIFY(!listview->isMovingHorizontally());
+ QCOMPARE(listview->contentX(), qreal(0));
+}
+
void tst_QQuickListView::attachedProperties_QTBUG_32836()
{
QScopedPointer<QQuickView> window(createView());
diff --git a/tests/auto/quick/qquicktableview/data/changemodelfromdelegate.qml b/tests/auto/quick/qquicktableview/data/changemodelfromdelegate.qml
new file mode 100644
index 0000000000..79a8e4351a
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/data/changemodelfromdelegate.qml
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Window 2.3
+import TestModel 0.1
+
+Item {
+ width: 640
+ height: 450
+
+ property alias tableView: tableView
+ property bool addRowFromDelegate: false
+
+ onAddRowFromDelegateChanged: {
+ if (!addRowFromDelegate)
+ return;
+ tableModel.addRow(0);
+ tableView.forceLayout();
+ }
+
+ TestModel {
+ id: tableModel
+ rowCount: 1
+ columnCount: 4
+ }
+
+ TableView {
+ id: tableView
+ width: 600
+ height: 400
+ clip: true
+ model: tableModel
+ delegate: tableViewDelegate
+ }
+
+ Component {
+ id: tableViewDelegate
+ Rectangle {
+ objectName: "tableViewDelegate"
+ implicitWidth: 100
+ implicitHeight: 100
+ color: "lightgray"
+ border.width: 1
+
+ Text {
+ anchors.centerIn: parent
+ text: modelData
+ }
+
+ Component.onCompleted: {
+ if (!addRowFromDelegate)
+ return;
+ addRowFromDelegate = false;
+ tableModel.addRow(0);
+ }
+ }
+ }
+
+}
+
diff --git a/tests/auto/quick/qquicktableview/testmodel.h b/tests/auto/quick/qquicktableview/testmodel.h
index 56d5021cec..28ea466b82 100644
--- a/tests/auto/quick/qquicktableview/testmodel.h
+++ b/tests/auto/quick/qquicktableview/testmodel.h
@@ -136,6 +136,11 @@ public:
endResetModel();
}
+ Q_INVOKABLE void addRow(int row)
+ {
+ insertRow(row, QModelIndex());
+ }
+
signals:
void rowCountChanged();
void columnCountChanged();
diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
index ea3531ba13..5e1c21fce8 100644
--- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
+++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
@@ -128,6 +128,7 @@ private slots:
void checkContextPropertiesQQmlListProperyModel_data();
void checkContextPropertiesQQmlListProperyModel();
void checkRowAndColumnChangedButNotIndex();
+ void checkChangingModelFromDelegate();
};
tst_QQuickTableView::tst_QQuickTableView()
@@ -1622,6 +1623,34 @@ void tst_QQuickTableView::checkRowAndColumnChangedButNotIndex()
QCOMPARE(contextColumn, 1);
}
+void tst_QQuickTableView::checkChangingModelFromDelegate()
+{
+ // Check that we don't restart a rebuild of the table
+ // while we're in the middle of rebuilding it from before
+ LOAD_TABLEVIEW("changemodelfromdelegate.qml");
+
+ // Set addRowFromDelegate. This will trigger the QML code to add a new
+ // row and call forceLayout(). When TableView instantiates the first
+ // delegate in the new row, the Component.onCompleted handler will try to
+ // add a new row. But since we're currently rebuilding, this should be
+ // scheduled for later.
+ view->rootObject()->setProperty("addRowFromDelegate", true);
+
+ // We now expect two rows in the table, one more than initially
+ QCOMPARE(tableViewPrivate->tableSize.height(), 2);
+ QCOMPARE(tableViewPrivate->loadedTable.height(), 2);
+
+ // And since the QML code tried to add another row as well, we
+ // expect rebuildScheduled to be true, and a polish event to be pending.
+ QCOMPARE(tableViewPrivate->rebuildScheduled, true);
+ QCOMPARE(tableViewPrivate->polishScheduled, true);
+ WAIT_UNTIL_POLISHED;
+
+ // After handling the polish event, we expect also the third row to now be added
+ QCOMPARE(tableViewPrivate->tableSize.height(), 3);
+ QCOMPARE(tableViewPrivate->loadedTable.height(), 3);
+}
+
QTEST_MAIN(tst_QQuickTableView)
#include "tst_qquicktableview.moc"