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;