aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4arrayobject.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2019-10-14 12:12:32 +0200
committerUlf Hermann <ulf.hermann@qt.io>2019-10-21 13:45:22 +0200
commit866f7f3c7b35194aac6b5a4409de847b2363e069 (patch)
tree0e2488e9bd889c287a95464603df26a5909b83ae /src/qml/jsruntime/qv4arrayobject.cpp
parent16cbcc606d431456ef5ab6783705a37d27776207 (diff)
Clean up ArrayPrototype::method_join
The code was really convoluted. Calling join() on anything that doesn't look like an array results in an empty string. Everything else can be handled by the same algorithm. While we're at it, clean up IntrinsicTypedArrayPrototype::method_join in the same way. Change-Id: I016cd2fe069d23387797a7e58020d40cdb8d60cc Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4arrayobject.cpp')
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp72
1 files changed, 35 insertions, 37 deletions
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index af1a2d1de0..d8d0d4739f 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -597,65 +597,63 @@ ReturnedValue ArrayPrototype::method_findIndex(const FunctionObject *b, const Va
return Encode(-1);
}
-ReturnedValue ArrayPrototype::method_join(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+ReturnedValue ArrayPrototype::method_join(const FunctionObject *functionObject,
+ const Value *thisObject, const Value *argv, int argc)
{
- Scope scope(b);
+ Scope scope(functionObject);
ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
return Encode(scope.engine->newString());
- ScopedValue arg(scope, argc ? argv[0] : Value::undefinedValue());
-
- QString r4;
- if (arg->isUndefined())
- r4 = QStringLiteral(",");
- else
- r4 = arg->toQString();
+ // We cannot optimize the resolution of the argument away in case of length == 0
+ // It may have side effects.
+ ScopedValue argument(scope, argc ? argv[0] : Value::undefinedValue());
+ const QString separator = argument->isUndefined()
+ ? QStringLiteral(",")
+ : argument->toQString();
- ScopedValue length(scope, instance->get(scope.engine->id_length()));
- const quint32 r2 = length->isUndefined() ? 0 : length->toUInt32();
-
- if (!r2)
+ ScopedValue scopedLength(scope, instance->get(scope.engine->id_length()));
+ const quint32 genericLength = scopedLength->isUndefined() ? 0 : scopedLength->toUInt32();
+ if (!genericLength)
return Encode(scope.engine->newString());
- QString R;
-
- // ### FIXME
- if (ArrayObject *a = instance->as<ArrayObject>()) {
- ScopedValue e(scope);
- for (uint i = 0; i < a->getLength(); ++i) {
+ QString result;
+ if (auto *arrayObject = instance->as<ArrayObject>()) {
+ ScopedValue entry(scope);
+ const qint64 arrayLength = arrayObject->getLength();
+ Q_ASSERT(arrayLength >= 0);
+ Q_ASSERT(arrayLength <= std::numeric_limits<quint32>::max());
+ for (quint32 i = 0; i < quint32(arrayLength); ++i) {
if (i)
- R += r4;
+ result += separator;
- e = a->get(i);
+ entry = arrayObject->get(i);
CHECK_EXCEPTION();
- if (!e->isNullOrUndefined())
- R += e->toQString();
+ if (!entry->isNullOrUndefined())
+ result += entry->toQString();
}
} else {
- //
- // crazy!
- //
ScopedString name(scope, scope.engine->newString(QStringLiteral("0")));
- ScopedValue r6(scope, instance->get(name));
- if (!r6->isNullOrUndefined())
- R = r6->toQString();
+ ScopedValue value(scope, instance->get(name));
+ CHECK_EXCEPTION();
+
+ if (!value->isNullOrUndefined())
+ result = value->toQString();
- ScopedValue r12(scope);
- for (quint32 k = 1; k < r2; ++k) {
- R += r4;
+ for (quint32 i = 1; i < genericLength; ++i) {
+ result += separator;
- name = Value::fromDouble(k).toString(scope.engine);
- r12 = instance->get(name);
+ name = Value::fromDouble(i).toString(scope.engine);
+ value = instance->get(name);
CHECK_EXCEPTION();
- if (!r12->isNullOrUndefined())
- R += r12->toQString();
+ if (!value->isNullOrUndefined())
+ result += value->toQString();
}
}
- return Encode(scope.engine->newString(R));
+ return Encode(scope.engine->newString(result));
}
ReturnedValue ArrayPrototype::method_pop(const FunctionObject *b, const Value *thisObject, const Value *, int)