diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-07-03 17:21:31 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-07-30 20:44:50 +0000 |
commit | 1cde99fbafe035cbd88237d8e0a3b52b780f68af (patch) | |
tree | ccc1057c42f6e2768323f1caa069f2236c6163f3 /src/qml/jsruntime/qv4arrayobject.cpp | |
parent | 55d0327ddf2b7b59d686218a9eb7f340732136ef (diff) |
Make Array.prototype.concat comply better with the spec
There are still some failures in the test cases, but at least
less than before.
Change-Id: I5bad4ddb1e9d6fe120e981f806a6d986fd43b64d
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4arrayobject.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4arrayobject.cpp | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 05f6b7dfec..4dbb61298e 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -364,22 +364,31 @@ ReturnedValue ArrayPrototype::method_concat(const FunctionObject *b, const Value ScopedArrayObject result(scope, scope.engine->newArrayObject()); - if (thisObject->isArrayObject()) { - result->copyArrayData(thisObject); - } else { - result->arraySet(0, thisObject); - } - ScopedArrayObject elt(scope); ScopedObject eltAsObj(scope); ScopedValue entry(scope); - for (int i = 0, ei = argc; i < ei; ++i) { - eltAsObj = argv[i]; - elt = argv[i]; + for (int i = -1; i < argc; ++i) { + const Value *v = i == -1 ? thisObject.getPointer() : argv + i; + eltAsObj = *v; + elt = *v; if (elt) { uint n = elt->getLength(); uint newLen = ArrayData::append(result, elt, n); result->setArrayLengthUnchecked(newLen); + } else if (eltAsObj && eltAsObj->isConcatSpreadable()) { + const uint startIndex = result->getLength(); + const uint len = eltAsObj->getLength(); + if (scope.engine->hasException) + return Encode::undefined(); + + for (uint i = 0; i < len; ++i) { + bool hasProperty = false; + entry = eltAsObj->get(i, &hasProperty); + if (hasProperty) { + if (!result->put(startIndex + i, entry)) + return scope.engine->throwTypeError(); + } + } } else if (eltAsObj && eltAsObj->isListType()) { const uint startIndex = result->getLength(); for (int i = 0, len = eltAsObj->getLength(); i < len; ++i) { @@ -388,7 +397,7 @@ ReturnedValue ArrayPrototype::method_concat(const FunctionObject *b, const Value result->put(startIndex + i, entry); } } else { - result->arraySet(result->getLength(), argv[i]); + result->arraySet(result->getLength(), *v); } } |