diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-08-14 20:34:37 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-08-23 08:13:42 +0000 |
commit | c1ba78d79647b42e6846edd3de27ff767291d6ee (patch) | |
tree | 2f303cfd51fa1e699bddf522d15f0d0697778067 /src/qml/jsruntime/qv4typedarray.cpp | |
parent | 5ad362938265169af2b85fc0e23ebfb9836907f0 (diff) |
Implement %TypedArray%.prototype.filter
Change-Id: I37bd3ab43f2d896b62fb9afc74e5fe3313b591d2
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4typedarray.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4typedarray.cpp | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp index 124aa724c6..68ac5645ae 100644 --- a/src/qml/jsruntime/qv4typedarray.cpp +++ b/src/qml/jsruntime/qv4typedarray.cpp @@ -625,6 +625,60 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_fill(const FunctionObject *b, return v.asReturnedValue(); } +ReturnedValue IntrinsicTypedArrayPrototype::method_filter(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) +{ + Scope scope(b); + Scoped<TypedArray> instance(scope, thisObject); + if (!instance || instance->d()->buffer->isDetachedBuffer()) + return scope.engine->throwTypeError(); + + uint len = instance->length(); + + if (!argc || !argv->isFunctionObject()) + THROW_TYPE_ERROR(); + const FunctionObject *callback = static_cast<const FunctionObject *>(argv); + + ScopedValue selected(scope); + ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue()); + Value *arguments = scope.alloc(3); + Value *list = arguments; + + uint to = 0; + for (uint k = 0; k < len; ++k) { + if (instance->d()->buffer->isDetachedBuffer()) + return scope.engine->throwTypeError(); + bool exists; + arguments[0] = instance->get(k, &exists); + if (!exists) + continue; + + arguments[1] = Primitive::fromDouble(k); + arguments[2] = instance; + selected = callback->call(that, arguments, 3); + if (selected->toBoolean()) { + ++arguments; + scope.alloc(1); + ++to; + } + } + + const FunctionObject *constructor = instance->speciesConstructor(scope, scope.engine->typedArrayCtors + instance->d()->arrayType); + if (!constructor) + return scope.engine->throwTypeError(); + + arguments = scope.alloc(1); + arguments[0] = Encode(to); + Scoped<TypedArray> a(scope, constructor->callAsConstructor(arguments, 1)); + if (!a || a->d()->buffer->isDetachedBuffer()) + return scope.engine->throwTypeError(); + if (a->length() < to) + return scope.engine->throwTypeError(); + + for (uint i = 0; i < to; ++i) + a->put(i, list[i]); + + return a->asReturnedValue(); +} ReturnedValue IntrinsicTypedArrayPrototype::method_find(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) { @@ -1310,7 +1364,7 @@ ReturnedValue IntrinsicTypedArrayCtor::method_of(const FunctionObject *f, const return scope.engine->throwTypeError(); TypedArray *a = newObj->as<TypedArray>(); Q_ASSERT(a); - if (a->getLength() < len) + if (a->length() < static_cast<uint>(len)) return scope.engine->throwTypeError(); for (int k = 0; k < len; ++k) { @@ -1339,6 +1393,7 @@ void IntrinsicTypedArrayPrototype::init(ExecutionEngine *engine, IntrinsicTypedA defineDefaultProperty(QStringLiteral("entries"), method_entries, 0); defineDefaultProperty(QStringLiteral("every"), method_every, 1); defineDefaultProperty(QStringLiteral("fill"), method_fill, 1); + defineDefaultProperty(QStringLiteral("filter"), method_filter, 1); defineDefaultProperty(QStringLiteral("find"), method_find, 1); defineDefaultProperty(QStringLiteral("findIndex"), method_findIndex, 1); defineDefaultProperty(QStringLiteral("forEach"), method_forEach, 1); |