Title: [207798] trunk
Revision
207798
Author
utatane....@gmail.com
Date
2016-10-24 19:35:59 -0700 (Mon, 24 Oct 2016)

Log Message

Arrow functions with concise bodies cannot return regular expressions
https://bugs.webkit.org/show_bug.cgi?id=163162

Reviewed by Filip Pizlo.

JSTests:

* ChakraCore/test/Operators/instanceof.baseline-jsc:
* ChakraCore/test/Regex/nul_character.baseline-jsc:
* ChakraCore/test/es5/Lex_u3.baseline-jsc:
* stress/parse-regexp-as-token.js: Added.
(shouldBe):

Source/_javascript_Core:

When we encounter the RegExp in the parser, we first scan it as / or /=.
And if / or /= is parsed under the primary _expression_ context, we rescan it
as RegExp. However, we did not update the token record information. So the
token record still says "I'm / or /=".

When we parse the string "() => /hello/", the last token becomes "/", which is
the first character of the RegExp, instead of "/hello/". Since the arrow
function parsing utilizes the end offset of the last token, we accidentally
recognize the range of the above arrow function as "() => /".

In this patch, we update the token when rescanning under the RegExp context.
This logic is similar to parsing Tail Template Literal token.

We also refine the error message for regular _expression_ literals. And since
the REGEXP token is now introduced, the other error messages using that token
are improved too.

Currently, unterminated error messages can be seen in Parser.cpp. However,
these messages cannot be shown to users if the lexer has m_error. So these
code is meaningless. I'll move these tokenizing errors to the lexer in the
subsequent patch[1].

[1]: https://bugs.webkit.org/show_bug.cgi?id=163928

* parser/Lexer.cpp:
(JSC::Lexer<T>::fillTokenInfo):
(JSC::Lexer<T>::lex):
(JSC::Lexer<T>::scanRegExp):
(JSC::Lexer<T>::scanTrailingTemplateString):
(JSC::Lexer<T>::skipRegExp): Deleted.
* parser/Lexer.h:
(JSC::Lexer::getToken):
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseAssignmentExpression):
* parser/Parser.h:
(JSC::Parser::getToken):
* parser/ParserTokens.h:

LayoutTests:

* fast/regex/dom/non-pattern-characters-expected.txt:
* js/arrowfunction-syntax-errors-expected.txt:
* js/regexp-compile-crash-expected.txt:
* sputnik/Conformance/07_Lexical_Conventions/7.4_Comments/S7.4_A4_T1-expected.txt:
* sputnik/Conformance/07_Lexical_Conventions/7.4_Comments/S7.4_A4_T4-expected.txt:
* sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.2_T2-expected.txt:
* sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.3_T1-expected.txt:
* sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.3_T3-expected.txt:
* sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.5_T1-expected.txt:
* sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.5_T3-expected.txt:
* sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.2_T1-expected.txt:
* sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.3_T1-expected.txt:
* sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.3_T3-expected.txt:
* sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.5_T1-expected.txt:
* sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.5_T3-expected.txt:

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChakraCore/test/Operators/instanceof.baseline-jsc (207797 => 207798)


--- trunk/JSTests/ChakraCore/test/Operators/instanceof.baseline-jsc	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/JSTests/ChakraCore/test/Operators/instanceof.baseline-jsc	2016-10-25 02:35:59 UTC (rev 207798)
@@ -228,7 +228,7 @@
  Exception: new Object() instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating 'new Object() instanceof new Boolean(true)')
  Exception: new Object() instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating 'new Object() instanceof new Boolean(false)')
  Exception: new Object() instanceof new Date(). new Date() is not a function. (evaluating 'new Object() instanceof new Date()')
- Exception: new Object() instanceof /a+/. / is not a function. (evaluating 'new Object() instanceof /')
+ Exception: new Object() instanceof /a+/. /a+/ is not a function. (evaluating 'new Object() instanceof /a+/')
  Exception: f instanceof new Object(). new Object() is not a function. (evaluating 'f instanceof new Object()')
  Exception: f instanceof f. f is not a function. (evaluating 'f instanceof f')
  Exception: f instanceof b. b is not a function. (evaluating 'f instanceof b')
@@ -249,7 +249,7 @@
  Exception: f instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating 'f instanceof new Boolean(true)')
  Exception: f instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating 'f instanceof new Boolean(false)')
  Exception: f instanceof new Date(). new Date() is not a function. (evaluating 'f instanceof new Date()')
- Exception: f instanceof /a+/. / is not a function. (evaluating 'f instanceof /')
+ Exception: f instanceof /a+/. /a+/ is not a function. (evaluating 'f instanceof /a+/')
  Exception: b instanceof new Object(). new Object() is not a function. (evaluating 'b instanceof new Object()')
  Exception: b instanceof f. f is not a function. (evaluating 'b instanceof f')
  Exception: b instanceof b. b is not a function. (evaluating 'b instanceof b')
@@ -270,7 +270,7 @@
  Exception: b instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating 'b instanceof new Boolean(true)')
  Exception: b instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating 'b instanceof new Boolean(false)')
  Exception: b instanceof new Date(). new Date() is not a function. (evaluating 'b instanceof new Date()')
- Exception: b instanceof /a+/. / is not a function. (evaluating 'b instanceof /')
+ Exception: b instanceof /a+/. /a+/ is not a function. (evaluating 'b instanceof /a+/')
  Exception: foo instanceof new Object(). new Object() is not a function. (evaluating 'foo instanceof new Object()')
  Exception: foo instanceof f. f is not a function. (evaluating 'foo instanceof f')
  Exception: foo instanceof b. b is not a function. (evaluating 'foo instanceof b')
@@ -291,7 +291,7 @@
  Exception: foo instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating 'foo instanceof new Boolean(true)')
  Exception: foo instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating 'foo instanceof new Boolean(false)')
  Exception: foo instanceof new Date(). new Date() is not a function. (evaluating 'foo instanceof new Date()')
- Exception: foo instanceof /a+/. / is not a function. (evaluating 'foo instanceof /')
+ Exception: foo instanceof /a+/. /a+/ is not a function. (evaluating 'foo instanceof /a+/')
  Exception: String.fromCharCode instanceof new Object(). new Object() is not a function. (evaluating 'String.fromCharCode instanceof new Object()')
  Exception: String.fromCharCode instanceof f. f is not a function. (evaluating 'String.fromCharCode instanceof f')
  Exception: String.fromCharCode instanceof b. b is not a function. (evaluating 'String.fromCharCode instanceof b')
