Bug 1185106 - Part 6.1: Support async function expression in Parser. r=till draft
authorTooru Fujisawa <arai_a@mac.com>
Sun, 28 Aug 2016 23:58:28 +0900
changeset 430932 6bde9502ed3cbcf771b8169ff89a58922dfae87d
parent 430931 bc51f7a59554539c5f2dc42715a129088949d428
child 430933 e3ac6d185295ce982b606aefd6bb1bf9efb65172
push id33945
push userarai_a@mac.com
push dateFri, 28 Oct 2016 11:34:02 +0000
reviewerstill
bugs1185106
milestone52.0a1
Bug 1185106 - Part 6.1: Support async function expression in Parser. r=till MozReview-Commit-ID: Ed7PAq3bNTX
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -3518,44 +3518,49 @@ Parser<ParseHandler>::functionStmt(Yield
         return finishLexicalScope(*synthesizedScopeForAnnexB, synthesizedStmtList);
     }
 
     return fun;
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
-Parser<ParseHandler>::functionExpr(InvokedPrediction invoked)
+Parser<ParseHandler>::functionExpr(InvokedPrediction invoked, FunctionAsyncKind asyncKind)
 {
     MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FUNCTION));
 
-    GeneratorKind generatorKind = NotGenerator;
+    AutoAwaitIsKeyword awaitIsKeyword(&tokenStream, asyncKind == AsyncFunction);
+    GeneratorKind generatorKind = asyncKind == AsyncFunction ? StarGenerator : NotGenerator;
     TokenKind tt;
     if (!tokenStream.getToken(&tt))
         return null();
 
     if (tt == TOK_MUL) {
+        if (asyncKind != SyncFunction) {
+            report(ParseError, false, null(), JSMSG_ASYNC_GENERATOR);
+            return null();
+        }
         generatorKind = StarGenerator;
         if (!tokenStream.getToken(&tt))
             return null();
     }
 
-    YieldHandling yieldHandling = GetYieldHandling(generatorKind, SyncFunction);
+    YieldHandling yieldHandling = GetYieldHandling(generatorKind, asyncKind);
 
     RootedPropertyName name(context);
     if (tt == TOK_NAME || tt == TOK_YIELD) {
         name = bindingIdentifier(yieldHandling);
         if (!name)
             return null();
     } else {
         tokenStream.ungetToken();
     }
 
     return functionDefinition(InAllowed, yieldHandling, name, Expression, generatorKind,
-                              SyncFunction, invoked);
+                              asyncKind, invoked);
 }
 
 /*
  * Return true if this node, known to be an unparenthesized string literal,
  * could be the string of a directive in a Directive Prologue. Directive
  * strings never contain escape sequences or line continuations.
  * isEscapeFreeStringLiteral, below, checks whether the node itself could be
  * a directive.
@@ -9234,16 +9239,27 @@ Parser<ParseHandler>::primaryExpr(YieldH
       case TOK_NO_SUBS_TEMPLATE:
         return noSubstitutionTemplate();
 
       case TOK_STRING:
         return stringLiteral();
 
       case TOK_YIELD:
       case TOK_NAME: {
+        if (tokenStream.currentName() == context->names().async) {
+            TokenKind nextSameLine = TOK_EOF;
+            if (!tokenStream.peekTokenSameLine(&nextSameLine))
+                return null();
+
+            if (nextSameLine == TOK_FUNCTION) {
+                tokenStream.consumeKnownToken(TOK_FUNCTION);
+                return functionExpr(PredictUninvoked, AsyncFunction);
+            }
+        }
+
         Rooted<PropertyName*> name(context, identifierReference(yieldHandling));
         if (!name)
             return null();
 
         return identifierReference(name);
       }
 
       case TOK_REGEXP:
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -1082,17 +1082,18 @@ class Parser final : private JS::AutoGCR
      * number of the parsers this is convenient and avoids a lot of
      * unnecessary ungetting and regetting of tokens.
      *
      * Some parsers have two versions:  an always-inlined version (with an 'i'
      * suffix) and a never-inlined version (with an 'n' suffix).
      */
     Node functionStmt(YieldHandling yieldHandling, DefaultHandling defaultHandling,
                       FunctionAsyncKind asyncKind = SyncFunction);
-    Node functionExpr(InvokedPrediction invoked = PredictUninvoked);
+    Node functionExpr(InvokedPrediction invoked = PredictUninvoked,
+                      FunctionAsyncKind asyncKind = SyncFunction);
 
     Node statementList(YieldHandling yieldHandling);
 
     Node blockStatement(YieldHandling yieldHandling,
                         unsigned errorNumber = JSMSG_CURLY_IN_COMPOUND);
     Node doWhileStatement(YieldHandling yieldHandling);
     Node whileStatement(YieldHandling yieldHandling);