aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp37
-rw-r--r--src/qml/jsruntime/qv4arrayobject_p.h1
-rw-r--r--src/qml/jsruntime/qv4object_p.h17
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations13
4 files changed, 55 insertions, 13 deletions
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index c04edbe872..f8398d206d 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -116,6 +116,7 @@ void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("keys"), method_keys, 0);
defineDefaultProperty(QStringLiteral("lastIndexOf"), method_lastIndexOf, 1);
defineDefaultProperty(QStringLiteral("every"), method_every, 1);
+ defineDefaultProperty(QStringLiteral("fill"), method_fill, 1);
defineDefaultProperty(QStringLiteral("some"), method_some, 1);
defineDefaultProperty(QStringLiteral("forEach"), method_forEach, 1);
defineDefaultProperty(QStringLiteral("map"), method_map, 1);
@@ -854,6 +855,42 @@ ReturnedValue ArrayPrototype::method_every(const FunctionObject *b, const Value
return Encode(ok);
}
+ReturnedValue ArrayPrototype::method_fill(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
+ if (!instance)
+ RETURN_UNDEFINED();
+
+ uint len = instance->getLength();
+ int relativeStart = argc > 1 ? argv[1].toInteger() : 0;
+ int relativeEnd = len;
+ if (argc > 2 && !argv[2].isUndefined()) {
+ relativeEnd = argv[2].toInteger();
+ }
+ uint k = 0;
+ uint fin = 0;
+
+ if (relativeStart < 0) {
+ k = std::max(len+relativeStart, uint(0));
+ } else {
+ k = std::min(uint(relativeStart), len);
+ }
+
+ if (relativeEnd < 0) {
+ fin = std::max(len + relativeEnd, uint(0));
+ } else {
+ fin = std::min(uint(relativeEnd), len);
+ }
+
+ while (k < fin) {
+ instance->setIndexed(k, argv[0], QV4::Object::DoThrowOnRejection);
+ k++;
+ }
+
+ return instance.asReturnedValue();
+}
+
ReturnedValue ArrayPrototype::method_some(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h
index 31067b0c39..a8feb65e80 100644
--- a/src/qml/jsruntime/qv4arrayobject_p.h
+++ b/src/qml/jsruntime/qv4arrayobject_p.h
@@ -98,6 +98,7 @@ struct ArrayPrototype: ArrayObject
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_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_some(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_map(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 7cc99376be..5ad67635db 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -385,6 +385,23 @@ public:
DoNotThrow
};
+ // This is the same as set(), but it doesn't require creating a string key,
+ // which is much more efficient for the array case.
+ inline bool setIndexed(uint idx, const Value &v, ThrowOnFailure shouldThrow)
+ {
+ bool ret = vtable()->putIndexed(this, idx, v);
+ // ES6: 7.3.3, 6: If success is false and Throw is true, throw a TypeError exception.
+ if (!ret && shouldThrow == ThrowOnFailure::DoThrowOnRejection) {
+ ExecutionEngine *e = engine();
+ if (!e->hasException) { // allow a custom set impl to throw itself
+ QString message = QLatin1String("Cannot assign to read-only property \"") +
+ QString::number(idx) + QLatin1Char('\"');
+ e->throwTypeError(message);
+ }
+ }
+ return ret;
+ }
+
// ES6: 7.3.3 Set (O, P, V, Throw)
inline bool set(StringOrSymbol *name, const Value &v, ThrowOnFailure shouldThrow)
{
diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations
index 626b1a39a4..3b6170716f 100644
--- a/tests/auto/qml/ecmascripttests/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
@@ -143,19 +143,6 @@ built-ins/Array/prototype/copyWithin/return-abrupt-from-this-length.js fails
built-ins/Array/prototype/copyWithin/return-this.js fails
built-ins/Array/prototype/copyWithin/undefined-end.js fails
built-ins/Array/prototype/every/15.4.4.16-3-29.js fails
-built-ins/Array/prototype/fill/coerced-indexes.js fails
-built-ins/Array/prototype/fill/fill-values-custom-start-and-end.js fails
-built-ins/Array/prototype/fill/fill-values-relative-end.js fails
-built-ins/Array/prototype/fill/fill-values-relative-start.js fails
-built-ins/Array/prototype/fill/fill-values.js fails
-built-ins/Array/prototype/fill/length.js fails
-built-ins/Array/prototype/fill/name.js fails
-built-ins/Array/prototype/fill/prop-desc.js fails
-built-ins/Array/prototype/fill/return-abrupt-from-end.js fails
-built-ins/Array/prototype/fill/return-abrupt-from-setting-property-value.js fails
-built-ins/Array/prototype/fill/return-abrupt-from-start.js fails
-built-ins/Array/prototype/fill/return-abrupt-from-this-length.js fails
-built-ins/Array/prototype/fill/return-this.js fails
built-ins/Array/prototype/filter/create-ctor-non-object.js fails
built-ins/Array/prototype/filter/create-proto-from-ctor-realm-array.js fails
built-ins/Array/prototype/filter/create-proto-from-ctor-realm-non-array.js fails