diff options
-rw-r--r-- | src/qml/jsruntime/jsruntime.pri | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4arrayiterator.cpp | 106 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4arrayiterator_p.h | 114 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4arrayobject.cpp | 42 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4arrayobject_p.h | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 12 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4iterator.cpp | 63 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4iterator_p.h | 76 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4managed.cpp | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4managed_p.h | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4typedarray.cpp | 43 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4typedarray_p.h | 3 | ||||
-rw-r--r-- | tests/auto/qml/ecmascripttests/TestExpectations | 53 |
14 files changed, 479 insertions, 49 deletions
diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri index c7d80d5a82..aa33565851 100644 --- a/src/qml/jsruntime/jsruntime.pri +++ b/src/qml/jsruntime/jsruntime.pri @@ -14,6 +14,7 @@ SOURCES += \ $$PWD/qv4sparsearray.cpp \ $$PWD/qv4arraydata.cpp \ $$PWD/qv4arrayobject.cpp \ + $$PWD/qv4arrayiterator.cpp \ $$PWD/qv4argumentsobject.cpp \ $$PWD/qv4booleanobject.cpp \ $$PWD/qv4dateobject.cpp \ @@ -21,6 +22,7 @@ SOURCES += \ $$PWD/qv4function.cpp \ $$PWD/qv4functionobject.cpp \ $$PWD/qv4globalobject.cpp \ + $$PWD/qv4iterator.cpp \ $$PWD/qv4jsonobject.cpp \ $$PWD/qv4mathobject.cpp \ $$PWD/qv4memberdata.cpp \ @@ -64,6 +66,7 @@ HEADERS += \ $$PWD/qv4sparsearray_p.h \ $$PWD/qv4arraydata_p.h \ $$PWD/qv4arrayobject_p.h \ + $$PWD/qv4arrayiterator_p.h \ $$PWD/qv4argumentsobject_p.h \ $$PWD/qv4booleanobject_p.h \ $$PWD/qv4dateobject_p.h \ @@ -71,6 +74,7 @@ HEADERS += \ $$PWD/qv4function_p.h \ $$PWD/qv4functionobject_p.h \ $$PWD/qv4globalobject_p.h \ + $$PWD/qv4iterator_p.h \ $$PWD/qv4jsonobject_p.h \ $$PWD/qv4mathobject_p.h \ $$PWD/qv4memberdata_p.h \ diff --git a/src/qml/jsruntime/qv4arrayiterator.cpp b/src/qml/jsruntime/qv4arrayiterator.cpp new file mode 100644 index 0000000000..13c036f9a9 --- /dev/null +++ b/src/qml/jsruntime/qv4arrayiterator.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Crimson AS <info@crimson.no> +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml 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$ +** +****************************************************************************/ + +#include <private/qv4iterator_p.h> +#include <private/qv4arrayiterator_p.h> +#include <private/qv4typedarray_p.h> +#include <private/qv4symbol_p.h> + +using namespace QV4; + +DEFINE_OBJECT_VTABLE(ArrayIteratorObject); + +void ArrayIteratorPrototype::init(ExecutionEngine *e) +{ + defineDefaultProperty(QStringLiteral("next"), method_next, 0); + + Scope scope(e); + ScopedString val(scope, e->newString(QLatin1String("Array Iterator"))); + defineReadonlyConfigurableProperty(e->symbol_toStringTag(), val); +} + +ReturnedValue ArrayIteratorPrototype::method_next(const FunctionObject *b, const Value *that, const Value *, int) +{ + Scope scope(b); + const ArrayIteratorObject *thisObject = that->as<ArrayIteratorObject>(); + if (!thisObject) + return scope.engine->throwTypeError(QLatin1String("Not an Array Iterator instance")); + + ScopedObject a(scope, thisObject->d()->iteratedObject); + if (!a) { + QV4::Value undefined = Primitive::undefinedValue(); + return IteratorPrototype::createIterResultObject(scope.engine, undefined, ScopedValue(scope, Primitive::fromBoolean(true)))->asReturnedValue(); + } + + quint32 index = thisObject->d()->nextIndex; + ArrayIteratorKind itemKind = thisObject->d()->iterationKind; + + Scoped<TypedArray> ta(scope, a->as<TypedArray>()); + quint32 len = a->getLength(); + + if (index >= len) { + thisObject->d()->iteratedObject.set(scope.engine, nullptr); + QV4::Value undefined = Primitive::undefinedValue(); + return IteratorPrototype::createIterResultObject(scope.engine, undefined, ScopedValue(scope, Primitive::fromBoolean(true)))->asReturnedValue(); + } + + thisObject->d()->nextIndex = index + 1; + if (itemKind == KeyIteratorKind) { + return IteratorPrototype::createIterResultObject(scope.engine, Primitive::fromInt32(index), ScopedValue(scope, Primitive::fromBoolean(false)))->asReturnedValue(); + } + + ReturnedValue elementValue = a->getIndexed(index); + CHECK_EXCEPTION(); + + if (itemKind == ValueIteratorKind) { + return IteratorPrototype::createIterResultObject(scope.engine, Value::fromReturnedValue(elementValue), ScopedValue(scope, Primitive::fromBoolean(false)))->asReturnedValue(); + } else { + Q_ASSERT(itemKind == KeyValueIteratorKind); + + ScopedArrayObject resultArray(scope, scope.engine->newArrayObject()); + resultArray->arrayReserve(2); + resultArray->arrayPut(0, Primitive::fromInt32(index)); + resultArray->arrayPut(1, Value::fromReturnedValue(elementValue)); + resultArray->setArrayLengthUnchecked(2); + + return IteratorPrototype::createIterResultObject(scope.engine, resultArray, ScopedValue(scope, Primitive::fromBoolean(false)))->asReturnedValue(); + } +} + diff --git a/src/qml/jsruntime/qv4arrayiterator_p.h b/src/qml/jsruntime/qv4arrayiterator_p.h new file mode 100644 index 0000000000..2951c9a763 --- /dev/null +++ b/src/qml/jsruntime/qv4arrayiterator_p.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Crimson AS <info@crimson.no> +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml 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$ +** +****************************************************************************/ + +#ifndef QV4ARRAYITERATOR_P_H +#define QV4ARRAYITERATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qv4object_p.h" +#include "qv4arraydata_p.h" + +QT_BEGIN_NAMESPACE + + +namespace QV4 { + +// ### spec says that this is a string, but I don't see it exposed anywhere, so +// does that matter? +// ### maybe we should share this with other iterator types in the future. +enum ArrayIteratorKind { + KeyIteratorKind, + ValueIteratorKind, + KeyValueIteratorKind +}; + +namespace Heap { + +#define ArrayIteratorObjectMembers(class, Member) \ + Member(class, Pointer, Object *, iteratedObject) \ + Member(class, NoMark, ArrayIteratorKind, iterationKind) \ + Member(class, NoMark, quint32, nextIndex) + +DECLARE_HEAP_OBJECT(ArrayIteratorObject, Object) { + DECLARE_MARKOBJECTS(ArrayIteratorObject); + void init(Object *obj, QV4::ExecutionEngine *engine) + { + Object::init(); + this->iteratedObject.set(engine, obj); + this->nextIndex = 0; + } +}; + +} + +struct ArrayIteratorPrototype : Object +{ + V4_PROTOTYPE(iteratorPrototype) + void init(ExecutionEngine *engine); + + static ReturnedValue method_next(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc); +}; + +struct ArrayIteratorObject : Object +{ + V4_OBJECT2(ArrayIteratorObject, Object) + Q_MANAGED_TYPE(ArrayIteratorObject) + V4_PROTOTYPE(arrayIteratorPrototype) + + void init(ExecutionEngine *engine); +}; + + +} + +QT_END_NAMESPACE + +#endif // QV4ARRAYITERATOR_P_H + 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(); +} + diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h index 3825a600a2..9416176863 100644 --- a/src/qml/jsruntime/qv4arrayobject_p.h +++ b/src/qml/jsruntime/qv4arrayobject_p.h @@ -82,6 +82,7 @@ struct ArrayPrototype: ArrayObject static ReturnedValue method_toString(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_concat(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_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_join(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); @@ -94,6 +95,7 @@ struct ArrayPrototype: ArrayObject 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_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); static ReturnedValue method_every(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); static ReturnedValue method_some(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); @@ -102,6 +104,7 @@ struct ArrayPrototype: ArrayObject static ReturnedValue method_filter(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_values(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); }; diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 22dc984b4a..0bd2894fe3 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -42,6 +42,7 @@ #include <qv4object_p.h> #include <qv4objectproto_p.h> #include <qv4objectiterator_p.h> +#include <qv4arrayiterator_p.h> #include <qv4arrayobject_p.h> #include <qv4booleanobject_p.h> #include <qv4globalobject_p.h> @@ -64,6 +65,7 @@ #include "qv4debugging_p.h" #include "qv4profiling_p.h" #include "qv4executableallocator_p.h" +#include "qv4iterator_p.h" #if QT_CONFIG(qml_sequence_object) #include "qv4sequenceobject_p.h" @@ -402,6 +404,8 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) jsObjects[SyntaxError_Ctor] = memoryManager->allocate<SyntaxErrorCtor>(global); jsObjects[TypeError_Ctor] = memoryManager->allocate<TypeErrorCtor>(global); jsObjects[URIError_Ctor] = memoryManager->allocate<URIErrorCtor>(global); + jsObjects[IteratorProto] = memoryManager->allocate<IteratorPrototype>(); + jsObjects[ArrayIteratorProto] = memoryManager->allocObject<ArrayIteratorPrototype>(newInternalClass(ArrayIteratorPrototype::staticVTable(), iteratorPrototype())); static_cast<ObjectPrototype *>(objectPrototype())->init(this, objectCtor()); static_cast<StringPrototype *>(stringPrototype())->init(this, stringCtor()); @@ -420,6 +424,9 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) static_cast<SyntaxErrorPrototype *>(syntaxErrorPrototype())->init(this, syntaxErrorCtor()); static_cast<TypeErrorPrototype *>(typeErrorPrototype())->init(this, typeErrorCtor()); static_cast<URIErrorPrototype *>(uRIErrorPrototype())->init(this, uRIErrorCtor()); + + static_cast<IteratorPrototype *>(iteratorPrototype())->init(this); + static_cast<ArrayIteratorPrototype *>(arrayIteratorPrototype())->init(this); static_cast<VariantPrototype *>(variantPrototype())->init(); #if QT_CONFIG(qml_sequence_object) @@ -779,6 +786,11 @@ Heap::Object *ExecutionEngine::newForEachIteratorObject(Object *o) return obj->d(); } +Heap::Object *ExecutionEngine::newArrayIteratorObject(Object *o) +{ + return memoryManager->allocate<ArrayIteratorObject>(o->d(), this); +} + Heap::QmlContext *ExecutionEngine::qmlContext() const { if (!currentStackFrame) diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index eaf1fae1af..517d9f88a8 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -185,6 +185,8 @@ public: DataViewProto, ValueTypeProto, SignalHandlerProto, + IteratorProto, + ArrayIteratorProto, Object_Ctor, String_Ctor, @@ -262,6 +264,8 @@ public: Object *valueTypeWrapperPrototype() const { return reinterpret_cast<Object *>(jsObjects + ValueTypeProto); } Object *signalHandlerPrototype() const { return reinterpret_cast<Object *>(jsObjects + SignalHandlerProto); } + Object *iteratorPrototype() const { return reinterpret_cast<Object *>(jsObjects + IteratorProto); } + Object *arrayIteratorPrototype() const { return reinterpret_cast<Object *>(jsObjects + ArrayIteratorProto); } EvalFunction *evalFunction() const { return reinterpret_cast<EvalFunction *>(jsObjects + Eval_Function); } FunctionObject *getStackFunction() const { return reinterpret_cast<FunctionObject *>(jsObjects + GetStack_Function); } @@ -476,6 +480,7 @@ public: Heap::Object *newVariantObject(const QVariant &v); Heap::Object *newForEachIteratorObject(Object *o); + Heap::Object *newArrayIteratorObject(Object *o); Heap::QmlContext *qmlContext() const; QObject *qmlScopeObject() const; diff --git a/src/qml/jsruntime/qv4iterator.cpp b/src/qml/jsruntime/qv4iterator.cpp new file mode 100644 index 0000000000..a97d2c60f2 --- /dev/null +++ b/src/qml/jsruntime/qv4iterator.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml 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$ +** +****************************************************************************/ +#include <qv4iterator_p.h> +#include <qv4symbol_p.h> +#include <qv4engine_p.h> + +using namespace QV4; + +void IteratorPrototype::init(ExecutionEngine *engine) +{ + defineDefaultProperty(engine->symbol_iterator(), method_iterator, 0); +} + +ReturnedValue IteratorPrototype::method_iterator(const FunctionObject *, const Value *thisObject, const Value *, int) +{ + return thisObject->asReturnedValue(); +} + + +Heap::Object *IteratorPrototype::createIterResultObject(ExecutionEngine *engine, const Value &value, const Value &done) +{ + Scope scope(engine); + ScopedObject obj(scope, engine->newObject()); + obj->set(ScopedString(scope, engine->newString(QStringLiteral("value"))), value, Object::DoNotThrow); + obj->set(ScopedString(scope, engine->newString(QStringLiteral("done"))), done, Object::DoNotThrow); + return obj->d(); +} diff --git a/src/qml/jsruntime/qv4iterator_p.h b/src/qml/jsruntime/qv4iterator_p.h new file mode 100644 index 0000000000..16027e64a0 --- /dev/null +++ b/src/qml/jsruntime/qv4iterator_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml 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$ +** +****************************************************************************/ + +#ifndef QV4ITERATOR_P_H +#define QV4ITERATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qv4object_p.h" +#include "qv4arraydata_p.h" + +QT_BEGIN_NAMESPACE + + +namespace QV4 { + +struct IteratorPrototype : Object +{ + void init(ExecutionEngine *engine); + + static ReturnedValue method_iterator(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc); + + static Heap::Object *createIterResultObject(ExecutionEngine *engine, const Value &value, const Value &done); +}; + +} + +QT_END_NAMESPACE + +#endif // QV4ARRAYITERATOR_P_H + diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp index a2e9deb854..d5ed0c0c32 100644 --- a/src/qml/jsruntime/qv4managed.cpp +++ b/src/qml/jsruntime/qv4managed.cpp @@ -122,6 +122,9 @@ QString Managed::className() const case Type_ExecutionContext: s = "__ExecutionContext"; break; + case Type_ArrayIteratorObject: + s = "Array Iterator"; + break; case Type_ForeachIteratorObject: s = "__ForeachIterator"; break; diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h index 5a032ba401..454f4912c0 100644 --- a/src/qml/jsruntime/qv4managed_p.h +++ b/src/qml/jsruntime/qv4managed_p.h @@ -198,6 +198,7 @@ public: Type_ExecutionContext, Type_InternalClass, + Type_ArrayIteratorObject, Type_ForeachIteratorObject, Type_RegExp, diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp index ea931abd1c..81e4deb463 100644 --- a/src/qml/jsruntime/qv4typedarray.cpp +++ b/src/qml/jsruntime/qv4typedarray.cpp @@ -36,10 +36,13 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #include "qv4typedarray_p.h" +#include "qv4arrayiterator_p.h" #include "qv4arraybuffer_p.h" #include "qv4string_p.h" #include "qv4jscall_p.h" +#include "qv4symbol_p.h" #include <cmath> @@ -405,8 +408,12 @@ void TypedArrayPrototype::init(ExecutionEngine *engine, TypedArrayCtor *ctor) defineAccessorProperty(QStringLiteral("length"), method_get_length, nullptr); defineReadonlyProperty(QStringLiteral("BYTES_PER_ELEMENT"), Primitive::fromInt32(operations[ctor->d()->type].bytesPerElement)); + defineDefaultProperty(QStringLiteral("entries"), method_entries, 0); + defineDefaultProperty(QStringLiteral("keys"), method_keys, 0); + defineDefaultProperty(QStringLiteral("values"), method_values, 0); defineDefaultProperty(QStringLiteral("set"), method_set, 1); defineDefaultProperty(QStringLiteral("subarray"), method_subarray, 0); + defineDefaultProperty(engine->symbol_iterator(), method_values, 0); } ReturnedValue TypedArrayPrototype::method_get_buffer(const FunctionObject *b, const Value *thisObject, const Value *, int) @@ -449,6 +456,42 @@ ReturnedValue TypedArrayPrototype::method_get_length(const FunctionObject *b, co return Encode(v->d()->byteLength/v->d()->type->bytesPerElement); } +ReturnedValue TypedArrayPrototype::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<ArrayIteratorObject> ao(scope, scope.engine->newArrayIteratorObject(O)); + ao->d()->iterationKind = ArrayIteratorKind::KeyValueIteratorKind; + return ao->asReturnedValue(); +} + +ReturnedValue TypedArrayPrototype::method_keys(const FunctionObject *b, const Value *thisObject, const Value *, int) +{ + Scope scope(b); + Scoped<TypedArray> O(scope, thisObject); + if (!O) + THROW_TYPE_ERROR(); + + Scoped<ArrayIteratorObject> ao(scope, scope.engine->newArrayIteratorObject(O)); + ao->d()->iterationKind = ArrayIteratorKind::KeyIteratorKind; + return ao->asReturnedValue(); +} + +ReturnedValue TypedArrayPrototype::method_values(const FunctionObject *b, const Value *thisObject, const Value *, int) +{ + Scope scope(b); + Scoped<TypedArray> O(scope, thisObject); + if (!O) + THROW_TYPE_ERROR(); + + Scoped<ArrayIteratorObject> ao(scope, scope.engine->newArrayIteratorObject(O)); + ao->d()->iterationKind = ArrayIteratorKind::ValueIteratorKind; + return ao->asReturnedValue(); +} + ReturnedValue TypedArrayPrototype::method_set(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) { Scope scope(b); diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h index 129c662c97..74561f9c35 100644 --- a/src/qml/jsruntime/qv4typedarray_p.h +++ b/src/qml/jsruntime/qv4typedarray_p.h @@ -158,6 +158,9 @@ struct TypedArrayPrototype : 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_entries(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_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_subarray(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); }; diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations index 97194ede51..a5f6eafaa7 100644 --- a/tests/auto/qml/ecmascripttests/TestExpectations +++ b/tests/auto/qml/ecmascripttests/TestExpectations @@ -126,13 +126,6 @@ built-ins/Array/prototype/copyWithin/return-abrupt-from-target.js fails 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/entries/iteration-mutable.js fails -built-ins/Array/prototype/entries/iteration.js fails -built-ins/Array/prototype/entries/length.js fails -built-ins/Array/prototype/entries/name.js fails -built-ins/Array/prototype/entries/prop-desc.js fails -built-ins/Array/prototype/entries/returns-iterator-from-object.js fails -built-ins/Array/prototype/entries/returns-iterator.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 @@ -179,13 +172,6 @@ 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 -built-ins/Array/prototype/keys/iteration-mutable.js fails -built-ins/Array/prototype/keys/iteration.js fails -built-ins/Array/prototype/keys/length.js fails -built-ins/Array/prototype/keys/name.js fails -built-ins/Array/prototype/keys/prop-desc.js fails -built-ins/Array/prototype/keys/returns-iterator-from-object.js fails -built-ins/Array/prototype/keys/returns-iterator.js fails built-ins/Array/prototype/lastIndexOf/15.4.4.15-3-28.js fails built-ins/Array/prototype/map/create-ctor-non-object.js fails built-ins/Array/prototype/map/create-proto-from-ctor-realm-array.js fails @@ -244,13 +230,6 @@ built-ins/Array/prototype/toLocaleString/primitive_this_value_getter.js strictFa built-ins/Array/prototype/unshift/clamps-to-integer-limit.js fails built-ins/Array/prototype/unshift/length-near-integer-limit.js fails built-ins/Array/prototype/unshift/throws-if-integer-limit-exceeded.js fails -built-ins/Array/prototype/values/iteration-mutable.js fails -built-ins/Array/prototype/values/iteration.js fails -built-ins/Array/prototype/values/length.js fails -built-ins/Array/prototype/values/name.js fails -built-ins/Array/prototype/values/prop-desc.js fails -built-ins/Array/prototype/values/returns-iterator-from-object.js fails -built-ins/Array/prototype/values/returns-iterator.js fails built-ins/ArrayBuffer/Symbol.species/length.js fails built-ins/ArrayBuffer/Symbol.species/return-value.js fails built-ins/ArrayBuffer/Symbol.species/symbol-species-name.js fails @@ -285,18 +264,6 @@ 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/Symbol.toStringTag/property-descriptor.js fails -built-ins/ArrayIteratorPrototype/Symbol.toStringTag/value-direct.js fails -built-ins/ArrayIteratorPrototype/Symbol.toStringTag/value-from-to-string.js fails -built-ins/ArrayIteratorPrototype/next/Float32Array.js fails -built-ins/ArrayIteratorPrototype/next/Float64Array.js fails -built-ins/ArrayIteratorPrototype/next/Int16Array.js fails -built-ins/ArrayIteratorPrototype/next/Int32Array.js fails -built-ins/ArrayIteratorPrototype/next/Int8Array.js fails -built-ins/ArrayIteratorPrototype/next/Uint16Array.js fails -built-ins/ArrayIteratorPrototype/next/Uint32Array.js fails -built-ins/ArrayIteratorPrototype/next/Uint8Array.js fails -built-ins/ArrayIteratorPrototype/next/Uint8ClampedArray.js fails built-ins/ArrayIteratorPrototype/next/args-mapped-expansion-after-exhaustion.js sloppyFails built-ins/ArrayIteratorPrototype/next/args-mapped-expansion-before-exhaustion.js sloppyFails built-ins/ArrayIteratorPrototype/next/args-mapped-iteration.js sloppyFails @@ -306,12 +273,6 @@ built-ins/ArrayIteratorPrototype/next/args-unmapped-expansion-before-exhaustion. built-ins/ArrayIteratorPrototype/next/args-unmapped-iteration.js sloppyFails built-ins/ArrayIteratorPrototype/next/args-unmapped-truncation-before-exhaustion.js sloppyFails built-ins/ArrayIteratorPrototype/next/detach-typedarray-in-progress.js fails -built-ins/ArrayIteratorPrototype/next/iteration-mutable.js fails -built-ins/ArrayIteratorPrototype/next/iteration.js fails -built-ins/ArrayIteratorPrototype/next/length.js fails -built-ins/ArrayIteratorPrototype/next/name.js fails -built-ins/ArrayIteratorPrototype/next/non-own-slots.js fails -built-ins/ArrayIteratorPrototype/next/property-descriptor.js fails built-ins/AsyncFunction/AsyncFunction-construct.js fails built-ins/AsyncFunction/AsyncFunction-is-extensible.js fails built-ins/AsyncFunction/AsyncFunction-is-subclass.js fails @@ -768,10 +729,6 @@ built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-before-nested.js fails built-ins/GeneratorPrototype/throw/try-finally-within-finally.js fails built-ins/GeneratorPrototype/throw/try-finally-within-try.js fails -built-ins/IteratorPrototype/Symbol.iterator/length.js fails -built-ins/IteratorPrototype/Symbol.iterator/name.js fails -built-ins/IteratorPrototype/Symbol.iterator/prop-desc.js fails -built-ins/IteratorPrototype/Symbol.iterator/return-val.js fails built-ins/JSON/Symbol.toStringTag.js fails built-ins/JSON/parse/revived-proxy-revoked.js fails built-ins/JSON/parse/revived-proxy.js fails @@ -2425,11 +2382,9 @@ built-ins/TypedArray/prototype/copyWithin/undefined-end.js fails built-ins/TypedArray/prototype/entries/detached-buffer.js fails built-ins/TypedArray/prototype/entries/invoked-as-func.js fails built-ins/TypedArray/prototype/entries/invoked-as-method.js fails -built-ins/TypedArray/prototype/entries/iter-prototype.js fails built-ins/TypedArray/prototype/entries/length.js fails built-ins/TypedArray/prototype/entries/name.js fails built-ins/TypedArray/prototype/entries/prop-desc.js fails -built-ins/TypedArray/prototype/entries/return-itor.js fails built-ins/TypedArray/prototype/entries/this-is-not-object.js fails built-ins/TypedArray/prototype/entries/this-is-not-typedarray-instance.js fails built-ins/TypedArray/prototype/every/callbackfn-arguments-with-thisarg.js fails @@ -2620,11 +2575,9 @@ built-ins/TypedArray/prototype/join/this-is-not-typedarray-instance.js fails built-ins/TypedArray/prototype/keys/detached-buffer.js fails built-ins/TypedArray/prototype/keys/invoked-as-func.js fails built-ins/TypedArray/prototype/keys/invoked-as-method.js fails -built-ins/TypedArray/prototype/keys/iter-prototype.js fails built-ins/TypedArray/prototype/keys/length.js fails built-ins/TypedArray/prototype/keys/name.js fails built-ins/TypedArray/prototype/keys/prop-desc.js fails -built-ins/TypedArray/prototype/keys/return-itor.js fails built-ins/TypedArray/prototype/keys/this-is-not-object.js fails built-ins/TypedArray/prototype/keys/this-is-not-typedarray-instance.js fails built-ins/TypedArray/prototype/lastIndexOf/detached-buffer.js fails @@ -2863,11 +2816,9 @@ built-ins/TypedArray/prototype/toString/detached-buffer.js fails built-ins/TypedArray/prototype/values/detached-buffer.js fails built-ins/TypedArray/prototype/values/invoked-as-func.js fails built-ins/TypedArray/prototype/values/invoked-as-method.js fails -built-ins/TypedArray/prototype/values/iter-prototype.js fails built-ins/TypedArray/prototype/values/length.js fails built-ins/TypedArray/prototype/values/name.js fails built-ins/TypedArray/prototype/values/prop-desc.js fails -built-ins/TypedArray/prototype/values/return-itor.js fails built-ins/TypedArray/prototype/values/this-is-not-object.js fails built-ins/TypedArray/prototype/values/this-is-not-typedarray-instance.js fails built-ins/TypedArrays/Float32Array/prototype/proto.js fails @@ -3036,12 +2987,16 @@ 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/TypedArrays/prototype/Symbol.iterator.js fails built-ins/TypedArrays/prototype/buffer/inherited.js fails built-ins/TypedArrays/prototype/byteLength/inherited.js fails built-ins/TypedArrays/prototype/byteOffset/inherited.js fails +built-ins/TypedArrays/prototype/entries/inherited.js fails +built-ins/TypedArrays/prototype/keys/inherited.js fails built-ins/TypedArrays/prototype/length/inherited.js fails built-ins/TypedArrays/prototype/set/inherited.js fails built-ins/TypedArrays/prototype/subarray/inherited.js fails +built-ins/TypedArrays/prototype/values/inherited.js fails built-ins/WeakMap/constructor.js fails built-ins/WeakMap/empty-iterable.js fails built-ins/WeakMap/get-set-method-failure.js fails |