Title: [158425] trunk
Revision
158425
Author
[email protected]
Date
2013-10-31 22:13:49 -0700 (Thu, 31 Oct 2013)

Log Message

_javascript_ parser bug
https://bugs.webkit.org/show_bug.cgi?id=123506

Reviewed by Mark Lam.

Source/_javascript_Core:

Add ParserState as an abstraction and use that to save and restore
the parser state around nested functions (We'll need to use this in
more places in future).  Also fix a minor error typo this testcases
hit.

* parser/Parser.cpp:
(JSC::::parseFunctionInfo):
(JSC::::parseAssignmentExpression):
* parser/Parser.h:
(JSC::Parser::saveState):
(JSC::Parser::restoreState):

LayoutTests:

Update and add tests

* js/dom/assign-expected.txt:
* js/function-toString-parentheses-expected.txt:
* js/parser-syntax-check-expected.txt:
* js/script-tests/parser-syntax-check.js:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (158424 => 158425)


--- trunk/LayoutTests/ChangeLog	2013-11-01 03:28:59 UTC (rev 158424)
+++ trunk/LayoutTests/ChangeLog	2013-11-01 05:13:49 UTC (rev 158425)
@@ -1,3 +1,17 @@
+2013-10-31  Oliver Hunt  <[email protected]>
+
+        _javascript_ parser bug
+        https://bugs.webkit.org/show_bug.cgi?id=123506
+
+        Reviewed by Mark Lam.
+
+        Update and add tests
+
+        * js/dom/assign-expected.txt:
+        * js/function-toString-parentheses-expected.txt:
+        * js/parser-syntax-check-expected.txt:
+        * js/script-tests/parser-syntax-check.js:
+
 2013-10-31  Ryosuke Niwa  <[email protected]>
 
         Update the test expectations for the bug 121452.

Modified: trunk/LayoutTests/js/dom/assign-expected.txt (158424 => 158425)


--- trunk/LayoutTests/js/dom/assign-expected.txt	2013-11-01 03:28:59 UTC (rev 158424)
+++ trunk/LayoutTests/js/dom/assign-expected.txt	2013-11-01 05:13:49 UTC (rev 158425)
@@ -15,7 +15,7 @@
 PASS ((window["x"])) = 10; x is 10
 PASS (y, x) = "FAIL"; threw exception ReferenceError: Left side of assignment is not a reference..
 PASS (true ? x : y) = "FAIL"; threw exception ReferenceError: Left side of assignment is not a reference..
-PASS x++ = "FAIL"; threw exception SyntaxError: Left hand sign of operator '=' must be a reference..
+PASS x++ = "FAIL"; threw exception SyntaxError: Left hand side of operator '=' must be a reference..
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/js/function-toString-parentheses-expected.txt (158424 => 158425)


--- trunk/LayoutTests/js/function-toString-parentheses-expected.txt	2013-11-01 03:28:59 UTC (rev 158424)
+++ trunk/LayoutTests/js/function-toString-parentheses-expected.txt	2013-11-01 05:13:49 UTC (rev 158425)
@@ -216,7 +216,7 @@
 PASS compileAndSerialize('a = b + c') is 'a = b + c'
 PASS compileAndSerialize('(a = b) + c') is '(a = b) + c'
 PASS compileAndSerialize('a = (b + c)') is 'a = (b + c)'
-PASS compileAndSerialize('a + b = c') threw exception SyntaxError: Left hand sign of operator '=' must be a reference..
+PASS compileAndSerialize('a + b = c') threw exception SyntaxError: Left hand side of operator '=' must be a reference..
 PASS compileAndSerialize('(a + b) = c') is '(a + b) = c'
 PASS compileAndSerialize('a + (b = c)') is 'a + (b = c)'
 PASS compileAndSerialize('a *= b *= c') is 'a *= b *= c'
@@ -228,7 +228,7 @@
 PASS compileAndSerialize('a *= b + c') is 'a *= b + c'
 PASS compileAndSerialize('(a *= b) + c') is '(a *= b) + c'
 PASS compileAndSerialize('a *= (b + c)') is 'a *= (b + c)'
-PASS compileAndSerialize('a + b *= c') threw exception SyntaxError: Left hand sign of operator '*=' must be a reference..
+PASS compileAndSerialize('a + b *= c') threw exception SyntaxError: Left hand side of operator '*=' must be a reference..
 PASS compileAndSerialize('(a + b) *= c') is '(a + b) *= c'
 PASS compileAndSerialize('a + (b *= c)') is 'a + (b *= c)'
 PASS compileAndSerialize('a /= b /= c') is 'a /= b /= c'
