diff options
author | Robin Burchell <robin.burchell@crimson.no> | 2018-05-25 10:44:20 +0200 |
---|---|---|
committer | Robin Burchell <robin.burchell@crimson.no> | 2018-05-25 20:41:55 +0000 |
commit | 30b3b8a7603a9963d17cf8520fda7252841cda91 (patch) | |
tree | 0604f4dc8bf6df584be3b0a248be48f4c05f8ebb | |
parent | a1ea2b8ec057bca58fdb5e9498e2f302ef0e61b4 (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.cpp | 40 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4arrayobject_p.h | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4value.cpp | 14 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4value_p.h | 3 | ||||
-rw-r--r-- | tests/auto/qml/ecmascripttests/TestExpectations | 20 |
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 |