diff options
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 3 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 1 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 3 | ||||
-rw-r--r-- | src/qml/compiler/qv4compiler.cpp | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast_p.h | 20 | ||||
-rw-r--r-- | tests/auto/qml/ecmascripttests/TestExpectations | 4 |
7 files changed, 26 insertions, 8 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 99811c3779..2b6bda1de3 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -2363,6 +2363,9 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast, Reference arg = referenceForName(e->name, true); initializeAndDestructureBindingElement(e, arg); } else { + if (!formals->next) + // trailing comma + break; Q_UNREACHABLE(); } formals = formals->next; diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index 8f8514535a..59c37fb6c7 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -520,6 +520,7 @@ Unit *CompilationUnit::createUnitData(QmlIR::Document *irDocument) signalParameterNameTable.append(stringTable.getStringId(arg)); function->nFormals = formals.size(); + function->length = function->nFormals; // Hack to ensure an activation is created. function->flags |= QV4::CompiledData::Function::HasCatchOrWith | QV4::CompiledData::Function::HasDirectEval; diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 41c27ffcd4..48bef10c6d 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -219,6 +219,7 @@ struct Function quint32_le codeSize; quint32_le nameIndex; + quint32_le length; quint32_le nFormals; quint32_le formalsOffset; quint32_le nLocals; @@ -276,7 +277,7 @@ struct Function return (a + 7) & ~size_t(7); } }; -static_assert(sizeof(Function) == 76, "Function structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); +static_assert(sizeof(Function) == 80, "Function structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); // Qml data structures diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index bfb450d408..4bc3940a02 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -313,6 +313,7 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte function->nestedFunctionIndex = irFunction->returnsClosure ? quint32(module->functions.indexOf(irFunction->nestedContexts.first())) : std::numeric_limits<uint32_t>::max(); + function->length = irFunction->formals ? irFunction->formals->length() : 0; function->nFormals = irFunction->arguments.size(); function->formalsOffset = currentOffset; currentOffset += function->nFormals * sizeof(quint32); diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 1a26fc857c..327a15361f 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -422,7 +422,7 @@ void Heap::ScriptFunction::init(QV4::ExecutionContext *scope, Function *function ScopedString name(s, function->name()); f->init(name, true); Q_ASSERT(internalClass && internalClass->find(s.engine->id_length()) == Index_Length); - setProperty(s.engine, Index_Length, Primitive::fromInt32(f->formalParameterCount())); + setProperty(s.engine, Index_Length, Primitive::fromInt32(int(function->compiledFunction->length))); } Heap::InternalClass *ScriptFunction::classForConstructor() const diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h index db41528a02..30f6011924 100644 --- a/src/qml/parser/qqmljsast_p.h +++ b/src/qml/parser/qqmljsast_p.h @@ -2307,14 +2307,30 @@ public: if (formals->bindingRestElement()) return false; BindingElement *e = formals->bindingElement(); - Q_ASSERT(e); - if (e->initializer || e->binding) + if (e && (e->initializer || e->binding)) return false; formals = formals->next; } return true; } + int length() + { + // the length property of Function objects + int l = 0; + AST::FormalParameterList *formals = this; + while (formals) { + if (formals->bindingRestElement()) + break; + BindingElement *e = formals->bindingElement(); + if (!e || e->initializer) + break; + ++l; + formals = formals->next; + } + return l; + } + bool containsName(const QString &name) const { for (const FormalParameterList *it = this; it; it = it->next) { if (QQmlJS::AST::BindingElement *b = it->bindingElement()) { diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations index fd30f36c13..5673f3f8a3 100644 --- a/tests/auto/qml/ecmascripttests/TestExpectations +++ b/tests/auto/qml/ecmascripttests/TestExpectations @@ -4128,7 +4128,6 @@ language/expressions/array/spread-sngl-literal language/expressions/arrow-function/cannot-override-this-with-thisArg language/expressions/arrow-function/dflt-params-ref-later language/expressions/arrow-function/dflt-params-ref-self -language/expressions/arrow-function/dflt-params-trailing-comma language/expressions/arrow-function/dstr-ary-init-iter-close language/expressions/arrow-function/dstr-ary-init-iter-get-err language/expressions/arrow-function/dstr-ary-init-iter-no-close @@ -4300,8 +4299,6 @@ language/expressions/arrow-function/lexical-super-call-from-within-constructor language/expressions/arrow-function/lexical-super-property language/expressions/arrow-function/lexical-super-property-from-within-constructor language/expressions/arrow-function/lexical-this -language/expressions/arrow-function/params-trailing-comma-multiple -language/expressions/arrow-function/params-trailing-comma-single language/expressions/arrow-function/prototype-rules language/expressions/arrow-function/scope-body-lex-distinct language/expressions/arrow-function/scope-param-elem-var-close @@ -6802,7 +6799,6 @@ language/module-code/namespace/Symbol.iterator language/module-code/namespace/Symbol.toStringTag language/module-code/parse-export-empty language/rest-parameters/array-pattern -language/rest-parameters/expected-argument-count language/rest-parameters/object-pattern language/rest-parameters/with-new-target language/statements/async-function/cptn-decl |