@@ -240,7 +240,7 @@
 PASS compileAndSerialize('a /= b + c') is 'a /= b + c'
 PASS compileAndSerialize('(a /= b) + c') is '(a /= b) + c'
 PASS compileAndSerialize('a /= (b + c)') is 'a /= (b + c)'
-PASS compileAndSerialize('a + b /= c') threw exception SyntaxError: Left hand sign of operator '/=' must be a reference..
+PASS compileAndSerialize('a + b /= c') threw exception SyntaxError: Left hand side of operator '/=' must be a reference..
 PASS compileAndSerialize('(a + b) /= c') is '(a + b) /= c'
 PASS compileAndSerialize('a + (b /= c)') is 'a + (b /= c)'
 PASS compileAndSerialize('a %= b %= c') is 'a %= b %= c'
@@ -252,7 +252,7 @@
 PASS compileAndSerialize('a %= b + c') is 'a %= b + c'
 PASS compileAndSerialize('(a %= b) + c') is '(a %= b) + c'
 PASS compileAndSerialize('a %= (b + c)') is 'a %= (b + c)'
-PASS compileAndSerialize('a + b %= c') threw exception SyntaxError: Left hand sign of operator '%=' must be a reference..
+PASS compileAndSerialize('a + b %= c') threw exception SyntaxError: Left hand side of operator '%=' must be a reference..
 PASS compileAndSerialize('(a + b) %= c') is '(a + b) %= c'
 PASS compileAndSerialize('a + (b %= c)') is 'a + (b %= c)'
 PASS compileAndSerialize('a += b += c') is 'a += b += c'
@@ -264,7 +264,7 @@
 PASS compileAndSerialize('a += b + c') is 'a += b + c'
 PASS compileAndSerialize('(a += b) + c') is '(a += b) + c'
 PASS compileAndSerialize('a += (b + c)') is 'a += (b + c)'
-PASS compileAndSerialize('a + b += c') threw exception SyntaxError: Left hand sign of operator '+=' must be a reference..
+PASS compileAndSerialize('a + b += c') threw exception SyntaxError: Left hand side of operator '+=' must be a reference..
 PASS compileAndSerialize('(a + b) += c') is '(a + b) += c'
 PASS compileAndSerialize('a + (b += c)') is 'a + (b += c)'
 PASS compileAndSerialize('a -= b -= c') is 'a -= b -= c'
@@ -276,7 +276,7 @@
 PASS compileAndSerialize('a -= b + c') is 'a -= b + c'
 PASS compileAndSerialize('(a -= b) + c') is '(a -= b) + c'
 PASS compileAndSerialize('a -= (b + c)') is 'a -= (b + c)'
-PASS compileAndSerialize('a + b -= c') threw exception SyntaxError: Left hand sign of operator '-=' must be a reference..
+PASS compileAndSerialize('a + b -= c') threw exception SyntaxError: Left hand side of operator '-=' must be a reference..
 PASS compileAndSerialize('(a + b) -= c') is '(a + b) -= c'
 PASS compileAndSerialize('a + (b -= c)') is 'a + (b -= c)'
 PASS compileAndSerialize('a <<= b <<= c') is 'a <<= b <<= c'
@@ -288,7 +288,7 @@
 PASS compileAndSerialize('a <<= b + c') is 'a <<= b + c'
 PASS compileAndSerialize('(a <<= b) + c') is '(a <<= b) + c'
 PASS compileAndSerialize('a <<= (b + c)') is 'a <<= (b + c)'
-PASS compileAndSerialize('a + b <<= c') threw exception SyntaxError: Left hand sign of operator '<<=' must be a reference..
+PASS compileAndSerialize('a + b <<= c') threw exception SyntaxError: Left hand side of operator '<<=' must be a reference..
 PASS compileAndSerialize('(a + b) <<= c') is '(a + b) <<= c'
 PASS compileAndSerialize('a + (b <<= c)') is 'a + (b <<= c)'
 PASS compileAndSerialize('a >>= b >>= c') is 'a >>= b >>= c'
@@ -300,7 +300,7 @@
 PASS compileAndSerialize('a >>= b + c') is 'a >>= b + c'
 PASS compileAndSerialize('(a >>= b) + c') is '(a >>= b) + c'
 PASS compileAndSerialize('a >>= (b + c)') is 'a >>= (b + c)'
-PASS compileAndSerialize('a + b >>= c') threw exception SyntaxError: Left hand sign of operator '>>=' must be a reference..
+PASS compileAndSerialize('a + b >>= c') threw exception SyntaxError: Left hand side of operator '>>=' must be a reference..
 PASS compileAndSerialize('(a + b) >>= c') is '(a + b) >>= c'
 PASS compileAndSerialize('a + (b >>= c)') is 'a + (b >>= c)'
 PASS compileAndSerialize('a >>>= b >>>= c') is 'a >>>= b >>>= c'
