Title: [106512] trunk
Revision
106512
Author
[email protected]
Date
2012-02-01 16:08:00 -0800 (Wed, 01 Feb 2012)

Log Message

calling function on catch block scope containing an eval result in wrong this value being passed
https://bugs.webkit.org/show_bug.cgi?id=77581

Reviewed by Oliver Hunt.

_javascript_:function F(){ return 'F' in this; }; try { throw F; } catch (e) { eval(""); alert(e()); }

Source/_javascript_Core: 

* bytecompiler/NodesCodegen.cpp:
(JSC::TryNode::emitBytecode):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
* parser/ASTBuilder.h:
(JSC::ASTBuilder::createTryStatement):
* parser/NodeConstructors.h:
(JSC::TryNode::TryNode):
* parser/Nodes.h:
(TryNode):
* parser/Parser.cpp:
(JSC::::parseTryStatement):
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::createTryStatement):
* runtime/JSObject.h:
(JSObject):
(JSC::JSObject::isStaticScopeObject):
(JSC):

LayoutTests: 

* fast/js/eval-var-decl-expected.txt:
* fast/js/script-tests/eval-var-decl.js:
(checkThis):
(testEvalInCatch):

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (106511 => 106512)


--- trunk/LayoutTests/ChangeLog	2012-02-02 00:01:45 UTC (rev 106511)
+++ trunk/LayoutTests/ChangeLog	2012-02-02 00:08:00 UTC (rev 106512)
@@ -1,3 +1,17 @@
+2012-02-01  Gavin Barraclough  <[email protected]>
+
+        calling function on catch block scope containing an eval result in wrong this value being passed
+        https://bugs.webkit.org/show_bug.cgi?id=77581
+
+        Reviewed by Oliver Hunt.
+
+        _javascript_:function F(){ return 'F' in this; }; try { throw F; } catch (e) { eval(""); alert(e()); }
+
+        * fast/js/eval-var-decl-expected.txt:
+        * fast/js/script-tests/eval-var-decl.js:
+        (checkThis):
+        (testEvalInCatch):
+
 2012-02-01  Florin Malita  <[email protected]>
 
         Backgrounds in HTML inside foreignObject don't draw

Modified: trunk/LayoutTests/fast/js/eval-var-decl-expected.txt (106511 => 106512)


--- trunk/LayoutTests/fast/js/eval-var-decl-expected.txt	2012-02-02 00:01:45 UTC (rev 106511)
+++ trunk/LayoutTests/fast/js/eval-var-decl-expected.txt	2012-02-02 00:08:00 UTC (rev 106512)
@@ -8,6 +8,7 @@
 PASS firstEvalResult is true
 PASS secondEvalResult is false
 PASS thirdEvalResult is true
+PASS testEvalInCatch() is true
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/js/script-tests/eval-var-decl.js (106511 => 106512)


--- trunk/LayoutTests/fast/js/script-tests/eval-var-decl.js	2012-02-02 00:01:45 UTC (rev 106511)
+++ trunk/LayoutTests/fast/js/script-tests/eval-var-decl.js	2012-02-02 00:08:00 UTC (rev 106512)
@@ -22,3 +22,21 @@
     thirdEvalResult = "Threw exception!";
 }
 shouldBeTrue("thirdEvalResult");
+
+// Check that the correct this value is passed to a function called having been caught from a throw, where the catch block contains an eval (bug#).
+function checkThis()
+{
+    "use strict";
+    return this === undefined;
+}
+function testEvalInCatch()
+{
+    try {
+        throw checkThis;
+    } catch(e) {
+        eval('');
+        return e();
+    }
+    return false;
+}
+shouldBeTrue("testEvalInCatch()");

Modified: trunk/Source/_javascript_Core/ChangeLog (106511 => 106512)