@@ -312,7 +312,7 @@
  Exception: String.fromCharCode instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating 'String.fromCharCode instanceof new Boolean(true)')
  Exception: String.fromCharCode instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating 'String.fromCharCode instanceof new Boolean(false)')
  Exception: String.fromCharCode instanceof new Date(). new Date() is not a function. (evaluating 'String.fromCharCode instanceof new Date()')
- Exception: String.fromCharCode instanceof /a+/. / is not a function. (evaluating 'String.fromCharCode instanceof /')
+ Exception: String.fromCharCode instanceof /a+/. /a+/ is not a function. (evaluating 'String.fromCharCode instanceof /a+/')
  Exception: Array.prototype.concat instanceof new Object(). new Object() is not a function. (evaluating 'Array.prototype.concat instanceof new Object()')
  Exception: Array.prototype.concat instanceof f. f is not a function. (evaluating 'Array.prototype.concat instanceof f')
  Exception: Array.prototype.concat instanceof b. b is not a function. (evaluating 'Array.prototype.concat instanceof b')
@@ -333,7 +333,7 @@
  Exception: Array.prototype.concat instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating 'Array.prototype.concat instanceof new Boolean(true)')
  Exception: Array.prototype.concat instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating 'Array.prototype.concat instanceof new Boolean(false)')
  Exception: Array.prototype.concat instanceof new Date(). new Date() is not a function. (evaluating 'Array.prototype.concat instanceof new Date()')
- Exception: Array.prototype.concat instanceof /a+/. / is not a function. (evaluating 'Array.prototype.concat instanceof /')
+ Exception: Array.prototype.concat instanceof /a+/. /a+/ is not a function. (evaluating 'Array.prototype.concat instanceof /a+/')
  Exception: [1,2,3] instanceof new Object(). new Object() is not a function. (evaluating '[1,2,3] instanceof new Object()')
  Exception: [1,2,3] instanceof f. f is not a function. (evaluating '[1,2,3] instanceof f')
  Exception: [1,2,3] instanceof b. b is not a function. (evaluating '[1,2,3] instanceof b')
@@ -354,7 +354,7 @@
  Exception: [1,2,3] instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating '[1,2,3] instanceof new Boolean(true)')
  Exception: [1,2,3] instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating '[1,2,3] instanceof new Boolean(false)')
  Exception: [1,2,3] instanceof new Date(). new Date() is not a function. (evaluating '[1,2,3] instanceof new Date()')
- Exception: [1,2,3] instanceof /a+/. / is not a function. (evaluating '[1,2,3] instanceof /')
+ Exception: [1,2,3] instanceof /a+/. /a+/ is not a function. (evaluating '[1,2,3] instanceof /a+/')
  Exception: new Array() instanceof new Object(). new Object() is not a function. (evaluating 'new Array() instanceof new Object()')
  Exception: new Array() instanceof f. f is not a function. (evaluating 'new Array() instanceof f')
  Exception: new Array() instanceof b. b is not a function. (evaluating 'new Array() instanceof b')
@@ -375,7 +375,7 @@
  Exception: new Array() instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating 'new Array() instanceof new Boolean(true)')
  Exception: new Array() instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating 'new Array() instanceof new Boolean(false)')
  Exception: new Array() instanceof new Date(). new Date() is not a function. (evaluating 'new Array() instanceof new Date()')
- Exception: new Array() instanceof /a+/. / is not a function. (evaluating 'new Array() instanceof /')
+ Exception: new Array() instanceof /a+/. /a+/ is not a function. (evaluating 'new Array() instanceof /a+/')
  Exception: fncs instanceof new Object(). new Object() is not a function. (evaluating 'fncs instanceof new Object()')
  Exception: fncs instanceof f. f is not a function. (evaluating 'fncs instanceof f')
  Exception: fncs instanceof b. b is not a function. (evaluating 'fncs instanceof b')
@@ -396,7 +396,7 @@
  Exception: fncs instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating 'fncs instanceof new Boolean(true)')
  Exception: fncs instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating 'fncs instanceof new Boolean(false)')
  Exception: fncs instanceof new Date(). new Date() is not a function. (evaluating 'fncs instanceof new Date()')
- Exception: fncs instanceof /a+/. / is not a function. (evaluating 'fncs instanceof /')
+ Exception: fncs instanceof /a+/. /a+/ is not a function. (evaluating 'fncs instanceof /a+/')
  Exception: 'hello' instanceof new Object(). new Object() is not a function. (evaluating ''hello' instanceof new Object()')
  Exception: 'hello' instanceof f. f is not a function. (evaluating ''hello' instanceof f')
  Exception: 'hello' instanceof b. b is not a function. (evaluating ''hello' instanceof b')
@@ -417,7 +417,7 @@
  Exception: 'hello' instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating ''hello' instanceof new Boolean(true)')
  Exception: 'hello' instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating ''hello' instanceof new Boolean(false)')
  Exception: 'hello' instanceof new Date(). new Date() is not a function. (evaluating ''hello' instanceof new Date()')
- Exception: 'hello' instanceof /a+/. / is not a function. (evaluating ''hello' instanceof /')
+ Exception: 'hello' instanceof /a+/. /a+/ is not a function. (evaluating ''hello' instanceof /a+/')
  Exception: new String('world') instanceof new Object(). new Object() is not a function. (evaluating 'new String('world') instanceof new Object()')
  Exception: new String('world') instanceof f. f is not a function. (evaluating 'new String('world') instanceof f')
  Exception: new String('world') instanceof b. b is not a function. (evaluating 'new String('world') instanceof b')
@@ -438,7 +438,7 @@
  Exception: new String('world') instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating 'new String('world') instanceof new Boolean(true)')
  Exception: new String('world') instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating 'new String('world') instanceof new Boolean(false)')
  Exception: new String('world') instanceof new Date(). new Date() is not a function. (evaluating 'new String('world') instanceof new Date()')
- Exception: new String('world') instanceof /a+/. / is not a function. (evaluating 'new String('world') instanceof /')
+ Exception: new String('world') instanceof /a+/. /a+/ is not a function. (evaluating 'new String('world') instanceof /a+/')
  Exception: 10 instanceof new Object(). new Object() is not a function. (evaluating '10 instanceof new Object()')
  Exception: 10 instanceof f. f is not a function. (evaluating '10 instanceof f')
  Exception: 10 instanceof b. b is not a function. (evaluating '10 instanceof b')
