aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp98
-rw-r--r--src/qml/jsruntime/qv4typedarray_p.h1
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations29
3 files changed, 75 insertions, 53 deletions
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index 5037b8a061..c52526d686 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -625,6 +625,24 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_fill(const FunctionObject *b,
return v.asReturnedValue();
}
+static TypedArray *typedArraySpeciesCreate(Scope &scope, const TypedArray *instance, uint len)
+{
+ const FunctionObject *constructor = instance->speciesConstructor(scope, scope.engine->typedArrayCtors + instance->d()->arrayType);
+ if (!constructor) {
+ scope.engine->throwTypeError();
+ return nullptr;
+ }
+
+ Value *arguments = scope.alloc(1);
+ arguments[0] = Encode(len);
+ Scoped<TypedArray> a(scope, constructor->callAsConstructor(arguments, 1));
+ if (!a || a->d()->buffer->isDetachedBuffer() || a->length() < len) {
+ scope.engine->throwTypeError();
+ return nullptr;
+ }
+ return a;
+}
+
ReturnedValue IntrinsicTypedArrayPrototype::method_filter(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
@@ -662,17 +680,9 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_filter(const FunctionObject *
}
}
- 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();
+ TypedArray *a = typedArraySpeciesCreate(scope, instance, to);
+ if (!a)
+ return Encode::undefined();
for (uint i = 0; i < to; ++i)
a->put(i, list[i]);
@@ -985,22 +995,14 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_map(const FunctionObject *b,
THROW_TYPE_ERROR();
const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
- const FunctionObject *constructor = instance->speciesConstructor(scope, scope.engine->typedArrayCtors + instance->d()->arrayType);
- if (!constructor)
- return scope.engine->throwTypeError();
-
- Value *arguments = scope.alloc(1);
- arguments[0] = Encode(len);
- Scoped<TypedArray> a(scope, constructor->callAsConstructor(arguments, 1));
- if (!a || a->d()->buffer->isDetachedBuffer())
- return scope.engine->throwTypeError();
- if (a->length() < len)
- return scope.engine->throwTypeError();
+ TypedArray *a = typedArraySpeciesCreate(scope, instance, len);
+ if (!a)
+ return Encode::undefined();
ScopedValue v(scope);
ScopedValue mapped(scope);
ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
- arguments = scope.alloc(3);
+ Value *arguments = scope.alloc(3);
for (uint k = 0; k < len; ++k) {
if (instance->d()->buffer->isDetachedBuffer())
@@ -1012,7 +1014,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_map(const FunctionObject *b,
mapped = callback->call(that, arguments, 3);
a->put(k, mapped);
}
- return a.asReturnedValue();
+ return a->asReturnedValue();
}
ReturnedValue IntrinsicTypedArrayPrototype::method_reduce(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
@@ -1285,6 +1287,53 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_set(const FunctionObject *b,
RETURN_UNDEFINED();
}
+ReturnedValue IntrinsicTypedArrayPrototype::method_slice(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();
+
+ double s = (argc ? argv[0] : Primitive::undefinedValue()).toInteger();
+ uint start;
+ if (s < 0)
+ start = (uint)qMax(len + s, 0.);
+ else if (s > len)
+ start = len;
+ else
+ start = (uint) s;
+ uint end = len;
+ if (argc > 1 && !argv[1].isUndefined()) {
+ double e = argv[1].toInteger();
+ if (e < 0)
+ end = (uint)qMax(len + e, 0.);
+ else if (e > len)
+ end = len;
+ else
+ end = (uint) e;
+ }
+ uint count = start > end ? 0 : end - start;
+
+ TypedArray *a = typedArraySpeciesCreate(scope, instance, count);
+ if (!a)
+ return Encode::undefined();
+
+ ScopedValue v(scope);
+ uint n = 0;
+ for (uint i = start; i < end; ++i) {
+ if (instance->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+ v = instance->get(i);
+ if (a->d()->buffer->isDetachedBuffer())
+ return scope.engine->throwTypeError();
+ a->put(n, v);
+ ++n;
+ }
+ return a->asReturnedValue();
+}
+
ReturnedValue IntrinsicTypedArrayPrototype::method_subarray(const FunctionObject *builtin, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(builtin);
@@ -1450,6 +1499,7 @@ void IntrinsicTypedArrayPrototype::init(ExecutionEngine *engine, IntrinsicTypedA
defineDefaultProperty(QStringLiteral("reverse"), method_reverse, 0);
defineDefaultProperty(QStringLiteral("some"), method_some, 1);
defineDefaultProperty(QStringLiteral("set"), method_set, 1);
+ defineDefaultProperty(QStringLiteral("slice"), method_slice, 2);
defineDefaultProperty(QStringLiteral("subarray"), method_subarray, 2);
defineDefaultProperty(engine->id_toLocaleString(), method_toLocaleString, 0);
ScopedObject f(scope, engine->arrayPrototype()->get(engine->id_toString()));
diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h
index 9377d0501c..31698fa6d0 100644
--- a/src/qml/jsruntime/qv4typedarray_p.h
+++ b/src/qml/jsruntime/qv4typedarray_p.h
@@ -194,6 +194,7 @@ struct IntrinsicTypedArrayPrototype : Object
static ReturnedValue method_some(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_slice(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_subarray(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_toLocaleString(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 92e1c7a489..de21ad7fad 100644
--- a/tests/auto/qml/ecmascripttests/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
@@ -684,36 +684,7 @@ built-ins/TypedArray/from/prop-desc.js fails
built-ins/TypedArray/prototype/constructor.js fails
built-ins/TypedArray/prototype/fill/fill-values-conversion-operations-consistent-nan.js fails
built-ins/TypedArray/prototype/set/array-arg-targetbuffer-detached-on-get-src-value-throws.js fails
-built-ins/TypedArray/prototype/slice/arraylength-internal.js fails
built-ins/TypedArray/prototype/slice/bit-precision.js fails
-built-ins/TypedArray/prototype/slice/detached-buffer-zero-count-custom-ctor-other-targettype.js fails
-built-ins/TypedArray/prototype/slice/detached-buffer-zero-count-custom-ctor-same-targettype.js fails
-built-ins/TypedArray/prototype/slice/infinity.js fails
-built-ins/TypedArray/prototype/slice/invoked-as-func.js fails
-built-ins/TypedArray/prototype/slice/invoked-as-method.js fails
-built-ins/TypedArray/prototype/slice/length.js fails
-built-ins/TypedArray/prototype/slice/minus-zero.js fails
-built-ins/TypedArray/prototype/slice/name.js fails
-built-ins/TypedArray/prototype/slice/prop-desc.js fails
-built-ins/TypedArray/prototype/slice/result-does-not-copy-ordinary-properties.js fails
-built-ins/TypedArray/prototype/slice/results-with-different-length.js fails
-built-ins/TypedArray/prototype/slice/results-with-empty-length.js fails
-built-ins/TypedArray/prototype/slice/results-with-same-length.js fails
-built-ins/TypedArray/prototype/slice/return-abrupt-from-end.js fails
-built-ins/TypedArray/prototype/slice/return-abrupt-from-start.js fails
-built-ins/TypedArray/prototype/slice/set-values-from-different-ctor-type.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-ctor-abrupt.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-ctor-inherited.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-ctor.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-species-abrupt.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-species-custom-ctor-invocation.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-species-custom-ctor-length.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-species-custom-ctor-returns-another-instance.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-species-custom-ctor.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-species-use-default-ctor.js fails
-built-ins/TypedArray/prototype/slice/speciesctor-get-species.js fails
-built-ins/TypedArray/prototype/slice/tointeger-end.js fails
-built-ins/TypedArray/prototype/slice/tointeger-start.js fails
built-ins/TypedArray/prototype/sort/arraylength-internal.js fails
built-ins/TypedArray/prototype/sort/comparefn-call-throws.js fails
built-ins/TypedArray/prototype/sort/comparefn-calls.js fails