--- trunk/Source/_javascript_Core/ChangeLog	2012-02-02 00:01:45 UTC (rev 106511)
+++ trunk/Source/_javascript_Core/ChangeLog	2012-02-02 00:08:00 UTC (rev 106512)
@@ -1,3 +1,31 @@
+2012-02-01  Gavin Barraclough  <[email protected]>
+
+        calling function on catch block scope containing an eval result in wrong this value being passed
+        https://bugs.webkit.org/show_bug.cgi?id=77581
+
+        Reviewed by Oliver Hunt.
+
+        _javascript_:function F(){ return 'F' in this; }; try { throw F; } catch (e) { eval(""); alert(e()); }
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::TryNode::emitBytecode):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createTryStatement):
+        * parser/NodeConstructors.h:
+        (JSC::TryNode::TryNode):
+        * parser/Nodes.h:
+        (TryNode):
+        * parser/Parser.cpp:
+        (JSC::::parseTryStatement):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createTryStatement):
+        * runtime/JSObject.h:
+        (JSObject):
+        (JSC::JSObject::isStaticScopeObject):
+        (JSC):
+
 2012-02-01  Oliver Hunt  <[email protected]>
 
         Add support for inferred function names

Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (106511 => 106512)


--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2012-02-02 00:01:45 UTC (rev 106511)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2012-02-02 00:08:00 UTC (rev 106512)
@@ -1969,13 +1969,7 @@
         // Uncaught exception path: the catch block.
         RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
         RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
-        if (m_catchHasEval) {
-            RefPtr<RegisterID> dynamicScopeObject = generator.emitNewObject(generator.newTemporary());
-            generator.emitPutById(dynamicScopeObject.get(), m_exceptionIdent, exceptionRegister.get());
-            generator.emitMove(exceptionRegister.get(), dynamicScopeObject.get());
-            generator.emitPushScope(exceptionRegister.get());
-        } else
-            generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
+        generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
         generator.emitNode(dst, m_catchBlock);
         generator.emitPopScope();
         generator.emitLabel(catchEndLabel.get());

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (106511 => 106512)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2012-02-02 00:01:45 UTC (rev 106511)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2012-02-02 00:08:00 UTC (rev 106512)
@@ -1324,7 +1324,7 @@
     JSObject* variableObject;
     for (ScopeChainNode* node = scopeChain; ; node = node->next.get()) {
         ASSERT(node);
-        if (node->object->isVariableObject()) {
+        if (node->object->isVariableObject() && !node->object->isStaticScopeObject()) {
             variableObject = static_cast<JSVariableObject*>(node->object.get());
             break;
         }

Modified: trunk/Source/_javascript_Core/parser/ASTBuilder.h (106511 => 106512)


--- trunk/Source/_javascript_Core/parser/ASTBuilder.h	2012-02-02 00:01:45 UTC (rev 106511)
+++ trunk/Source/_javascript_Core/parser/ASTBuilder.h	2012-02-02 00:08:00 UTC (rev 106512)
@@ -419,9 +419,9 @@
         return result;
     }
 
-    StatementNode* createTryStatement(int lineNumber, StatementNode* tryBlock, const Identifier* ident, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine)
+    StatementNode* createTryStatement(int lineNumber, StatementNode* tryBlock, const Identifier* ident, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine)
     {
-        TryNode* result = new (m_globalData) TryNode(lineNumber, tryBlock, *ident, catchHasEval, catchBlock, finallyBlock);
+        TryNode* result = new (m_globalData) TryNode(lineNumber, tryBlock, *ident, catchBlock, finallyBlock);
         if (catchBlock)
             usesCatch();
         result->setLoc(startLine, endLine);

Modified: trunk/Source/_javascript_Core/parser/NodeConstructors.h (106511 => 106512)


--- trunk/Source/_javascript_Core/parser/NodeConstructors.h	2012-02-02 00:01:45 UTC (rev 106511)
+++ trunk/Source/_javascript_Core/parser/NodeConstructors.h	2012-02-02 00:08:00 UTC (rev 106512)
@@ -781,13 +781,12 @@
     {
     }
 
-    inline TryNode::TryNode(int lineNumber, StatementNode* tryBlock, const Identifier& exceptionIdent, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock)
+    inline TryNode::TryNode(int lineNumber, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock)
         : StatementNode(lineNumber)
         , m_tryBlock(tryBlock)
         , m_exceptionIdent(exceptionIdent)
         , m_catchBlock(catchBlock)
         , m_finallyBlock(finallyBlock)
-        , m_catchHasEval(catchHasEval)
     {
     }
 

Modified: trunk/Source/_javascript_Core/parser/Nodes.h (106511 => 106512)


--- trunk/Source/_javascript_Core/parser/Nodes.h	2012-02-02 00:01:45 UTC (rev 106511)
+++ trunk/Source/_javascript_Core/parser/Nodes.h	2012-02-02 00:08:00 UTC (rev 106512)
@@ -1348,7 +1348,7 @@
 
     class TryNode : public StatementNode {
     public:
-        TryNode(int, StatementNode* tryBlock, const Identifier& exceptionIdent, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock);
+        TryNode(int, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1357,7 +1357,6 @@
         const Identifier& m_exceptionIdent;
         StatementNode* m_catchBlock;
         StatementNode* m_finallyBlock;
-        bool m_catchHasEval;
     };
 
     class ParameterNode : public ParserArenaFreeable {

Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (106511 => 106512)


--- trunk/Source/_javascript_Core/parser/Parser.cpp	2012-02-02 00:01:45 UTC (rev 106511)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp	2012-02-02 00:08:00 UTC (rev 106512)
@@ -603,7 +603,6 @@
     ASSERT(match(TRY));
     TreeStatement tryBlock = 0;
     const Identifier* ident = &m_globalData->propertyNames->nullIdentifier;
-    bool catchHasEval = false;
     TreeStatement catchBlock = 0;
     TreeStatement finallyBlock = 0;
     int firstLine = tokenLine();
@@ -626,10 +625,8 @@
         catchScope->preventNewDecls();
         consumeOrFail(CLOSEPAREN);
         matchOrFail(OPENBRACE);
-        int initialEvalCount = context.evalCount();
         catchBlock = parseBlockStatement(context);
         failIfFalseWithMessage(catchBlock, "'try' must have a catch or finally block");
-        catchHasEval = initialEvalCount != context.evalCount();
         failIfFalse(popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo));
     }
     
@@ -640,7 +637,7 @@
         failIfFalse(finallyBlock);
     }
     failIfFalse(catchBlock || finallyBlock);
-    return context.createTryStatement(m_lexer->lastLineNumber(), tryBlock, ident, catchHasEval, catchBlock, finallyBlock, firstLine, lastLine);
+    return context.createTryStatement(m_lexer->lastLineNumber(), tryBlock, ident, catchBlock, finallyBlock, firstLine, lastLine);
 }
 
 template <typename LexerType>