@@ -459,7 +459,7 @@
  Exception: 10 instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating '10 instanceof new Boolean(true)')
  Exception: 10 instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating '10 instanceof new Boolean(false)')
  Exception: 10 instanceof new Date(). new Date() is not a function. (evaluating '10 instanceof new Date()')
- Exception: 10 instanceof /a+/. / is not a function. (evaluating '10 instanceof /')
+ Exception: 10 instanceof /a+/. /a+/ is not a function. (evaluating '10 instanceof /a+/')
  Exception: 10.2 instanceof new Object(). new Object() is not a function. (evaluating '10.2 instanceof new Object()')
  Exception: 10.2 instanceof f. f is not a function. (evaluating '10.2 instanceof f')
  Exception: 10.2 instanceof b. b is not a function. (evaluating '10.2 instanceof b')
@@ -480,7 +480,7 @@
  Exception: 10.2 instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating '10.2 instanceof new Boolean(true)')
  Exception: 10.2 instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating '10.2 instanceof new Boolean(false)')
  Exception: 10.2 instanceof new Date(). new Date() is not a function. (evaluating '10.2 instanceof new Date()')
- Exception: 10.2 instanceof /a+/. / is not a function. (evaluating '10.2 instanceof /')
+ Exception: 10.2 instanceof /a+/. /a+/ is not a function. (evaluating '10.2 instanceof /a+/')
  Exception: NaN instanceof new Object(). new Object() is not a function. (evaluating 'NaN instanceof new Object()')
  Exception: NaN instanceof f. f is not a function. (evaluating 'NaN instanceof f')
  Exception: NaN instanceof b. b is not a function. (evaluating 'NaN instanceof b')
@@ -501,7 +501,7 @@
  Exception: NaN instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating 'NaN instanceof new Boolean(true)')
  Exception: NaN instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating 'NaN instanceof new Boolean(false)')
  Exception: NaN instanceof new Date(). new Date() is not a function. (evaluating 'NaN instanceof new Date()')
- Exception: NaN instanceof /a+/. / is not a function. (evaluating 'NaN instanceof /')
+ Exception: NaN instanceof /a+/. /a+/ is not a function. (evaluating 'NaN instanceof /a+/')
  Exception: new Number(3) instanceof new Object(). new Object() is not a function. (evaluating 'new Number(3) instanceof new Object()')
  Exception: new Number(3) instanceof f. f is not a function. (evaluating 'new Number(3) instanceof f')
  Exception: new Number(3) instanceof b. b is not a function. (evaluating 'new Number(3) instanceof b')
@@ -522,7 +522,7 @@
  Exception: new Number(3) instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating 'new Number(3) instanceof new Boolean(true)')
  Exception: new Number(3) instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating 'new Number(3) instanceof new Boolean(false)')
  Exception: new Number(3) instanceof new Date(). new Date() is not a function. (evaluating 'new Number(3) instanceof new Date()')
- Exception: new Number(3) instanceof /a+/. / is not a function. (evaluating 'new Number(3) instanceof /')
+ Exception: new Number(3) instanceof /a+/. /a+/ is not a function. (evaluating 'new Number(3) instanceof /a+/')
  Exception: true instanceof new Object(). new Object() is not a function. (evaluating 'true instanceof new Object()')
  Exception: true instanceof f. f is not a function. (evaluating 'true instanceof f')
  Exception: true instanceof b. b is not a function. (evaluating 'true instanceof b')
@@ -543,7 +543,7 @@
  Exception: true instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating 'true instanceof new Boolean(true)')
  Exception: true instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating 'true instanceof new Boolean(false)')
  Exception: true instanceof new Date(). new Date() is not a function. (evaluating 'true instanceof new Date()')
- Exception: true instanceof /a+/. / is not a function. (evaluating 'true instanceof /')
+ Exception: true instanceof /a+/. /a+/ is not a function. (evaluating 'true instanceof /a+/')
  Exception: false instanceof new Object(). new Object() is not a function. (evaluating 'false instanceof new Object()')
  Exception: false instanceof f. f is not a function. (evaluating 'false instanceof f')
  Exception: false instanceof b. b is not a function. (evaluating 'false instanceof b')
@@ -564,7 +564,7 @@
  Exception: false instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating 'false instanceof new Boolean(true)')
  Exception: false instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating 'false instanceof new Boolean(false)')
  Exception: false instanceof new Date(). new Date() is not a function. (evaluating 'false instanceof new Date()')
- Exception: false instanceof /a+/. / is not a function. (evaluating 'false instanceof /')
+ Exception: false instanceof /a+/. /a+/ is not a function. (evaluating 'false instanceof /a+/')
  Exception: new Boolean(true) instanceof new Object(). new Object() is not a function. (evaluating 'new Boolean(true) instanceof new Object()')
  Exception: new Boolean(true) instanceof f. f is not a function. (evaluating 'new Boolean(true) instanceof f')
  Exception: new Boolean(true) instanceof b. b is not a function. (evaluating 'new Boolean(true) instanceof b')
@@ -585,7 +585,7 @@
  Exception: new Boolean(true) instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating 'new Boolean(true) instanceof new Boolean(true)')
  Exception: new Boolean(true) instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating 'new Boolean(true) instanceof new Boolean(false)')
  Exception: new Boolean(true) instanceof new Date(). new Date() is not a function. (evaluating 'new Boolean(true) instanceof new Date()')
- Exception: new Boolean(true) instanceof /a+/. / is not a function. (evaluating 'new Boolean(true) instanceof /')
+ Exception: new Boolean(true) instanceof /a+/. /a+/ is not a function. (evaluating 'new Boolean(true) instanceof /a+/')
  Exception: new Boolean(false) instanceof new Object(). new Object() is not a function. (evaluating 'new Boolean(false) instanceof new Object()')
  Exception: new Boolean(false) instanceof f. f is not a function. (evaluating 'new Boolean(false) instanceof f')
  Exception: new Boolean(false) instanceof b. b is not a function. (evaluating 'new Boolean(false) instanceof b')
@@ -606,7 +606,7 @@
  Exception: new Boolean(false) instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating 'new Boolean(false) instanceof new Boolean(true)')
  Exception: new Boolean(false) instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating 'new Boolean(false) instanceof new Boolean(false)')
  Exception: new Boolean(false) instanceof new Date(). new Date() is not a function. (evaluating 'new Boolean(false) instanceof new Date()')
