From 526d604c23fce27b85906ae11f772c00ae8b14e2 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sun, 2 Jun 2013 16:58:01 +0200 Subject: [PATCH] Allow return statement when parsing bindings An explicit return statement was allowed in bindings with v8 (as they were rewritten as function closures. There's no reason to forbid them now. Fixes two tests in qqmlecmascript. Change-Id: I27a6f88d17d8c35b37735ad321b7607f09b1e67c Reviewed-by: Simon Hausmann --- src/qml/qml/v4/qv4codegen.cpp | 8 ++++---- src/qml/qml/v4/qv4codegen_p.h | 3 ++- src/qml/qml/v4/qv4script.cpp | 3 ++- src/qml/qml/v4/qv4script_p.h | 5 +++-- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/qml/qml/v4/qv4codegen.cpp b/src/qml/qml/v4/qv4codegen.cpp index 1b8473d..fcbca56 100644 --- a/src/qml/qml/v4/qv4codegen.cpp +++ b/src/qml/qml/v4/qv4codegen.cpp @@ -2007,7 +2007,7 @@ V4IR::Expr *Codegen::identifier(const QString &name, int line, int col) f = f->outer; } - if (!e->parent && (!f || !f->insideWithOrCatch) && _mode != EvalCode && (!f || f->name != name)) + if (!e->parent && (!f || !f->insideWithOrCatch) && _mode != EvalCode && _mode != QmlBinding && (!f || f->name != name)) return _block->GLOBALNAME(name, line, col); // global context or with. Lookup by name @@ -2631,7 +2631,7 @@ V4IR::Function *Codegen::defineFunction(const QString &name, AST::Node *ast, } if (args) { V4IR::ExprList *next = function->New(); - next->expr = entryBlock->CONST(V4IR::BoolType, mode == EvalCode); + next->expr = entryBlock->CONST(V4IR::BoolType, (mode == EvalCode || mode == QmlBinding)); next->next = args; args = next; @@ -2819,7 +2819,7 @@ bool Codegen::visit(EmptyStatement *) bool Codegen::visit(ExpressionStatement *ast) { - if (_mode == EvalCode) { + if (_mode == EvalCode || _mode == QmlBinding) { Result e = expression(ast->expression); if (*e) move(_block->TEMP(_returnAddress), *e); @@ -3017,7 +3017,7 @@ bool Codegen::visit(LocalForStatement *ast) bool Codegen::visit(ReturnStatement *ast) { - if (_mode != FunctionCode) + if (_mode != FunctionCode && _mode != QmlBinding) throwSyntaxError(ast->returnToken, QCoreApplication::translate("qv4codegen", "Return statement outside of function")); if (ast->expression) { Result expr = expression(ast->expression); diff --git a/src/qml/qml/v4/qv4codegen_p.h b/src/qml/qml/v4/qv4codegen_p.h index 9e95d89..a4d20e3 100644 --- a/src/qml/qml/v4/qv4codegen_p.h +++ b/src/qml/qml/v4/qv4codegen_p.h @@ -78,7 +78,8 @@ public: enum Mode { GlobalCode, EvalCode, - FunctionCode + FunctionCode, + QmlBinding }; V4IR::Function *operator()(const QString &fileName, diff --git a/src/qml/qml/v4/qv4script.cpp b/src/qml/qml/v4/qv4script.cpp index c0e2495..0e11831 100644 --- a/src/qml/qml/v4/qv4script.cpp +++ b/src/qml/qml/v4/qv4script.cpp @@ -159,7 +159,8 @@ void Script::parse() inheritedLocals.append(*i ? (*i)->toQString() : QString()); Codegen cg(scope, strictMode); - V4IR::Function *globalIRCode = cg(sourceFile, sourceCode, program, &module, QQmlJS::Codegen::EvalCode, inheritedLocals); + V4IR::Function *globalIRCode = cg(sourceFile, sourceCode, program, &module, + parseAsBinding ? QQmlJS::Codegen::QmlBinding : QQmlJS::Codegen::EvalCode, inheritedLocals); QScopedPointer isel(v4->iselFactory->create(v4, &module)); if (inheritContext) isel->setUseFastLookups(false); diff --git a/src/qml/qml/v4/qv4script_p.h b/src/qml/qml/v4/qv4script_p.h index 388d0fa..f46d300 100644 --- a/src/qml/qml/v4/qv4script_p.h +++ b/src/qml/qml/v4/qv4script_p.h @@ -54,11 +54,11 @@ struct Q_QML_EXPORT Script { Script(ExecutionContext *scope, const QString &sourceCode, const QString &source = QString(), int line = 1, int column = 0) : sourceFile(source), line(line), column(column), sourceCode(sourceCode) , scope(scope), strictMode(false), inheritContext(false), parsed(false) - , vmFunction(0) {} + , vmFunction(0), parseAsBinding(false) {} Script(ExecutionEngine *engine, Object *qml, const QString &sourceCode, const QString &source = QString(), int line = 1, int column = 0) : sourceFile(source), line(line), column(column), sourceCode(sourceCode) , scope(engine->rootContext), strictMode(true), inheritContext(true), parsed(false) - , qml(Value::fromObject(qml)), vmFunction(0) {} + , qml(Value::fromObject(qml)), vmFunction(0), parseAsBinding(true) {} QString sourceFile; int line; int column; @@ -69,6 +69,7 @@ struct Q_QML_EXPORT Script { bool parsed; QV4::PersistentValue qml; Function *vmFunction; + bool parseAsBinding; void parse(); Value run(); -- 2.7.4