From: Lars Knoll Date: Sun, 2 Dec 2012 18:58:35 +0000 (-0800) Subject: Pass the ExecutionContext into the code generator X-Git-Tag: upstream/5.2.1~669^2~659^2~760 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ecb72cd271992ed4b0b300c6b4ccbde9c3bcc729;p=platform%2Fupstream%2Fqtdeclarative.git Pass the ExecutionContext into the code generator Use the contexts strict mode flag to correctly parse eval code inside strict mode sections. Add code to allow the code generator to throw syntax errors. Change-Id: I4e4258b0d0b88952f4d609ec51bbe8db9a1c66a9 Reviewed-by: Simon Hausmann --- diff --git a/qmljs_objects.cpp b/qmljs_objects.cpp index e0ebc67..e2cb5cf 100644 --- a/qmljs_objects.cpp +++ b/qmljs_objects.cpp @@ -569,7 +569,7 @@ QQmlJS::IR::Function *EvalFunction::parseSource(QQmlJS::VM::ExecutionContext *ct return 0; } - Codegen cg(ctx->engine->debugger); + Codegen cg(ctx); globalCode = cg(program, &module, mode); if (globalCode) { // only generate other functions if global code generation succeeded. diff --git a/qv4codegen.cpp b/qv4codegen.cpp index c9978ed..893bbb1 100644 --- a/qv4codegen.cpp +++ b/qv4codegen.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -206,6 +207,7 @@ protected: inline void enterEnvironment(Node *node) { Environment *e = _cg->newEnvironment(node, _env); + e->isStrict = _cg->_context->strictMode; _envStack.append(e); _env = e; } @@ -248,8 +250,7 @@ protected: || name == QLatin1String("public") || name == QLatin1String("static") || name == QLatin1String("yield")) { - // TODO: error! - qDebug("TODO: give a proper error message @%u:%u", loc.startLine, loc.startColumn); + _cg->throwSyntaxError(loc, "Unexpected strict mode reserved word"); } } } @@ -353,7 +354,7 @@ protected: QStack _envStack; }; -Codegen::Codegen(Debugging::Debugger *debugger) +Codegen::Codegen(VM::ExecutionContext *context) : _module(0) , _function(0) , _block(0) @@ -365,7 +366,8 @@ Codegen::Codegen(Debugging::Debugger *debugger) , _loop(0) , _labelledStatement(0) , _tryCleanup(0) - , _debugger(debugger) + , _context(context) + , _debugger(context->engine->debugger) { } @@ -1021,7 +1023,7 @@ bool Codegen::visit(BinaryExpression *ast) case QSOperator::Assign: if (! (left->asTemp() || left->asName() || left->asSubscript() || left->asMember())) { - assert(!"syntax error"); + throwSyntaxError(ast->lastSourceLocation(), "syntax error"); } if (_expr.accept(nx)) { @@ -1046,7 +1048,7 @@ bool Codegen::visit(BinaryExpression *ast) case QSOperator::InplaceURightShift: case QSOperator::InplaceXor: { if (! (left->asTemp() || left->asName() || left->asSubscript() || left->asMember())) { - assert(!"syntax error"); + throwSyntaxError(ast->lastSourceLocation(), "syntax error"); } if (_expr.accept(nx)) { @@ -1730,7 +1732,7 @@ bool Codegen::visit(BreakStatement *ast) return false; } } - assert(!"throw syntax error"); + throwSyntaxError(ast->lastSourceLocation(), QString("Undefined label '") + ast->label.toString() + QString("'")); } return false; @@ -1752,7 +1754,7 @@ bool Codegen::visit(ContinueStatement *ast) return false; } } - assert(!"throw syntax error"); + throwSyntaxError(ast->lastSourceLocation(), QString("Undefined label '") + ast->label.toString() + QString("'")); } return false; } @@ -2264,3 +2266,13 @@ bool Codegen::visit(UiSourceElement *) assert(!"not implemented"); return false; } + +void Codegen::throwSyntaxError(const SourceLocation &loc, const QString &detail) +{ + VM::DiagnosticMessage *msg = new VM::DiagnosticMessage; + msg->offset = loc.begin(); + msg->startLine = loc.startLine; + msg->startColumn = loc.startColumn; + msg->message = new VM::String(detail); + _context->throwSyntaxError(msg); +} diff --git a/qv4codegen_p.h b/qv4codegen_p.h index a75c872..f1dca06 100644 --- a/qv4codegen_p.h +++ b/qv4codegen_p.h @@ -50,6 +50,10 @@ namespace AST { class UiParameterList; } +namespace VM { +struct ExecutionContext; +} + namespace Debugging { class Debugger; } // namespace Debugging @@ -57,7 +61,7 @@ class Debugger; class Codegen: protected AST::Visitor { public: - Codegen(Debugging::Debugger *debugger); + Codegen(VM::ExecutionContext *ctx); enum Mode { GlobalCode, @@ -329,6 +333,8 @@ protected: virtual bool visit(AST::UiScriptBinding *ast); virtual bool visit(AST::UiSourceElement *ast); + void throwSyntaxError(const AST::SourceLocation &loc, const QString &detail); + private: Result _expr; QString _property; @@ -346,6 +352,7 @@ private: TryCleanup *_tryCleanup; QHash _envMap; QHash _functionMap; + VM::ExecutionContext *_context; Debugging::Debugger *_debugger; class ScanFunctions; diff --git a/qv4ecmaobjects.cpp b/qv4ecmaobjects.cpp index 8edd43c..99375d2 100644 --- a/qv4ecmaobjects.cpp +++ b/qv4ecmaobjects.cpp @@ -1892,7 +1892,7 @@ Value FunctionCtor::construct(ExecutionContext *ctx) IR::Module module; - Codegen cg(ctx->engine->debugger); + Codegen cg(ctx); IR::Function *irf = cg(fe, &module); EvalInstructionSelection *isel = ctx->engine->iselFactory->create(ctx->engine);