- Exception: new Boolean(false) instanceof /a+/. / is not a function. (evaluating 'new Boolean(false) instanceof /')
+ Exception: new Boolean(false) instanceof /a+/. /a+/ is not a function. (evaluating 'new Boolean(false) instanceof /a+/')
  Exception: new Date() instanceof new Object(). new Object() is not a function. (evaluating 'new Date() instanceof new Object()')
  Exception: new Date() instanceof f. f is not a function. (evaluating 'new Date() instanceof f')
  Exception: new Date() instanceof b. b is not a function. (evaluating 'new Date() instanceof b')
@@ -627,7 +627,7 @@
  Exception: new Date() instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating 'new Date() instanceof new Boolean(true)')
  Exception: new Date() instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating 'new Date() instanceof new Boolean(false)')
  Exception: new Date() instanceof new Date(). new Date() is not a function. (evaluating 'new Date() instanceof new Date()')
- Exception: new Date() instanceof /a+/. / is not a function. (evaluating 'new Date() instanceof /')
+ Exception: new Date() instanceof /a+/. /a+/ is not a function. (evaluating 'new Date() instanceof /a+/')
  Exception: /a+/ instanceof new Object(). new Object() is not a function. (evaluating '/a+/ instanceof new Object()')
  Exception: /a+/ instanceof f. f is not a function. (evaluating '/a+/ instanceof f')
  Exception: /a+/ instanceof b. b is not a function. (evaluating '/a+/ instanceof b')
@@ -648,4 +648,4 @@
  Exception: /a+/ instanceof new Boolean(true). new Boolean(true) is not a function. (evaluating '/a+/ instanceof new Boolean(true)')
  Exception: /a+/ instanceof new Boolean(false). new Boolean(false) is not a function. (evaluating '/a+/ instanceof new Boolean(false)')
  Exception: /a+/ instanceof new Date(). new Date() is not a function. (evaluating '/a+/ instanceof new Date()')
- Exception: /a+/ instanceof /a+/. / is not a function. (evaluating '/a+/ instanceof /')
+ Exception: /a+/ instanceof /a+/. /a+/ is not a function. (evaluating '/a+/ instanceof /a+/')

Modified: trunk/JSTests/ChakraCore/test/Regex/nul_character.baseline-jsc (207797 => 207798)


--- trunk/JSTests/ChakraCore/test/Regex/nul_character.baseline-jsc	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/JSTests/ChakraCore/test/Regex/nul_character.baseline-jsc	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1,23 +1,23 @@
 --- 1 ---
 5
-SyntaxError: Unexpected token '/'. Invalid regular _expression_.
-SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+SyntaxError: Unterminated regular _expression_ literal '/'
+SyntaxError: Unterminated regular _expression_ literal '/'
 --- 2 ---
 4
-SyntaxError: Unexpected token '/'. Invalid regular _expression_.
-SyntaxError: Unexpected token '/'. Invalid regular _expression_.
-SyntaxError: Unexpected token '/'. Invalid regular _expression_.
-SyntaxError: Unexpected token '/'. Invalid regular _expression_.
-SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+SyntaxError: Unterminated regular _expression_ literal '/\'
+SyntaxError: Unterminated regular _expression_ literal '/\'
+SyntaxError: Unterminated regular _expression_ literal '/\'
+SyntaxError: Unterminated regular _expression_ literal '/\'
+SyntaxError: Unterminated regular _expression_ literal '/\'
 4
 5
 --- 3 ---
-SyntaxError: Unexpected token '/'. Invalid regular _expression_.
-SyntaxError: Unexpected token '/'. Invalid regular _expression_.
-SyntaxError: Unexpected token '/'. Invalid regular _expression_.
-SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+SyntaxError: Unterminated regular _expression_ literal '/['
+SyntaxError: Unterminated regular _expression_ literal '/['
+SyntaxError: Unterminated regular _expression_ literal '/['
+SyntaxError: Unterminated regular _expression_ literal '/['
 5
-SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+SyntaxError: Unterminated regular _expression_ literal '/['
 SyntaxError: Invalid regular _expression_: unmatched parentheses
 --- 4 ---
 9

Modified: trunk/JSTests/ChakraCore/test/es5/Lex_u3.baseline-jsc (207797 => 207798)


--- trunk/JSTests/ChakraCore/test/es5/Lex_u3.baseline-jsc	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/JSTests/ChakraCore/test/es5/Lex_u3.baseline-jsc	2016-10-25 02:35:59 UTC (rev 207798)
@@ -3,7 +3,7 @@
 str const Left 
  str const right
 LS in string -  compile failure in ES5: expected.SyntaxError: Unexpected EOF
-LS in regex literal -  compile failure in ES5: expected.SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+LS in regex literal -  compile failure in ES5: expected.SyntaxError: Unterminated regular _expression_ literal '/str const regex '
 LS%20in%20escape%20sequence%20string%20literal%20%20%3Amore%20string
 BOM is WS :  91
 ZVNJ is id part :  aa%u200Cbb

Modified: trunk/JSTests/ChangeLog (207797 => 207798)


--- trunk/JSTests/ChangeLog	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/JSTests/ChangeLog	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1,3 +1,16 @@
+2016-10-24  Yusuke Suzuki  <utatane....@gmail.com>
+
+        Arrow functions with concise bodies cannot return regular expressions
+        https://bugs.webkit.org/show_bug.cgi?id=163162
+
+        Reviewed by Filip Pizlo.
+
+        * ChakraCore/test/Operators/instanceof.baseline-jsc:
+        * ChakraCore/test/Regex/nul_character.baseline-jsc:
+        * ChakraCore/test/es5/Lex_u3.baseline-jsc:
+        * stress/parse-regexp-as-token.js: Added.
+        (shouldBe):
+
 2016-10-24  Keith Miller  <keith_mil...@apple.com>
 
         Wasm should support floating point operations.

Added: trunk/JSTests/stress/parse-regexp-as-token.js (0 => 207798)


--- trunk/JSTests/stress/parse-regexp-as-token.js	                        (rev 0)
+++ trunk/JSTests/stress/parse-regexp-as-token.js	2016-10-25 02:35:59 UTC (rev 207798)
@@ -0,0 +1,7 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error(`bad value: ${String(actual)}`);
+}
+
+var arrow = () => /Cocoa/;
+shouldBe(arrow.toString(), `() => /Cocoa/`);

Modified: trunk/LayoutTests/ChangeLog (207797 => 207798)


