Bug 1219877 - Allow let token with TOK_NAME in strict mode in Parser::shouldParseLetDeclaration. r=shu, a=ritu
authorTooru Fujisawa <arai_a@mac.com>
Fri, 30 Oct 2015 05:06:20 +0900
changeset 305379 d2e9e817010addf21d6a887b5c76384d8bcf542f
parent 305378 3b6702f55a1946e411fa2c3e3967ed7354b938d5
child 305380 6b3d8fdb0c789fe6411e0f9bf814b93f4d575cee
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshu, ritu
bugs1219877
milestone44.0a2
Bug 1219877 - Allow let token with TOK_NAME in strict mode in Parser::shouldParseLetDeclaration. r=shu, a=ritu
js/src/frontend/Parser.cpp
js/src/jit-test/tests/parser/let-after-directive.js
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -6653,19 +6653,16 @@ Parser<SyntaxParseHandler>::classDefinit
     MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
     return SyntaxParseHandler::NodeFailure;
 }
 
 template <typename ParseHandler>
 bool
 Parser<ParseHandler>::shouldParseLetDeclaration(bool* parseDeclOut)
 {
-    // 'let' is a reserved keyword in strict mode and we shouldn't get here.
-    MOZ_ASSERT(!pc->sc->strict());
-
     TokenKind tt;
     *parseDeclOut = false;
 
     if (!tokenStream.peekToken(&tt))
         return false;
 
     switch (tt) {
       case TOK_NAME:
@@ -6686,16 +6683,19 @@ Parser<ParseHandler>::shouldParseLetDecl
     return true;
 }
 
 template <typename ParseHandler>
 bool
 Parser<ParseHandler>::peekShouldParseLetDeclaration(bool* parseDeclOut,
                                                     TokenStream::Modifier modifier)
 {
+    // 'let' is a reserved keyword in strict mode and we shouldn't get here.
+    MOZ_ASSERT(!pc->sc->strict());
+
     *parseDeclOut = false;
 
 #ifdef DEBUG
     TokenKind tt;
     if (!tokenStream.peekToken(&tt, modifier))
         return false;
     MOZ_ASSERT(tt == TOK_NAME && tokenStream.nextName() == context->names().let);
 #endif
@@ -6772,17 +6772,22 @@ Parser<ParseHandler>::statement(YieldHan
                 return null();
             return labeledStatement(yieldHandling);
         }
         return expressionStatement(yieldHandling);
       }
 
       case TOK_NAME: {
         // 'let' is a contextual keyword in sloppy node. In strict mode, it is
-        // always lexed as TOK_LET.
+        // always lexed as TOK_LET except following case:
+        //
+        //   "use strict"
+        //   let a = 1;
+        //
+        // There 'let' is lexed as TOK_NAME before parsing directive.
         if (tokenStream.currentName() == context->names().let) {
             bool parseDecl;
             if (!shouldParseLetDeclaration(&parseDecl))
                 return null();
             if (parseDecl)
                 return lexicalDeclaration(yieldHandling, /* isConst = */ false);
         }
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/parser/let-after-directive.js
@@ -0,0 +1,6 @@
+// 'let' after "use strict" directive without semicolon is lexed as TOK_NAME
+// before parsing the directive.  'let' with TOK_NAME should be handled
+// correctly in strict mode.
+
+"use strict"
+let a = 1;