diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-08-12 23:51:14 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-08-23 08:13:29 +0000 |
commit | c9712699ca7ec8c04afa3cb70afebf4ee146d105 (patch) | |
tree | 6debe8389165296ae5d3ca38806b937174be57d1 /src | |
parent | 1abbc4aa2c3f8f0b76ae524785711dc73fd69120 (diff) |
Implement TypedArray.prototype.copyWithin
Change-Id: If0d33cc40e79d0609ad205cfe5a08d2266403867
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsruntime/qv4arrayobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4typedarray.cpp | 51 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4typedarray_p.h | 1 |
3 files changed, 53 insertions, 1 deletions
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 450916fbf7..544be06664 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -432,7 +432,7 @@ ReturnedValue ArrayPrototype::method_copyWithin(const FunctionObject *b, const V double len = instance->getLength(); double target = argv[0].toInteger(); - double start = argv[1].toInteger(); + double start = argc > 1 ? argv[1].toInteger() : 0; double end = len; if (argc > 2 && !argv[2].isUndefined()) { diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp index 625d0f9961..9b55bd26c7 100644 --- a/src/qml/jsruntime/qv4typedarray.cpp +++ b/src/qml/jsruntime/qv4typedarray.cpp @@ -482,6 +482,56 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_get_length(const FunctionObje return Encode(v->d()->byteLength/v->d()->type->bytesPerElement); } +ReturnedValue IntrinsicTypedArrayPrototype::method_copyWithin(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc) +{ + Scope scope(f); + Scoped<TypedArray> O(scope, thisObject); + if (!O || O->d()->buffer->isDetachedBuffer()) + return scope.engine->throwTypeError(); + + if (!argc) + return O->asReturnedValue(); + + qint64 len = static_cast<uint>(O->length()); + + qint64 to = static_cast<qint64>(argv[0].toInteger()); + if (to < 0) + to = qMax(len + to, 0ll); + else + to = qMin(to, len); + + qint64 from = (argc > 1) ? static_cast<qint64>(argv[1].toInteger()) : 0ll; + if (from < 0) + from = qMax(len + from, 0ll); + else + from = qMin(from, len); + + double fend = argv[2].toInteger(); + if (fend > len) + fend = len; + qint64 end = (argc > 2 && !argv[2].isUndefined()) ? static_cast<qint64>(fend) : len; + if (end < 0) + end = qMax(len + end, 0ll); + else + end = qMin(end, len); + + qint64 count = qMin(end - from, len - to); + + if (count <= 0) + return O->asReturnedValue(); + + if (O->d()->buffer->isDetachedBuffer()) + return scope.engine->throwTypeError(); + + if (from != to) { + int elementSize = O->d()->type->bytesPerElement; + char *data = O->d()->buffer->data->data() + O->d()->byteOffset; + memmove(data + to*elementSize, data + from*elementSize, count*elementSize); + } + + return O->asReturnedValue(); +} + ReturnedValue IntrinsicTypedArrayPrototype::method_entries(const FunctionObject *b, const Value *thisObject, const Value *, int) { Scope scope(b); @@ -721,6 +771,7 @@ void IntrinsicTypedArrayPrototype::init(ExecutionEngine *engine, IntrinsicTypedA defineAccessorProperty(QStringLiteral("byteOffset"), method_get_byteOffset, nullptr); defineAccessorProperty(QStringLiteral("length"), method_get_length, nullptr); + defineDefaultProperty(QStringLiteral("copyWithin"), method_copyWithin, 2); defineDefaultProperty(QStringLiteral("entries"), method_entries, 0); defineDefaultProperty(QStringLiteral("keys"), method_keys, 0); defineDefaultProperty(QStringLiteral("set"), method_set, 1); diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h index 06292b7f8d..8696f5ae4a 100644 --- a/src/qml/jsruntime/qv4typedarray_p.h +++ b/src/qml/jsruntime/qv4typedarray_p.h @@ -174,6 +174,7 @@ struct IntrinsicTypedArrayPrototype : 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_copyWithin(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); |