--- trunk/LayoutTests/ChangeLog	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/LayoutTests/ChangeLog	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1,3 +1,26 @@
+2016-10-24  Yusuke Suzuki  <utatane....@gmail.com>
+
+        Arrow functions with concise bodies cannot return regular expressions
+        https://bugs.webkit.org/show_bug.cgi?id=163162
+
+        Reviewed by Filip Pizlo.
+
+        * fast/regex/dom/non-pattern-characters-expected.txt:
+        * js/arrowfunction-syntax-errors-expected.txt:
+        * js/regexp-compile-crash-expected.txt:
+        * sputnik/Conformance/07_Lexical_Conventions/7.4_Comments/S7.4_A4_T1-expected.txt:
+        * sputnik/Conformance/07_Lexical_Conventions/7.4_Comments/S7.4_A4_T4-expected.txt:
+        * sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.2_T2-expected.txt:
+        * sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.3_T1-expected.txt:
+        * sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.3_T3-expected.txt:
+        * sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.5_T1-expected.txt:
+        * sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.5_T3-expected.txt:
+        * sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.2_T1-expected.txt:
+        * sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.3_T1-expected.txt:
+        * sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.3_T3-expected.txt:
+        * sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.5_T1-expected.txt:
+        * sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.5_T3-expected.txt:
+
 2016-10-24  Chris Dumez  <cdu...@apple.com>
 
         event.(dataTransfer|clipboardData).getData('text/html') (onpaste, ondrop)

Modified: trunk/LayoutTests/fast/regex/dom/non-pattern-characters-expected.txt (207797 => 207798)


--- trunk/LayoutTests/fast/regex/dom/non-pattern-characters-expected.txt	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/LayoutTests/fast/regex/dom/non-pattern-characters-expected.txt	2016-10-25 02:35:59 UTC (rev 207798)
@@ -33,8 +33,8 @@
 PASS regexp.test('a_') is true
 
 Testing regexp: [invalid \ variations]
-PASS /\/ threw exception SyntaxError: Unexpected token '/'. Invalid regular _expression_..
-PASS /a\/ threw exception SyntaxError: Unexpected token '/'. Invalid regular _expression_..
+PASS /\/ threw exception SyntaxError: Unterminated regular _expression_ literal '/\/'.
+PASS /a\/ threw exception SyntaxError: Unterminated regular _expression_ literal '/a\/'.
 
 Testing regexp: /./
 PASS regexp.test('a') is true
