diff options
Diffstat (limited to 'src')
| -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 |
6 files changed, 26 insertions, 4 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()) { |