@@ -312,7 +312,7 @@
 PASS compileAndSerialize('a >>>= b + c') is 'a >>>= b + c'
 PASS compileAndSerialize('(a >>>= b) + c') is '(a >>>= b) + c'
 PASS compileAndSerialize('a >>>= (b + c)') is 'a >>>= (b + c)'
-PASS compileAndSerialize('a + b >>>= c') threw exception SyntaxError: Left hand sign of operator '>>>=' must be a reference..
+PASS compileAndSerialize('a + b >>>= c') threw exception SyntaxError: Left hand side of operator '>>>=' must be a reference..
 PASS compileAndSerialize('(a + b) >>>= c') is '(a + b) >>>= c'
 PASS compileAndSerialize('a + (b >>>= c)') is 'a + (b >>>= c)'
 PASS compileAndSerialize('a &= b &= c') is 'a &= b &= c'
@@ -324,7 +324,7 @@
 PASS compileAndSerialize('a &= b + c') is 'a &= b + c'
 PASS compileAndSerialize('(a &= b) + c') is '(a &= b) + c'
 PASS compileAndSerialize('a &= (b + c)') is 'a &= (b + c)'
-PASS compileAndSerialize('a + b &= c') threw exception SyntaxError: Left hand sign of operator '&=' must be a reference..
+PASS compileAndSerialize('a + b &= c') threw exception SyntaxError: Left hand side of operator '&=' must be a reference..
 PASS compileAndSerialize('(a + b) &= c') is '(a + b) &= c'
 PASS compileAndSerialize('a + (b &= c)') is 'a + (b &= c)'
 PASS compileAndSerialize('a ^= b ^= c') is 'a ^= b ^= c'
@@ -336,7 +336,7 @@
 PASS compileAndSerialize('a ^= b + c') is 'a ^= b + c'
 PASS compileAndSerialize('(a ^= b) + c') is '(a ^= b) + c'
 PASS compileAndSerialize('a ^= (b + c)') is 'a ^= (b + c)'
-PASS compileAndSerialize('a + b ^= c') threw exception SyntaxError: Left hand sign of operator '^=' must be a reference..
+PASS compileAndSerialize('a + b ^= c') threw exception SyntaxError: Left hand side of operator '^=' must be a reference..
 PASS compileAndSerialize('(a + b) ^= c') is '(a + b) ^= c'
 PASS compileAndSerialize('a + (b ^= c)') is 'a + (b ^= c)'
 PASS compileAndSerialize('a |= b |= c') is 'a |= b |= c'
@@ -348,7 +348,7 @@
 PASS compileAndSerialize('a |= b + c') is 'a |= b + c'
 PASS compileAndSerialize('(a |= b) + c') is '(a |= b) + c'
 PASS compileAndSerialize('a |= (b + c)') is 'a |= (b + c)'
-PASS compileAndSerialize('a + b |= c') threw exception SyntaxError: Left hand sign of operator '|=' must be a reference..
+PASS compileAndSerialize('a + b |= c') threw exception SyntaxError: Left hand side of operator '|=' must be a reference..
 PASS compileAndSerialize('(a + b) |= c') is '(a + b) |= c'
 PASS compileAndSerialize('a + (b |= c)') is 'a + (b |= c)'
 PASS compileAndSerialize('delete a + b') is 'delete a + b'

Modified: trunk/LayoutTests/js/parser-syntax-check-expected.txt (158424 => 158425)


--- trunk/LayoutTests/js/parser-syntax-check-expected.txt	2013-11-01 03:28:59 UTC (rev 158424)
+++ trunk/LayoutTests/js/parser-syntax-check-expected.txt	2013-11-01 05:13:49 UTC (rev 158425)
@@ -688,6 +688,10 @@
 PASS Invalid: "function f() { ({set [x](){}}) }"
 PASS Invalid: "({[...x]: 1})"
 PASS Invalid: "function f() { ({[...x]: 1}) }"
+PASS Valid:   "( function(){ return this || eval('this'); }().x = 'y' )"
+PASS Valid:   "function f() { ( function(){ return this || eval('this'); }().x = 'y' ) }"
+PASS Invalid: "function(){ return this || eval('this'); }().x = 'y'"
+PASS Invalid: "function f() { function(){ return this || eval('this'); }().x = 'y' }"
 PASS e.line is 1
 PASS foo is 'PASS'
 PASS bar is 'PASS'

Modified: trunk/LayoutTests/js/script-tests/parser-syntax-check.js (158424 => 158425)


