diff options
author | Robin Burchell <robin.burchell@crimson.no> | 2017-02-09 19:58:50 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-05-02 14:20:13 +0000 |
commit | a4207b2f958e12b01653d8285d9433a77bce9c52 (patch) | |
tree | bd56186a0a0112586379f92429c99be659d7e711 /src/qml/jsruntime/qv4arrayobject.cpp | |
parent | f665c9b25dde5d34f14a47f2aa52f8141bc03fd1 (diff) |
Add Array Iterator objects from ES6 (22.1.5)
And implement / expose them via:
22.1.3.4 - Array.prototype.entries()
22.1.3.13 - Array.prototype.keys()
22.1.3.29 - Array.prototype.values()
22.1.3.31 - Array.prototype[Symbol.iterator]
Most tests for Array iterators now pass.
At the same time, expose them on TypedArray's prototype:
- 22.2.3.15 %TypedArray%.prototype.keys
- 22.2.3.29 %TypedArray%.prototype.values
- 22.2.3.6 %TypedArray%.prototype.entries
- 22.2.3.31 %TypedArray%.prototype[Symbol.iterator]
For TypedArray, test coverage improves a tiny bit (3 passing tests), but the
vast majority fail as it seems like the object structure for TypedArray is
currently incomplete as far as ES6 expects.
It seems that ES6 expects the object structure to be:
* %TypedArray% (inherits FunctionObject)
(this is the TypedArray intrinsic object, and responsible for initializing
the TypedArray instances)
* All the TypedArray ctors (e.g. UInt8Array)
These inherit %TypedArray%, and make a super call to it to do their work
* %TypedArrayPrototype% (inherits Object)
(this is the initial prototype for %TypedArray%)
* All the ctors have their own separate instance of this
* The instances also make use it
So, for instance, a lot of the tests attempt to access the prototype like:
var proto = Object.getPrototypeOf(Int8Array)
var keys = proto.prototype.keys
As ES6 expects Int8Array.prototype to be %TypedArray% (22.2.5), this expands to:
Object.getPrototypeOf(%TypedArray%)
which it expects to be %TypedArrayPrototype%.
But since we have no intrinsic object, and the ctors inherit
FunctionObject, we instead return the wrong prototype into 'var proto'.
Change-Id: I5e1a95a0420ecb70a0e35a5df3f65557510c5925
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4arrayobject.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4arrayobject.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 2bc5ec1de1..4dfe177c12 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -38,12 +38,14 @@ ****************************************************************************/ #include "qv4arrayobject_p.h" +#include "qv4arrayiterator_p.h" #include "qv4sparsearray_p.h" #include "qv4objectproto_p.h" #include "qv4jscall_p.h" #include "qv4argumentsobject_p.h" #include "qv4runtime_p.h" #include "qv4string_p.h" +#include "qv4symbol_p.h" #include <QtCore/qscopedvaluerollback.h> using namespace QV4; @@ -96,6 +98,7 @@ void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(engine->id_toString(), method_toString, 0); defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString, 0); defineDefaultProperty(QStringLiteral("concat"), method_concat, 1); + defineDefaultProperty(QStringLiteral("entries"), method_entries, 0); defineDefaultProperty(QStringLiteral("find"), method_find, 1); defineDefaultProperty(QStringLiteral("findIndex"), method_findIndex, 1); defineDefaultProperty(QStringLiteral("join"), method_join, 1); @@ -108,6 +111,7 @@ void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(QStringLiteral("splice"), method_splice, 2); defineDefaultProperty(QStringLiteral("unshift"), method_unshift, 1); defineDefaultProperty(QStringLiteral("indexOf"), method_indexOf, 1); + defineDefaultProperty(QStringLiteral("keys"), method_keys, 0); defineDefaultProperty(QStringLiteral("lastIndexOf"), method_lastIndexOf, 1); defineDefaultProperty(QStringLiteral("every"), method_every, 1); defineDefaultProperty(QStringLiteral("some"), method_some, 1); @@ -116,6 +120,8 @@ void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(QStringLiteral("filter"), method_filter, 1); defineDefaultProperty(QStringLiteral("reduce"), method_reduce, 1); defineDefaultProperty(QStringLiteral("reduceRight"), method_reduceRight, 1); + defineDefaultProperty(QStringLiteral("values"), method_values, 0); + defineDefaultProperty(engine->symbol_iterator(), method_values, 0); } ReturnedValue ArrayPrototype::method_isArray(const FunctionObject *, const Value *, const Value *argv, int argc) @@ -183,6 +189,18 @@ ReturnedValue ArrayPrototype::method_concat(const FunctionObject *b, const Value return result.asReturnedValue(); } +ReturnedValue ArrayPrototype::method_entries(const FunctionObject *b, const Value *thisObject, const Value *, int) +{ + Scope scope(b); + ScopedObject O(scope, thisObject->toObject(scope.engine)); + if (!O) + RETURN_UNDEFINED(); + + Scoped<ArrayIteratorObject> ao(scope, scope.engine->newArrayIteratorObject(O)); + ao->d()->iterationKind = ArrayIteratorKind::KeyValueIteratorKind; + return ao->asReturnedValue(); +} + ReturnedValue ArrayPrototype::method_find(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) { Scope scope(b); @@ -743,6 +761,18 @@ ReturnedValue ArrayPrototype::method_indexOf(const FunctionObject *b, const Valu return Encode(-1); } +ReturnedValue ArrayPrototype::method_keys(const FunctionObject *f, const Value *thisObject, const Value *, int) +{ + Scope scope(f); + ScopedObject O(scope, thisObject->toObject(scope.engine)); + if (!O) + RETURN_UNDEFINED(); + + Scoped<ArrayIteratorObject> ao(scope, scope.engine->newArrayIteratorObject(O)); + ao->d()->iterationKind = ArrayIteratorKind::KeyIteratorKind; + return ao->asReturnedValue(); +} + ReturnedValue ArrayPrototype::method_lastIndexOf(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) { Scope scope(b); @@ -1058,3 +1088,15 @@ ReturnedValue ArrayPrototype::method_reduceRight(const FunctionObject *b, const return acc->asReturnedValue(); } +ReturnedValue ArrayPrototype::method_values(const FunctionObject *b, const Value *thisObject, const Value *, int) +{ + Scope scope(b); + ScopedObject O(scope, thisObject->toObject(scope.engine)); + if (!O) + RETURN_UNDEFINED(); + + Scoped<ArrayIteratorObject> ao(scope, scope.engine->newArrayIteratorObject(O)); + ao->d()->iterationKind = ArrayIteratorKind::ValueIteratorKind; + return ao->asReturnedValue(); +} + |