@@ -80,8 +80,8 @@
 PASS /a)/ threw exception SyntaxError: Invalid regular _expression_: unmatched parentheses.
 
 Testing regexp: [invalid [ variations]
-PASS /[/ threw exception SyntaxError: Unexpected token '/'. Invalid regular _expression_..
-PASS /a[/ threw exception SyntaxError: Unexpected token '/'. Invalid regular _expression_..
+PASS /[/ threw exception SyntaxError: Unterminated regular _expression_ literal '/[/'.
+PASS /a[/ threw exception SyntaxError: Unterminated regular _expression_ literal '/a[/'.
 PASS /[b-a]/ threw exception SyntaxError: Invalid regular _expression_: range out of order in character class.
 PASS /a[b-a]/ threw exception SyntaxError: Invalid regular _expression_: range out of order in character class.
 

Modified: trunk/LayoutTests/js/arrowfunction-syntax-errors-expected.txt (207797 => 207798)


--- trunk/LayoutTests/js/arrowfunction-syntax-errors-expected.txt	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/LayoutTests/js/arrowfunction-syntax-errors-expected.txt	2016-10-25 02:35:59 UTC (rev 207798)
@@ -6,7 +6,7 @@
 PASS =>{} threw exception SyntaxError: Unexpected token '=>'.
 PASS x=> threw exception SyntaxError: Unexpected end of script.
 PASS x=>* threw exception SyntaxError: Unexpected token '*'.
-PASS x=>/ threw exception SyntaxError: Unexpected token '/'. Invalid regular _expression_..
+PASS x=>/ threw exception SyntaxError: Unterminated regular _expression_ literal '/'.
 PASS x=>% threw exception SyntaxError: Unexpected token '%'.
 PASS x=>+ threw exception SyntaxError: Unexpected end of script.
 PASS x=>- threw exception SyntaxError: Unexpected end of script.
@@ -32,7 +32,7 @@
 PASS x=>, threw exception SyntaxError: Unexpected token ','.
 PASS x=>{ threw exception SyntaxError: Unexpected end of script.
 PASS x=>{* threw exception SyntaxError: Unexpected token '*'.
-PASS x=>{/ threw exception SyntaxError: Unexpected token '/'. Invalid regular _expression_..
+PASS x=>{/ threw exception SyntaxError: Unterminated regular _expression_ literal '/'.
 PASS x=>{% threw exception SyntaxError: Unexpected token '%'.
 PASS x=>{+ threw exception SyntaxError: Unexpected end of script.
 PASS x=>{- threw exception SyntaxError: Unexpected end of script.
@@ -59,7 +59,7 @@
 PASS x=>} threw exception SyntaxError: Unexpected token '}'.
 PASS var y = x=> threw exception SyntaxError: Unexpected end of script.
 PASS var y = x=>* threw exception SyntaxError: Unexpected token '*'.
-PASS var y = x=>/ threw exception SyntaxError: Unexpected token '/'. Invalid regular _expression_..
+PASS var y = x=>/ threw exception SyntaxError: Unterminated regular _expression_ literal '/'.
 PASS var y = x=>% threw exception SyntaxError: Unexpected token '%'.
 PASS var y = x=>+ threw exception SyntaxError: Unexpected end of script.
 PASS var y = x=>- threw exception SyntaxError: Unexpected end of script.
@@ -85,7 +85,7 @@
 PASS var y = x=>, threw exception SyntaxError: Unexpected token ','.
 PASS var y = x=>{ threw exception SyntaxError: Unexpected end of script.
 PASS var y = x=>{* threw exception SyntaxError: Unexpected token '*'.
-PASS var y = x=>{/ threw exception SyntaxError: Unexpected token '/'. Invalid regular _expression_..
+PASS var y = x=>{/ threw exception SyntaxError: Unterminated regular _expression_ literal '/'.
 PASS var y = x=>{% threw exception SyntaxError: Unexpected token '%'.
 PASS var y = x=>{+ threw exception SyntaxError: Unexpected end of script.
 PASS var y = x=>{- threw exception SyntaxError: Unexpected end of script.

Modified: trunk/LayoutTests/js/regexp-compile-crash-expected.txt (207797 => 207798)


--- trunk/LayoutTests/js/regexp-compile-crash-expected.txt	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/LayoutTests/js/regexp-compile-crash-expected.txt	2016-10-25 02:35:59 UTC (rev 207798)
@@ -4,9 +4,9 @@
 
 
 PASS !!/\)[;s]+/ is true
-PASS /[/ threw exception SyntaxError: Unexpected token '/'. Invalid regular _expression_..
-PASS /[a/ threw exception SyntaxError: Unexpected token '/'. Invalid regular _expression_..
-PASS /[-/ threw exception SyntaxError: Unexpected token '/'. Invalid regular _expression_..
+PASS /[/ threw exception SyntaxError: Unterminated regular _expression_ literal '/[/'.
+PASS /[a/ threw exception SyntaxError: Unterminated regular _expression_ literal '/[a/'.
+PASS /[-/ threw exception SyntaxError: Unterminated regular _expression_ literal '/[-/'.
 PASS !!/(a)/ is true
 PASS !!/(a){1,3}/ is true
 PASS No crashes, yay!

Modified: trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.4_Comments/S7.4_A4_T1-expected.txt (207797 => 207798)


--- trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.4_Comments/S7.4_A4_T1-expected.txt	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.4_Comments/S7.4_A4_T1-expected.txt	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 79: SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+CONSOLE MESSAGE: line 79: SyntaxError: Unterminated regular _expression_ literal '/'
 S7.4_A4_T1
 
 PASS Expected parsing failure

Modified: trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.4_Comments/S7.4_A4_T4-expected.txt (207797 => 207798)


--- trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.4_Comments/S7.4_A4_T4-expected.txt	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.4_Comments/S7.4_A4_T4-expected.txt	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 79: SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+CONSOLE MESSAGE: line 79: SyntaxError: Unterminated regular _expression_ literal '/'
 S7.4_A4_T4
 
 PASS Expected parsing failure

Modified: trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.2_T2-expected.txt (207797 => 207798)


--- trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.2_T2-expected.txt	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.2_T2-expected.txt	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 77: SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+CONSOLE MESSAGE: line 77: SyntaxError: Unterminated regular _expression_ literal '/\/'
 S7.8.5_A1.2_T2
 
 PASS Expected parsing failure

Modified: trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.3_T1-expected.txt (207797 => 207798)


--- trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.3_T1-expected.txt	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.3_T1-expected.txt	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 77: SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+CONSOLE MESSAGE: line 77: SyntaxError: Unterminated regular _expression_ literal '/'
 S7.8.5_A1.3_T1
 
 PASS Expected parsing failure

Modified: trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.3_T3-expected.txt (207797 => 207798)


--- trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.3_T3-expected.txt	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.3_T3-expected.txt	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 77: SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+CONSOLE MESSAGE: line 77: SyntaxError: Unterminated regular _expression_ literal '/'
 S7.8.5_A1.3_T3
 
 PASS Expected parsing failure

Modified: trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.5_T1-expected.txt (207797 => 207798)


--- trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.5_T1-expected.txt	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.5_T1-expected.txt	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 77: SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+CONSOLE MESSAGE: line 77: SyntaxError: Unterminated regular _expression_ literal '/\'
 S7.8.5_A1.5_T1
 
 PASS Expected parsing failure

Modified: trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.5_T3-expected.txt (207797 => 207798)


--- trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.5_T3-expected.txt	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A1.5_T3-expected.txt	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 77: SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+CONSOLE MESSAGE: line 77: SyntaxError: Unterminated regular _expression_ literal '/\'
 S7.8.5_A1.5_T3
 
 PASS Expected parsing failure

Modified: trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.2_T1-expected.txt (207797 => 207798)


--- trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.2_T1-expected.txt	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.2_T1-expected.txt	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 77: SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+CONSOLE MESSAGE: line 77: SyntaxError: Unterminated regular _expression_ literal '/a\/'
 S7.8.5_A2.2_T1
 
 PASS Expected parsing failure

Modified: trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.3_T1-expected.txt (207797 => 207798)


--- trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.3_T1-expected.txt	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.3_T1-expected.txt	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 77: SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+CONSOLE MESSAGE: line 77: SyntaxError: Unterminated regular _expression_ literal '/a'
 S7.8.5_A2.3_T1
 
 PASS Expected parsing failure

Modified: trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.3_T3-expected.txt (207797 => 207798)


--- trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.3_T3-expected.txt	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.3_T3-expected.txt	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 77: SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+CONSOLE MESSAGE: line 77: SyntaxError: Unterminated regular _expression_ literal '/a'
 S7.8.5_A2.3_T3
 
 PASS Expected parsing failure

Modified: trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.5_T1-expected.txt (207797 => 207798)


--- trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.5_T1-expected.txt	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.5_T1-expected.txt	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 77: SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+CONSOLE MESSAGE: line 77: SyntaxError: Unterminated regular _expression_ literal '/a\'
 S7.8.5_A2.5_T1
 
 PASS Expected parsing failure

Modified: trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.5_T3-expected.txt (207797 => 207798)


--- trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.5_T3-expected.txt	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.8_Literals/7.8.5_Regular_Expression_Literals/S7.8.5_A2.5_T3-expected.txt	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 77: SyntaxError: Unexpected token '/'. Invalid regular _expression_.
+CONSOLE MESSAGE: line 77: SyntaxError: Unterminated regular _expression_ literal '/a\'
 S7.8.5_A2.5_T3
 
 PASS Expected parsing failure

Modified: trunk/Source/_javascript_Core/ChangeLog (207797 => 207798)


--- trunk/Source/_javascript_Core/ChangeLog	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1,3 +1,48 @@
+2016-10-24  Yusuke Suzuki  <utatane....@gmail.com>
+
+        Arrow functions with concise bodies cannot return regular expressions
+        https://bugs.webkit.org/show_bug.cgi?id=163162
+
+        Reviewed by Filip Pizlo.
+
+        When we encounter the RegExp in the parser, we first scan it as / or /=.
+        And if / or /= is parsed under the primary _expression_ context, we rescan it
+        as RegExp. However, we did not update the token record information. So the
+        token record still says "I'm / or /=".
+
+        When we parse the string "() => /hello/", the last token becomes "/", which is
+        the first character of the RegExp, instead of "/hello/". Since the arrow
+        function parsing utilizes the end offset of the last token, we accidentally
+        recognize the range of the above arrow function as "() => /".
+
+        In this patch, we update the token when rescanning under the RegExp context.
+        This logic is similar to parsing Tail Template Literal token.
+
+        We also refine the error message for regular _expression_ literals. And since
+        the REGEXP token is now introduced, the other error messages using that token
+        are improved too.
+
+        Currently, unterminated error messages can be seen in Parser.cpp. However,
+        these messages cannot be shown to users if the lexer has m_error. So these
+        code is meaningless. I'll move these tokenizing errors to the lexer in the
+        subsequent patch[1].
+
+        [1]: https://bugs.webkit.org/show_bug.cgi?id=163928
+
+        * parser/Lexer.cpp:
+        (JSC::Lexer<T>::fillTokenInfo):
+        (JSC::Lexer<T>::lex):
+        (JSC::Lexer<T>::scanRegExp):
+        (JSC::Lexer<T>::scanTrailingTemplateString):
+        (JSC::Lexer<T>::skipRegExp): Deleted.
+        * parser/Lexer.h:
+        (JSC::Lexer::getToken):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseAssignmentExpression):
+        * parser/Parser.h:
+        (JSC::Parser::getToken):
+        * parser/ParserTokens.h:
+
 2016-10-24  Per Arne Vollan  <pvol...@apple.com>
 
         [Win] CMake build type is not set.

Modified: trunk/Source/_javascript_Core/parser/Lexer.cpp (207797 => 207798)


--- trunk/Source/_javascript_Core/parser/Lexer.cpp	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/Source/_javascript_Core/parser/Lexer.cpp	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1783,6 +1783,18 @@
 }
 
 template <typename T>
+void Lexer<T>::fillTokenInfo(JSToken* tokenRecord, JSTokenType token, int lineNumber, int endOffset, int lineStartOffset, JSTextPosition endPosition)
+{
+    JSTokenLocation* tokenLocation = &tokenRecord->m_location;
+    tokenLocation->line = lineNumber;
+    tokenLocation->endOffset = endOffset;
+    tokenLocation->lineStartOffset = lineStartOffset;
+    ASSERT(tokenLocation->endOffset >= tokenLocation->lineStartOffset);
+    tokenRecord->m_endPosition = endPosition;
+    m_lastToken = token;
+}
+
+template <typename T>
 JSTokenType Lexer<T>::lex(JSToken* tokenRecord, unsigned lexerFlags, bool strictMode)
 {
     JSTokenData* tokenData = &tokenRecord->m_data;
@@ -1796,15 +1808,6 @@
     JSTokenType token = ERRORTOK;
     m_terminator = false;
 
-    auto fillTokenInfo = [&] (int lineNumber, int endOffset, int lineStartOffset, JSTextPosition endPosition) {
-        tokenLocation->line = lineNumber;
-        tokenLocation->endOffset = endOffset;
-        tokenLocation->lineStartOffset = lineStartOffset;
-        ASSERT(tokenLocation->endOffset >= tokenLocation->lineStartOffset);
-        tokenRecord->m_endPosition = endPosition;
-        m_lastToken = token;
-    };
-
 start:
     skipWhitespace();
 
@@ -2312,17 +2315,17 @@
             goto start;
 
         token = SEMICOLON;
-        fillTokenInfo(lineNumber, endOffset, lineStartOffset, endPosition);
+        fillTokenInfo(tokenRecord, token, lineNumber, endOffset, lineStartOffset, endPosition);
         return token;
     }
 
 returnToken:
-    fillTokenInfo(m_lineNumber, currentOffset(), currentLineStartOffset(), currentPosition());
+    fillTokenInfo(tokenRecord, token, m_lineNumber, currentOffset(), currentLineStartOffset(), currentPosition());
     return token;
 
 returnError:
     m_error = true;
-    fillTokenInfo(m_lineNumber, currentOffset(), currentLineStartOffset(), currentPosition());
+    fillTokenInfo(tokenRecord, token, m_lineNumber, currentOffset(), currentLineStartOffset(), currentPosition());
     RELEASE_ASSERT(token & ErrorTokenFlag);
     return token;
 }
@@ -2340,8 +2343,9 @@
 }
 
 template <typename T>
-bool Lexer<T>::scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar patternPrefix)
+JSTokenType Lexer<T>::scanRegExp(JSToken* tokenRecord, UChar patternPrefix)
 {
+    JSTokenData* tokenData = &tokenRecord->m_data;
     ASSERT(m_buffer16.isEmpty());
 
     bool lastWasEscape = false;
@@ -2358,7 +2362,11 @@
     while (true) {
         if (isLineTerminator(m_current) || atEnd()) {
             m_buffer16.shrink(0);
-            return false;
+            JSTokenType token = UNTERMINATED_REGEXP_LITERAL_ERRORTOK;
+            fillTokenInfo(tokenRecord, token, m_lineNumber, currentOffset(), currentLineStartOffset(), currentPosition());
+            m_error = true;
+            m_lexErrorMessage = makeString("Unterminated regular _expression_ literal '", getToken(*tokenRecord), "'");
+            return token;
         }
 
         T prev = m_current;
@@ -2389,7 +2397,7 @@
         }
     }
 
-    pattern = makeRightSizedIdentifier(m_buffer16.data(), m_buffer16.size(), charactersOredTogether);
+    tokenData->pattern = makeRightSizedIdentifier(m_buffer16.data(), m_buffer16.size(), charactersOredTogether);
 
     m_buffer16.shrink(0);
     charactersOredTogether = 0;
@@ -2400,51 +2408,15 @@
         shift();
     }
 
-    flags = makeRightSizedIdentifier(m_buffer16.data(), m_buffer16.size(), charactersOredTogether);
+    tokenData->flags = makeRightSizedIdentifier(m_buffer16.data(), m_buffer16.size(), charactersOredTogether);
     m_buffer16.shrink(0);
 
-    return true;
-}
+    // Since RegExp always ends with /, m_atLineStart always becomes false.
+    m_atLineStart = false;
 
-template <typename T>
-bool Lexer<T>::skipRegExp()
-{
-    bool lastWasEscape = false;
-    bool inBrackets = false;
-
-    while (true) {
-        if (isLineTerminator(m_current) || atEnd())
-            return false;
-
-        T prev = m_current;
-        
-        shift();
-
-        if (prev == '/' && !lastWasEscape && !inBrackets)
-            break;
-
-        if (lastWasEscape) {
-            lastWasEscape = false;
-            continue;
-        }
-
-        switch (prev) {
-        case '[':
-            inBrackets = true;
-            break;
-        case ']':
-            inBrackets = false;
-            break;
-        case '\\':
-            lastWasEscape = true;
-            break;
-        }
-    }
-
-    while (isIdentPart(m_current))
-        shift();
-
-    return true;
+    JSTokenType token = REGEXP;
+    fillTokenInfo(tokenRecord, token, m_lineNumber, currentOffset(), currentLineStartOffset(), currentPosition());
+    return token;
 }
 
 template <typename T>
@@ -2451,7 +2423,6 @@
 JSTokenType Lexer<T>::scanTrailingTemplateString(JSToken* tokenRecord, RawStringsBuildMode rawStringsBuildMode)
 {
     JSTokenData* tokenData = &tokenRecord->m_data;
-    JSTokenLocation* tokenLocation = &tokenRecord->m_location;
     ASSERT(!m_error);
     ASSERT(m_buffer16.isEmpty());
 
@@ -2462,20 +2433,12 @@
     if (UNLIKELY(result != StringParsedSuccessfully)) {
         token = result == StringUnterminated ? UNTERMINATED_TEMPLATE_LITERAL_ERRORTOK : INVALID_TEMPLATE_LITERAL_ERRORTOK;
         m_error = true;
-    } else {
+    } else
         token = TEMPLATE;
-        m_lastToken = token;
-    }
 
     // Since TemplateString always ends with ` or }, m_atLineStart always becomes false.
     m_atLineStart = false;
-
-    // Adjust current tokenLocation data for TemplateString.
-    tokenLocation->line = m_lineNumber;
-    tokenLocation->endOffset = currentOffset();
-    tokenLocation->lineStartOffset = currentLineStartOffset();
-    ASSERT(tokenLocation->endOffset >= tokenLocation->lineStartOffset);
-    tokenRecord->m_endPosition = currentPosition();
+    fillTokenInfo(tokenRecord, token, m_lineNumber, currentOffset(), currentLineStartOffset(), currentPosition());
     return token;
 }
 

Modified: trunk/Source/_javascript_Core/parser/Lexer.h (207797 => 207798)


--- trunk/Source/_javascript_Core/parser/Lexer.h	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/Source/_javascript_Core/parser/Lexer.h	2016-10-25 02:35:59 UTC (rev 207798)
@@ -75,10 +75,9 @@
     void setLastLineNumber(int lastLineNumber) { m_lastLineNumber = lastLineNumber; }
     int lastLineNumber() const { return m_lastLineNumber; }
     bool prevTerminator() const { return m_terminator; }
-    bool scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar patternPrefix = 0);
+    JSTokenType scanRegExp(JSToken*, UChar patternPrefix = 0);
     enum class RawStringsBuildMode { BuildRawStrings, DontBuildRawStrings };
     JSTokenType scanTrailingTemplateString(JSToken*, RawStringsBuildMode);
-    bool skipRegExp();
 
     // Functions for use after parsing.
     bool sawError() const { return m_error; }
@@ -115,6 +114,13 @@
 
     JSTokenType lexExpectIdentifier(JSToken*, unsigned, bool strictMode);
 
+    ALWAYS_INLINE StringView getToken(const JSToken& token)
+    {
+        SourceProvider* sourceProvider = m_source->provider();
+        ASSERT_WITH_MESSAGE(token.m_location.startOffset <= token.m_location.endOffset, "Calling this function with the baked token.");
+        return sourceProvider->getRange(token.m_location.startOffset, token.m_location.endOffset);
+    }
+
 private:
     void record8(int);
     void append8(const T*, size_t);
@@ -181,6 +187,8 @@
     template <unsigned length>
     ALWAYS_INLINE bool consume(const char (&input)[length]);
 
+    void fillTokenInfo(JSToken*, JSTokenType, int lineNumber, int endOffset, int lineStartOffset, JSTextPosition endPosition);
+
     static const size_t initialReadBufferCapacity = 32;
 
     int m_lineNumber;

Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (207797 => 207798)


--- trunk/Source/_javascript_Core/parser/Parser.cpp	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp	2016-10-25 02:35:59 UTC (rev 207798)
@@ -4306,13 +4306,14 @@
     case DIVEQUAL:
     case DIVIDE: {
         /* regexp */
-        const Identifier* pattern;
-        const Identifier* flags;
         if (match(DIVEQUAL))
-            failIfFalse(m_lexer->scanRegExp(pattern, flags, '='), "Invalid regular _expression_");
+            m_token.m_type = m_lexer->scanRegExp(&m_token, '=');
         else
-            failIfFalse(m_lexer->scanRegExp(pattern, flags), "Invalid regular _expression_");
-        
+            m_token.m_type = m_lexer->scanRegExp(&m_token);
+        matchOrFail(REGEXP, "Invalid regular _expression_");
+
+        const Identifier* pattern = m_token.m_data.pattern;
+        const Identifier* flags = m_token.m_data.flags;
         JSTextPosition start = tokenStartPosition();
         JSTokenLocation location(tokenLocation());
         next();

Modified: trunk/Source/_javascript_Core/parser/Parser.h (207797 => 207798)


--- trunk/Source/_javascript_Core/parser/Parser.h	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/Source/_javascript_Core/parser/Parser.h	2016-10-25 02:35:59 UTC (rev 207798)
@@ -1288,9 +1288,9 @@
     }
 
     void printUnexpectedTokenText(WTF::PrintStream&);
-    ALWAYS_INLINE StringView getToken() {
-        SourceProvider* sourceProvider = m_source->provider();
-        return sourceProvider->getRange(tokenStart(), tokenEndPosition().offset);
+    ALWAYS_INLINE StringView getToken()
+    {
+        return m_lexer->getToken(m_token);
     }
     
     ALWAYS_INLINE bool match(JSTokenType expected)

Modified: trunk/Source/_javascript_Core/parser/ParserTokens.h (207797 => 207798)


--- trunk/Source/_javascript_Core/parser/ParserTokens.h	2016-10-25 01:48:42 UTC (rev 207797)
+++ trunk/Source/_javascript_Core/parser/ParserTokens.h	2016-10-25 02:35:59 UTC (rev 207798)
@@ -96,6 +96,7 @@
     IDENT,
     STRING,
     TEMPLATE,
+    REGEXP,
     SEMICOLON,
     COLON,
     DOT,
@@ -166,7 +167,8 @@
     UNTERMINATED_HEX_NUMBER_ERRORTOK = 11 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
     UNTERMINATED_BINARY_NUMBER_ERRORTOK = 12 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
     UNTERMINATED_TEMPLATE_LITERAL_ERRORTOK = 13 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
-    INVALID_TEMPLATE_LITERAL_ERRORTOK = 14 | ErrorTokenFlag,
+    UNTERMINATED_REGEXP_LITERAL_ERRORTOK = 14 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
+    INVALID_TEMPLATE_LITERAL_ERRORTOK = 15 | ErrorTokenFlag,
 };
 
 struct JSTextPosition {
@@ -199,6 +201,10 @@
         const Identifier* raw;
         bool isTail;
     };
+    struct {
+        const Identifier* pattern;
+        const Identifier* flags;
+    };
 };
 
 struct JSTokenLocation {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to