--- trunk/LayoutTests/js/script-tests/parser-syntax-check.js	2013-11-01 03:28:59 UTC (rev 158424)
+++ trunk/LayoutTests/js/script-tests/parser-syntax-check.js	2013-11-01 05:13:49 UTC (rev 158425)
@@ -427,6 +427,8 @@
 invalid("({get [x](){}})")
 invalid("({set [x](){}})")
 invalid("({[...x]: 1})")
+valid("( function(){ return this || eval('this'); }().x = 'y' )");
+invalid("function(){ return this || eval('this'); }().x = 'y'");
 
 
 

Modified: trunk/Source/_javascript_Core/ChangeLog (158424 => 158425)


--- trunk/Source/_javascript_Core/ChangeLog	2013-11-01 03:28:59 UTC (rev 158424)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-11-01 05:13:49 UTC (rev 158425)
@@ -1,3 +1,22 @@
+2013-10-31  Oliver Hunt  <[email protected]>
+
+        _javascript_ parser bug
+        https://bugs.webkit.org/show_bug.cgi?id=123506
+
+        Reviewed by Mark Lam.
+
+        Add ParserState as an abstraction and use that to save and restore
+        the parser state around nested functions (We'll need to use this in
+        more places in future).  Also fix a minor error typo this testcases
+        hit.
+
+        * parser/Parser.cpp:
+        (JSC::::parseFunctionInfo):
+        (JSC::::parseAssignmentExpression):
+        * parser/Parser.h:
+        (JSC::Parser::saveState):
+        (JSC::Parser::restoreState):
+
 2013-10-31  Filip Pizlo  <[email protected]>
 
         FTL Int32ToDouble should handle the forward type check case where you need a recovery

Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (158424 => 158425)


--- trunk/Source/_javascript_Core/parser/Parser.cpp	2013-11-01 03:28:59 UTC (rev 158424)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp	2013-11-01 05:13:49 UTC (rev 158425)
@@ -1105,7 +1105,9 @@
         return true;
     }
     m_lastFunctionName = lastFunctionName;
+    ParserState oldState = saveState();
     body = parseFunctionBody(context);
+    restoreState(oldState);
     failIfFalse(body, "Cannot parse the body of this ", stringForFunctionMode(mode));
     if (functionScope->strictMode() && name) {
         RELEASE_ASSERT(mode == FunctionMode);
@@ -1370,7 +1372,7 @@
     failIfFalse(lhs, "Cannot parse _expression_");
     if (initialNonLHSCount != m_nonLHSCount) {
         if (m_token.m_type >= EQUAL && m_token.m_type <= OREQUAL)
-            semanticFail("Left hand sign of operator '", getToken(), "' must be a reference");
+            semanticFail("Left hand side of operator '", getToken(), "' must be a reference");
 
         return lhs;
     }
@@ -1411,7 +1413,7 @@
         failIfFalse(lhs, "Cannot parse the right hand side of an assignment _expression_");
         if (initialNonLHSCount != m_nonLHSCount) {
             if (m_token.m_type >= EQUAL && m_token.m_type <= OREQUAL)
-                semanticFail("Left hand sign of operator '", getToken(), "' must be a reference");
+                semanticFail("Left hand side of operator '", getToken(), "' must be a reference");
             break;
         }
     }

Modified: trunk/Source/_javascript_Core/parser/Parser.h (158424 => 158425)


--- trunk/Source/_javascript_Core/parser/Parser.h	2013-11-01 03:28:59 UTC (rev 158424)
+++ trunk/Source/_javascript_Core/parser/Parser.h	2013-11-01 05:13:49 UTC (rev 158425)
@@ -759,7 +759,6 @@
         return !m_errorMessage.isNull();
     }
 
-    
     struct SavePoint {
         int startOffset;
         unsigned oldLineStartOffset;
@@ -784,7 +783,31 @@
         m_lexer->setLastLineNumber(savePoint.oldLastLineNumber);
         m_lexer->setLineNumber(savePoint.oldLineNumber);
     }
+
+    struct ParserState {
+        int assignmentCount;
+        int nonLHSCount;
+        int nonTrivialExpressionCount;
+    };
+
+    ALWAYS_INLINE ParserState saveState()
+    {
+        ParserState result;
+        result.assignmentCount = m_assignmentCount;
+        result.nonLHSCount = m_nonLHSCount;
+        result.nonTrivialExpressionCount = m_nonTrivialExpressionCount;
+        return result;
+    }
     
+    ALWAYS_INLINE void restoreState(const ParserState& state)
+    {
+        m_assignmentCount = state.assignmentCount;
+        m_nonLHSCount = state.nonLHSCount;
+        m_nonTrivialExpressionCount = state.nonTrivialExpressionCount;
+        
+    }
+    
+
     VM* m_vm;
     const SourceCode* m_source;
     ParserArena* m_arena;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to