Modified: trunk/Source/_javascript_Core/parser/SyntaxChecker.h (106511 => 106512)


--- trunk/Source/_javascript_Core/parser/SyntaxChecker.h	2012-02-02 00:01:45 UTC (rev 106511)
+++ trunk/Source/_javascript_Core/parser/SyntaxChecker.h	2012-02-02 00:08:00 UTC (rev 106512)
@@ -193,7 +193,7 @@
     int createBreakStatement(int, const Identifier*, int, int, int, int) { return 1; }
     int createContinueStatement(int, int, int, int, int) { return 1; }
     int createContinueStatement(int, const Identifier*, int, int, int, int) { return 1; }
-    int createTryStatement(int, int, const Identifier*, bool, int, int, int, int) { return 1; }
+    int createTryStatement(int, int, const Identifier*, int, int, int, int) { return 1; }
     int createSwitchStatement(int, int, int, int, int, int, int) { return 1; }
     int createWhileStatement(int, int, int, int, int) { return 1; }
     int createWithStatement(int, int, int, int, int, int, int) { return 1; }

Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (106511 => 106512)


--- trunk/Source/_javascript_Core/runtime/JSObject.h	2012-02-02 00:01:45 UTC (rev 106511)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h	2012-02-02 00:08:00 UTC (rev 106512)
@@ -203,6 +203,7 @@
 
         bool isGlobalObject() const;
         bool isVariableObject() const;
+        bool isStaticScopeObject() const;
         bool isActivationObject() const;
         bool isErrorInstance() const;
         bool isGlobalThis() const;
@@ -428,6 +429,11 @@
     return structure()->typeInfo().type() >= VariableObjectType;
 }
 
+inline bool JSObject::isStaticScopeObject() const
+{
+    return structure()->typeInfo().type() == StaticScopeObjectType;
+}
+
 inline bool JSObject::isActivationObject() const
 {
     return structure()->typeInfo().type() == ActivationObjectType;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to