Fix the remaining test failures for the with() statement
authorLars Knoll <lars.knoll@digia.com>
Thu, 24 Jan 2013 12:12:26 +0000 (13:12 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Thu, 24 Jan 2013 12:15:46 +0000 (13:15 +0100)
Properly pop the pushed scopes for break, continue and return
statements inside with() blocks.

Change-Id: I7439cd7b7c70819cd5de903395e1b67c394a38c6
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
qv4codegen.cpp
qv4codegen_p.h
tests/TestExpectations

index f16ce68..5ee7159 100644 (file)
@@ -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<IR::ExprList>();
     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));
 
index 9806198..a8e0fcc 100644 (file)
@@ -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<AST::Node *, Environment *> _envMap;
     QHash<AST::FunctionExpression *, int> _functionMap;
     VM::ExecutionContext *_context;
index faec629..4193992 100644 (file)
@@ -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