From 126d9d7cc35d1cca525091a49412ee6683310128 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Tue, 12 Sep 2017 12:20:16 +0200 Subject: Fix argument order for bound signal expressions Function::updateInternalClass added the arguments in reverse order to the call context object. However, the index of the member is used as the index into CallData::args, so the result would be a reverse order when lookup was done. Now the order is as expected: first argument first. To handle duplicates, another pass is done before adding those arguments so that names are uniques out. Change-Id: Icfb6af2769b7669ff5589ef29f16c23c314758e8 Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4function.cpp | 41 +++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'src/qml/jsruntime/qv4function.cpp') diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index 234e3291d5..879d75e4d5 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -83,22 +83,39 @@ Function::~Function() void Function::updateInternalClass(ExecutionEngine *engine, const QList ¶meters) { - internalClass = engine->internalClasses[EngineBase::Class_CallContext]; + QStringList parameterNames; - // iterate backwards, so we get the right ordering for duplicate names - Scope scope(engine); - ScopedString arg(scope); - for (int i = parameters.size() - 1; i >= 0; --i) { - arg = engine->newString(QString::fromUtf8(parameters.at(i))); - while (1) { - InternalClass *newClass = internalClass->addMember(arg, Attr_NotConfigurable); - if (newClass != internalClass) { - internalClass = newClass; + // Resolve duplicate parameter names: + for (int i = 0, ei = parameters.count(); i != ei; ++i) { + const QByteArray ¶m = parameters.at(i); + int duplicate = -1; + + for (int j = i - 1; j >= 0; --j) { + const QByteArray &prevParam = parameters.at(j); + if (param == prevParam) { + duplicate = j; break; } - // duplicate arguments, need some trick to store them - arg = engine->memoryManager->alloc(arg->d(), engine->newString(QString(0xfffe))); } + + if (duplicate == -1) { + parameterNames.append(QString::fromUtf8(param)); + } else { + const QString &dup = parameterNames[duplicate]; + parameterNames.append(dup); + parameterNames[duplicate] = + QString(0xfffe) + QString::number(duplicate) + dup; + } + + } + + internalClass = engine->internalClasses[EngineBase::Class_CallContext]; + + Scope scope(engine); + ScopedString arg(scope); + for (const QString ¶meterName : parameterNames) { + arg = engine->newString(parameterName); + internalClass = internalClass->addMember(arg, Attr_NotConfigurable); } nFormals = parameters.size(); -- cgit v1.2.1