From: Lars Knoll Date: Thu, 24 Jan 2013 12:12:26 +0000 (+0100) Subject: Fix the remaining test failures for the with() statement X-Git-Tag: upstream/5.2.1~669^2~659^2~392 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=865a5bf47fb077b654930a84852f189676a7cff3;p=platform%2Fupstream%2Fqtdeclarative.git Fix the remaining test failures for the with() statement Properly pop the pushed scopes for break, continue and return statements inside with() blocks. Change-Id: I7439cd7b7c70819cd5de903395e1b67c394a38c6 Reviewed-by: Simon Hausmann --- diff --git a/qv4codegen.cpp b/qv4codegen.cpp index f16ce68..5ee7159 100644 --- a/qv4codegen.cpp +++ b/qv4codegen.cpp @@ -413,7 +413,7 @@ Codegen::Codegen(VM::ExecutionContext *context, bool strict) , _env(0) , _loop(0) , _labelledStatement(0) - , _tryCleanup(0) + , _scopeAndFinally(0) , _context(context) , _strictMode(strict) , _debugger(context->engine->debugger) @@ -432,7 +432,7 @@ Codegen::Codegen(ErrorHandler *errorHandler, bool strictMode) , _env(0) , _loop(0) , _labelledStatement(0) - , _tryCleanup(0) + , _scopeAndFinally(0) , _context(0) , _strictMode(strictMode) , _debugger(0) @@ -515,7 +515,7 @@ void Codegen::enterLoop(Statement *node, IR::BasicBlock *breakBlock, IR::BasicBl { _loop = new Loop(node, breakBlock, continueBlock, _loop); _loop->labelledStatement = _labelledStatement; // consume the enclosing labelled statement - _loop->tryCleanup = _tryCleanup; + _loop->scopeAndFinally = _scopeAndFinally; _labelledStatement = 0; } @@ -1849,7 +1849,7 @@ IR::Function *Codegen::defineFunction(const QString &name, AST::Node *ast, { qSwap(_mode, mode); // enter function code. - TryCleanup *tryCleanup = 0; + ScopeAndFinally *scopeAndFinally = 0; enterEnvironment(ast); IR::Function *function = _module->newFunction(name, _function); @@ -1914,7 +1914,7 @@ IR::Function *Codegen::defineFunction(const QString &name, AST::Node *ast, qSwap(_exitBlock, exitBlock); qSwap(_throwBlock, throwBlock); qSwap(_returnAddress, returnAddress); - qSwap(_tryCleanup, tryCleanup); + qSwap(_scopeAndFinally, scopeAndFinally); qSwap(_loop, loop); for (FormalParameterList *it = formals; it; it = it->next) { @@ -1948,7 +1948,7 @@ IR::Function *Codegen::defineFunction(const QString &name, AST::Node *ast, qSwap(_exitBlock, exitBlock); qSwap(_throwBlock, throwBlock); qSwap(_returnAddress, returnAddress); - qSwap(_tryCleanup, tryCleanup); + qSwap(_scopeAndFinally, scopeAndFinally); qSwap(_loop, loop); leaveEnvironment(); @@ -2020,7 +2020,7 @@ bool Codegen::visit(BreakStatement *ast) if (!loop) throwSyntaxError(ast->lastSourceLocation(), QCoreApplication::translate("qv4codegen", "Undefined label '%1'").arg(ast->label.toString())); } - unwindException(loop->tryCleanup); + unwindException(loop->scopeAndFinally); _block->JUMP(loop->breakBlock); return false; } @@ -2046,7 +2046,7 @@ bool Codegen::visit(ContinueStatement *ast) } if (!loop) throwSyntaxError(ast->lastSourceLocation(), QCoreApplication::translate("qv4codegen", "continue outside of loop")); - unwindException(loop->tryCleanup); + unwindException(loop->scopeAndFinally); _block->JUMP(loop->continueBlock); return false; } @@ -2394,8 +2394,8 @@ bool Codegen::visit(TryStatement *ast) deleteExceptionArgs->next->init(_block->TEMP(inCatch)); } - TryCleanup tcf(_tryCleanup, ast->finallyExpression, deleteExceptionArgs); - _tryCleanup = &tcf; + ScopeAndFinally tcf(_scopeAndFinally, ast->finallyExpression, deleteExceptionArgs); + _scopeAndFinally = &tcf; _block->CJUMP(_block->TEMP(hasException), catchBody ? catchBody : finallyBody, tryBody); @@ -2438,7 +2438,7 @@ bool Codegen::visit(TryStatement *ast) _block->JUMP(finallyBody); } - _tryCleanup = tcf.parent; + _scopeAndFinally = tcf.parent; IR::BasicBlock *after = _function->newBasicBlock(); _block = finallyBody; @@ -2461,18 +2461,23 @@ bool Codegen::visit(TryStatement *ast) return false; } -void Codegen::unwindException(Codegen::TryCleanup *outest) +void Codegen::unwindException(Codegen::ScopeAndFinally *outest) { - TryCleanup *tryCleanup = _tryCleanup; - qSwap(_tryCleanup, tryCleanup); - while (_tryCleanup != outest) { - _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_delete_exception_handler, 0, 0), _tryCleanup->deleteExceptionArgs)); - TryCleanup *tc = _tryCleanup; - _tryCleanup = tc->parent; - if (tc->finally && tc->finally->statement) - statement(tc->finally->statement); + ScopeAndFinally *scopeAndFinally = _scopeAndFinally; + qSwap(_scopeAndFinally, scopeAndFinally); + while (_scopeAndFinally != outest) { + if (_scopeAndFinally->popScope) { + _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_pop_scope, 0, 0))); + _scopeAndFinally = _scopeAndFinally->parent; + } else { + _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_delete_exception_handler, 0, 0), _scopeAndFinally->deleteExceptionArgs)); + ScopeAndFinally *tc = _scopeAndFinally; + _scopeAndFinally = tc->parent; + if (tc->finally && tc->finally->statement) + statement(tc->finally->statement); + } } - qSwap(_tryCleanup, tryCleanup); + qSwap(_scopeAndFinally, scopeAndFinally); } bool Codegen::visit(VariableStatement *ast) @@ -2514,8 +2519,14 @@ bool Codegen::visit(WithStatement *ast) IR::ExprList *args = _function->New(); args->init(_block->TEMP(withObject)); _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_push_with_scope, 0, 0), args)); + ++_function->insideWith; - statement(ast->statement); + { + ScopeAndFinally scope(_scopeAndFinally); + _scopeAndFinally = &scope; + statement(ast->statement); + _scopeAndFinally = scope.parent; + } --_function->insideWith; _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_pop_scope, 0, 0), 0)); diff --git a/qv4codegen_p.h b/qv4codegen_p.h index 9806198..a8e0fcc 100644 --- a/qv4codegen_p.h +++ b/qv4codegen_p.h @@ -213,13 +213,15 @@ protected: struct UiMember { }; - struct TryCleanup { - TryCleanup *parent; + struct ScopeAndFinally { + ScopeAndFinally *parent; AST::Finally *finally; IR::ExprList *deleteExceptionArgs; + bool popScope; - TryCleanup(TryCleanup *parent, AST::Finally *finally, IR::ExprList *deleteExceptionArgs) - : parent(parent), finally(finally), deleteExceptionArgs(deleteExceptionArgs) + ScopeAndFinally(ScopeAndFinally *parent) : parent(parent), finally(0), deleteExceptionArgs(0), popScope(true) {} + ScopeAndFinally(ScopeAndFinally *parent, AST::Finally *finally, IR::ExprList *deleteExceptionArgs) + : parent(parent), finally(finally), deleteExceptionArgs(deleteExceptionArgs), popScope(false) {} }; @@ -229,7 +231,7 @@ protected: IR::BasicBlock *breakBlock; IR::BasicBlock *continueBlock; Loop *parent; - TryCleanup *tryCleanup; + ScopeAndFinally *scopeAndFinally; Loop(AST::Statement *node, IR::BasicBlock *breakBlock, IR::BasicBlock *continueBlock, Loop *parent) : labelledStatement(0), node(node), breakBlock(breakBlock), continueBlock(continueBlock), parent(parent) {} @@ -260,7 +262,7 @@ protected: const QStringList &inheritedLocals = QStringList()); int indexOfArgument(const QStringRef &string) const; - void unwindException(TryCleanup *outest); + void unwindException(ScopeAndFinally *outest); void statement(AST::Statement *ast); void statement(AST::ExpressionNode *ast); @@ -399,7 +401,7 @@ private: Environment *_env; Loop *_loop; AST::LabelledStatement *_labelledStatement; - TryCleanup *_tryCleanup; + ScopeAndFinally *_scopeAndFinally; QHash _envMap; QHash _functionMap; VM::ExecutionContext *_context; diff --git a/tests/TestExpectations b/tests/TestExpectations index faec629..4193992 100644 --- a/tests/TestExpectations +++ b/tests/TestExpectations @@ -77,15 +77,7 @@ S11.5.3_A3_T2.9 failing S11.5.3_A4_T2 failing S11.8.6_A3 failing S11.8.6_A5_T2 failing -S12.10_A1.4_T4 failing -S12.10_A1.4_T5 failing -S12.10_A1.5_T4 failing -S12.10_A1.5_T5 failing 12.14-13 failing -S12.10_A3.4_T4 failing -S12.10_A3.4_T5 failing -S12.10_A3.5_T4 failing -S12.10_A3.5_T5 failing S13_A15_T4 failing S13_A3_T1 failing 13.1-11-s failing @@ -164,4 +156,4 @@ S12.9_A1_T6 failing S12.9_A1_T7 failing S12.9_A1_T8 failing S12.9_A1_T9 failing -S15.2.4.4_A14 failing +S15.2.4.4_A14 failing \ No newline at end of file