aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Burchell <robin.burchell@crimson.no>2018-05-25 10:44:20 +0200
committerRobin Burchell <robin.burchell@crimson.no>2018-05-25 20:41:55 +0000
commit30b3b8a7603a9963d17cf8520fda7252841cda91 (patch)
tree0604f4dc8bf6df584be3b0a248be48f4c05f8ebb
parenta1ea2b8ec057bca58fdb5e9498e2f302ef0e61b4 (diff)
qv4arrayobject: Implement Array.prototype.includes from ES7
We also add a sameValueZero helper, to make life easier. Remaining failures: built-ins/Array/prototype/includes/get-prop.js fails (due to missing Proxy) built-ins/Array/prototype/includes/length-boundaries.js fails length-boundaries failure is due to strange treatment of edge number values in Value, I think, I haven't yet been able to rectify that one. Change-Id: Idacca528d88fb052d19a5d244662927f502f20d2 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp40
-rw-r--r--src/qml/jsruntime/qv4arrayobject_p.h1
-rw-r--r--src/qml/jsruntime/qv4value.cpp14
-rw-r--r--src/qml/jsruntime/qv4value_p.h3
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations20
5 files changed, 57 insertions, 21 deletions
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index f8398d206d..2c4be85014 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2018 Crimson AS <info@crimson.no>
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
@@ -112,6 +113,7 @@ void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("sort"), method_sort, 1);
defineDefaultProperty(QStringLiteral("splice"), method_splice, 2);
defineDefaultProperty(QStringLiteral("unshift"), method_unshift, 1);
+ defineDefaultProperty(QStringLiteral("includes"), method_includes, 1);
defineDefaultProperty(QStringLiteral("indexOf"), method_indexOf, 1);
defineDefaultProperty(QStringLiteral("keys"), method_keys, 0);
defineDefaultProperty(QStringLiteral("lastIndexOf"), method_lastIndexOf, 1);
@@ -701,6 +703,44 @@ ReturnedValue ArrayPrototype::method_unshift(const FunctionObject *b, const Valu
return Encode(newLen);
}
+ReturnedValue ArrayPrototype::method_includes(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();
+
+ qint64 len = instance->getLength();
+ 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, instance->getIndexed(k));
+ if (val->sameValueZero(argv[0])) {
+ return Encode(true);
+ }
+ k++;
+ }
+
+ return Encode(false);
+}
+
ReturnedValue ArrayPrototype::method_indexOf(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 a8feb65e80..87eabd465a 100644
--- a/src/qml/jsruntime/qv4arrayobject_p.h
+++ b/src/qml/jsruntime/qv4arrayobject_p.h
@@ -94,6 +94,7 @@ struct ArrayPrototype: ArrayObject
static ReturnedValue method_sort(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_splice(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_unshift(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_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);
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index a18dffac1e..85b4297dd6 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -246,6 +246,20 @@ bool Value::sameValue(Value other) const {
return false;
}
+bool Value::sameValueZero(Value other) const {
+ if (_val == other._val)
+ return true;
+ String *s = stringValue();
+ String *os = other.stringValue();
+ if (s && os)
+ return s->isEqualTo(os);
+ if (isInteger() && other.isDouble())
+ return double(int_32()) == other.doubleValue();
+ if (isDouble() && other.isInteger())
+ return other.int_32() == doubleValue();
+ return false;
+}
+
#ifndef V4_BOOTSTRAP
Heap::String *Value::toString(ExecutionEngine *e, Value val)
{
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index a27ae9c9a6..af956e84e1 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -478,8 +478,9 @@ public:
ReturnedValue asReturnedValue() const { return _val; }
static Value fromReturnedValue(ReturnedValue val) { Value v; v._val = val; return v; }
- // Section 9.12
+ // As per ES specs
bool sameValue(Value other) const;
+ bool sameValueZero(Value other) const;
inline void mark(MarkStack *markStack);
diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations
index 3b6170716f..4cb73a13fa 100644
--- a/tests/auto/qml/ecmascripttests/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
@@ -150,28 +150,8 @@ built-ins/Array/prototype/filter/create-proxy.js fails
built-ins/Array/prototype/filter/create-revoked-proxy.js fails
built-ins/Array/prototype/filter/create-species-non-ctor.js fails
built-ins/Array/prototype/filter/create-species.js fails
-built-ins/Array/prototype/includes/fromIndex-equal-or-greater-length-returns-false.js fails
-built-ins/Array/prototype/includes/fromIndex-infinity.js fails
-built-ins/Array/prototype/includes/fromIndex-minus-zero.js fails
built-ins/Array/prototype/includes/get-prop.js fails
built-ins/Array/prototype/includes/length-boundaries.js fails
-built-ins/Array/prototype/includes/length-zero-returns-false.js fails
-built-ins/Array/prototype/includes/length.js fails
-built-ins/Array/prototype/includes/name.js fails
-built-ins/Array/prototype/includes/no-arg.js fails
-built-ins/Array/prototype/includes/prop-desc.js fails
-built-ins/Array/prototype/includes/return-abrupt-get-length.js fails
-built-ins/Array/prototype/includes/return-abrupt-get-prop.js fails
-built-ins/Array/prototype/includes/return-abrupt-tointeger-fromindex.js fails
-built-ins/Array/prototype/includes/return-abrupt-tonumber-length.js fails
-built-ins/Array/prototype/includes/samevaluezero.js fails
-built-ins/Array/prototype/includes/search-found-returns-true.js fails
-built-ins/Array/prototype/includes/search-not-found-returns-false.js fails
-built-ins/Array/prototype/includes/sparse.js fails
-built-ins/Array/prototype/includes/tointeger-fromindex.js fails
-built-ins/Array/prototype/includes/tolength-length.js fails
-built-ins/Array/prototype/includes/using-fromindex.js fails
-built-ins/Array/prototype/includes/values-are-not-cached.js fails
built-ins/Array/prototype/indexOf/15.4.4.14-3-28.js fails
built-ins/Array/prototype/indexOf/15.4.4.14-3-29.js fails
built-ins/Array/prototype/join/S15.4.4.5_A4_T3.js fails