Bug 1185106 - Part 5.3: Support await expression in Parser. r=till
authorTooru Fujisawa <arai_a@mac.com>
Sun, 28 Aug 2016 20:42:40 +0900
changeset 346919 2465f743fb4f2b36e0a92a44a02f93472a1ad63e
parent 346918 0572beaf72429bbffaeede34b8ce40829e62715b
child 346920 7dd9e2d62584ccfa708d322c55980015cea6df76
push id10298
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:33:03 +0000
treeherdermozilla-aurora@7e29173b1641 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill
bugs1185106
milestone52.0a1
Bug 1185106 - Part 5.3: Support await expression in Parser. r=till MozReview-Commit-ID: BspiXPRu6SR
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/FoldConstants.cpp
js/src/frontend/FullParseHandler.h
js/src/frontend/NameFunctions.cpp
js/src/frontend/ParseNode.cpp
js/src/frontend/ParseNode.h
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
js/src/frontend/SyntaxParseHandler.h
js/src/js.msg
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -2460,16 +2460,17 @@ BytecodeEmitter::checkSideEffects(ParseN
       // This invokes the (user-controllable) iterator protocol.
       case PNK_SPREAD:
         MOZ_ASSERT(pn->isArity(PN_UNARY));
         *answer = true;
         return true;
 
       case PNK_YIELD_STAR:
       case PNK_YIELD:
+      case PNK_AWAIT:
         MOZ_ASSERT(pn->isArity(PN_BINARY));
         *answer = true;
         return true;
 
       // Deletion generally has side effects, even if isolated cases have none.
       case PNK_DELETENAME:
       case PNK_DELETEPROP:
       case PNK_DELETEELEM:
@@ -9247,16 +9248,17 @@ BytecodeEmitter::emitTree(ParseNode* pn,
         break;
 
       case PNK_GENERATOR:
         if (!emit1(JSOP_GENERATOR))
             return false;
         break;
 
       case PNK_YIELD:
+      case PNK_AWAIT:
         if (!emitYield(pn))
             return false;
         break;
 
       case PNK_STATEMENTLIST:
         if (!emitStatementList(pn))
             return false;
         break;
--- a/js/src/frontend/FoldConstants.cpp
+++ b/js/src/frontend/FoldConstants.cpp
@@ -306,16 +306,17 @@ ContainsHoistedDeclaration(ExclusiveCont
       case PNK_COMPUTED_NAME:
       case PNK_SPREAD:
       case PNK_MUTATEPROTO:
       case PNK_COLON:
       case PNK_SHORTHAND:
       case PNK_CONDITIONAL:
       case PNK_TYPEOFNAME:
       case PNK_TYPEOFEXPR:
+      case PNK_AWAIT:
       case PNK_VOID:
       case PNK_NOT:
       case PNK_BITNOT:
       case PNK_DELETENAME:
       case PNK_DELETEPROP:
       case PNK_DELETEELEM:
       case PNK_DELETEEXPR:
       case PNK_POS:
@@ -1778,16 +1779,17 @@ Fold(ExclusiveContext* cx, ParseNode** p
         return FoldList(cx, pn, parser, inGenexpLambda);
 
       case PNK_YIELD_STAR:
         MOZ_ASSERT(pn->isArity(PN_BINARY));
         MOZ_ASSERT(pn->pn_right->isKind(PNK_NAME));
         return Fold(cx, &pn->pn_left, parser, inGenexpLambda);
 
       case PNK_YIELD:
+      case PNK_AWAIT:
         MOZ_ASSERT(pn->isArity(PN_BINARY));
         MOZ_ASSERT(pn->pn_right->isKind(PNK_NAME) ||
                    (pn->pn_right->isKind(PNK_ASSIGN) &&
                     pn->pn_right->pn_left->isKind(PNK_NAME) &&
                     pn->pn_right->pn_right->isKind(PNK_GENERATOR)));
         if (!pn->pn_left)
             return true;
         return Fold(cx, &pn->pn_left, parser, inGenexpLambda);
--- a/js/src/frontend/FullParseHandler.h
+++ b/js/src/frontend/FullParseHandler.h
@@ -427,16 +427,21 @@ class FullParseHandler
         return new_<BinaryNode>(PNK_YIELD, op, pos, value, gen);
     }
 
     ParseNode* newYieldStarExpression(uint32_t begin, ParseNode* value, ParseNode* gen) {
         TokenPos pos(begin, value->pn_pos.end);
         return new_<BinaryNode>(PNK_YIELD_STAR, JSOP_NOP, pos, value, gen);
     }
 
+    ParseNode* newAwaitExpression(uint32_t begin, ParseNode* value, ParseNode* gen) {
+        TokenPos pos(begin, value ? value->pn_pos.end : begin + 1);
+        return new_<BinaryNode>(PNK_AWAIT, JSOP_YIELD, pos, value, gen);
+    }
+
     // Statements
 
     ParseNode* newStatementList(const TokenPos& pos) {
         return new_<ListNode>(PNK_STATEMENTLIST, pos);
     }
 
     MOZ_MUST_USE bool isFunctionStmt(ParseNode* stmt) {
         while (stmt->isKind(PNK_LABEL))
--- a/js/src/frontend/NameFunctions.cpp
+++ b/js/src/frontend/NameFunctions.cpp
@@ -502,16 +502,17 @@ class NameResolver
           case PNK_YIELD_STAR:
             MOZ_ASSERT(cur->isArity(PN_BINARY));
             MOZ_ASSERT(cur->pn_right->isKind(PNK_NAME));
             if (!resolve(cur->pn_left, prefix))
                 return false;
             break;
 
           case PNK_YIELD:
+          case PNK_AWAIT:
             MOZ_ASSERT(cur->isArity(PN_BINARY));
             if (cur->pn_left) {
                 if (!resolve(cur->pn_left, prefix))
                     return false;
             }
             MOZ_ASSERT(cur->pn_right->isKind(PNK_NAME) ||
                        (cur->pn_right->isKind(PNK_ASSIGN) &&
                         cur->pn_right->pn_left->isKind(PNK_NAME) &&
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -285,17 +285,18 @@ PushNodeChildren(ParseNode* pn, NodeStac
         return PushResult::Recyclable;
       }
 
       // The left half is the expression being yielded.  The right half is
       // internal goop: a name reference to the invisible '.generator' local
       // variable, or an assignment of a PNK_GENERATOR node to the '.generator'
       // local, for a synthesized, prepended initial yield.  Yum!
       case PNK_YIELD_STAR:
-      case PNK_YIELD: {
+      case PNK_YIELD:
+      case PNK_AWAIT: {
         MOZ_ASSERT(pn->isArity(PN_BINARY));
         MOZ_ASSERT(pn->pn_right);
         MOZ_ASSERT(pn->pn_right->isKind(PNK_NAME) ||
                    (pn->pn_right->isKind(PNK_ASSIGN) &&
                     pn->pn_right->pn_left->isKind(PNK_NAME) &&
                     pn->pn_right->pn_right->isKind(PNK_GENERATOR)));
         if (pn->pn_left)
             stack->push(pn->pn_left);
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -115,16 +115,17 @@ class ObjectBox;
     F(SETTHIS) \
     \
     /* Unary operators. */ \
     F(TYPEOFNAME) \
     F(TYPEOFEXPR) \
     F(VOID) \
     F(NOT) \
     F(BITNOT) \
+    F(AWAIT) \
     \
     /* \
      * Binary operators. \
      * These must be in the same order as TOK_OR and friends in TokenStream.h. \
      */ \
     F(OR) \
     F(AND) \
     F(BITOR) \
@@ -345,17 +346,18 @@ IsTypeofKind(ParseNodeKind kind)
  * PNK_MOD,
  * PNK_POW                  (**) is right-associative, but forms a list
  *                          nonetheless. Special hacks everywhere.
  *
  * PNK_POS,     unary       pn_kid: UNARY expr
  * PNK_NEG
  * PNK_VOID,    unary       pn_kid: UNARY expr
  * PNK_NOT,
- * PNK_BITNOT
+ * PNK_BITNOT,
+ * PNK_AWAIT
  * PNK_TYPEOFNAME, unary    pn_kid: UNARY expr
  * PNK_TYPEOFEXPR
  * PNK_PREINCREMENT, unary  pn_kid: MEMBER expr
  * PNK_POSTINCREMENT,
  * PNK_PREDECREMENT,
  * PNK_POSTDECREMENT
  * PNK_NEW      list        pn_head: list of ctor, arg1, arg2, ... argN
  *                          pn_count: 1 + N (where N is number of args)
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -852,17 +852,17 @@ Parser<ParseHandler>::reportBadReturn(No
 template <typename ParseHandler>
 bool
 Parser<ParseHandler>::isValidStrictBinding(PropertyName* name)
 {
     return name != context->names().eval &&
            name != context->names().arguments &&
            name != context->names().let &&
            name != context->names().static_ &&
-           !IsKeyword(name);
+           !(IsKeyword(name) && name != context->names().await);
 }
 
 /*
  * Check that it is permitted to introduce a binding for |name|. Use |pos| for
  * reporting error locations.
  */
 template <typename ParseHandler>
 bool
@@ -2729,20 +2729,19 @@ Parser<ParseHandler>::functionArguments(
                 if (duplicatedParam) {
                     // Has duplicated args before the destructuring parameter.
                     report(ParseError, false, null(), JSMSG_BAD_DUP_ARGS);
                     return false;
                 }
 
                 funbox->hasDestructuringArgs = true;
 
-                Node destruct = destructuringDeclarationWithoutYield(
+                Node destruct = destructuringDeclarationWithoutYieldOrAwait(
                     DeclarationKind::FormalParameter,
-                    yieldHandling, tt,
-                    JSMSG_YIELD_IN_DEFAULT);
+                    yieldHandling, tt);
                 if (!destruct)
                     return false;
 
                 if (!noteDestructuredPositionalFormalParameter(funcpn, destruct))
                     return false;
 
                 break;
               }
@@ -2801,17 +2800,17 @@ Parser<ParseHandler>::functionArguments(
                     hasDefault = true;
 
                     // The Function.length property is the number of formals
                     // before the first default argument.
                     funbox->length = positionalFormals.length() - 1;
                 }
                 funbox->hasParameterExprs = true;
 
-                Node def_expr = assignExprWithoutYield(yieldHandling, JSMSG_YIELD_IN_DEFAULT);
+                Node def_expr = assignExprWithoutYieldOrAwait(yieldHandling);
                 if (!def_expr)
                     return false;
                 if (!handler.setLastFunctionFormalParameterDefault(funcpn, def_expr))
                     return false;
             }
 
             if (parenFreeArrow || IsSetterKind(kind))
                 break;
@@ -3346,16 +3345,17 @@ Parser<ParseHandler>::functionFormalPara
 {
     // Given a properly initialized parse context, try to parse an actual
     // function without concern for conversion to strict mode, use of lazy
     // parsing and such.
 
     FunctionBox* funbox = pc->functionBox();
     RootedFunction fun(context, funbox->function());
 
+    AutoAwaitIsKeyword awaitIsKeyword(&tokenStream, funbox->isAsync());
     if (!functionArguments(yieldHandling, kind, pn))
         return false;
 
     Maybe<ParseContext::VarScope> varScope;
     if (funbox->hasParameterExprs) {
         varScope.emplace(this);
         if (!varScope->init(pc))
             return false;
@@ -4159,26 +4159,32 @@ Parser<ParseHandler>::destructuringDecla
     if (!pattern || !checkDestructuringPattern(pattern, Some(kind), &possibleError))
         return null();
 
     return pattern;
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
-Parser<ParseHandler>::destructuringDeclarationWithoutYield(DeclarationKind kind,
-                                                           YieldHandling yieldHandling,
-                                                           TokenKind tt, unsigned msg)
+Parser<ParseHandler>::destructuringDeclarationWithoutYieldOrAwait(DeclarationKind kind,
+                                                                  YieldHandling yieldHandling,
+                                                                  TokenKind tt)
 {
     uint32_t startYieldOffset = pc->lastYieldOffset;
+    uint32_t startAwaitOffset = pc->lastAwaitOffset;
     Node res = destructuringDeclaration(kind, yieldHandling, tt);
-    if (res && pc->lastYieldOffset != startYieldOffset) {
-        reportWithOffset(ParseError, false, pc->lastYieldOffset,
-                         msg, js_yield_str);
-        return null();
+    if (res) {
+        if (pc->lastYieldOffset != startYieldOffset) {
+            reportWithOffset(ParseError, false, pc->lastYieldOffset, JSMSG_YIELD_IN_DEFAULT);
+            return null();
+        }
+        if (pc->lastAwaitOffset != startAwaitOffset) {
+            reportWithOffset(ParseError, false, pc->lastAwaitOffset, JSMSG_AWAIT_IN_DEFAULT);
+            return null();
+        }
     }
     return res;
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::blockStatement(YieldHandling yieldHandling, unsigned errorNumber)
 {
@@ -5867,16 +5873,26 @@ Parser<ParseHandler>::newYieldExpression
         return null();
     if (isYieldStar)
         return handler.newYieldStarExpression(begin, expr, generator);
     return handler.newYieldExpression(begin, expr, generator);
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
+Parser<ParseHandler>::newAwaitExpression(uint32_t begin, typename ParseHandler::Node expr)
+{
+    Node generator = newDotGeneratorName();
+    if (!generator)
+        return null();
+    return handler.newAwaitExpression(begin, expr, generator);
+}
+
+template <typename ParseHandler>
+typename ParseHandler::Node
 Parser<ParseHandler>::yieldExpression(InHandling inHandling)
 {
     MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_YIELD));
     uint32_t begin = pos().begin;
 
     switch (pc->generatorKind()) {
       case StarGenerator:
       {
@@ -7785,16 +7801,31 @@ Parser<ParseHandler>::unaryExpr(YieldHan
             if (!report(ParseStrictError, pc->sc()->strict(), expr, JSMSG_DEPRECATED_DELETE_OPERAND))
                 return null();
             pc->sc()->setBindingsAccessedDynamically();
         }
 
         return handler.newDelete(begin, expr);
       }
 
+      case TOK_AWAIT: {
+        TokenKind nextSameLine = TOK_EOF;
+        if (!tokenStream.peekTokenSameLine(&nextSameLine, TokenStream::Operand))
+            return null();
+        if (nextSameLine != TOK_EOL) {
+            Node kid = unaryExpr(yieldHandling, tripledotHandling, possibleError, invoked);
+            if (!kid)
+                return null();
+            pc->lastAwaitOffset = begin;
+            return newAwaitExpression(begin, kid);
+        }
+        report(ParseError, false, null(), JSMSG_LINE_BREAK_AFTER_AWAIT);
+        return null();
+      }
+
       default: {
         Node pn = memberExpr(yieldHandling, tripledotHandling, tt, /* allowCallSyntax = */ true,
                              possibleError, invoked);
         if (!pn)
             return null();
 
         /* Don't look across a newline boundary for a postfix incop. */
         if (!tokenStream.peekTokenSameLine(&tt))
@@ -8114,24 +8145,30 @@ Parser<ParseHandler>::generatorComprehen
     handler.setBeginPosition(result, begin);
     handler.setEndPosition(result, pos().end);
 
     return result;
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
-Parser<ParseHandler>::assignExprWithoutYield(YieldHandling yieldHandling, unsigned msg)
+Parser<ParseHandler>::assignExprWithoutYieldOrAwait(YieldHandling yieldHandling)
 {
     uint32_t startYieldOffset = pc->lastYieldOffset;
+    uint32_t startAwaitOffset = pc->lastAwaitOffset;
     Node res = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
-    if (res && pc->lastYieldOffset != startYieldOffset) {
-        reportWithOffset(ParseError, false, pc->lastYieldOffset,
-                         msg, js_yield_str);
-        return null();
+    if (res) {
+        if (pc->lastYieldOffset != startYieldOffset) {
+            reportWithOffset(ParseError, false, pc->lastYieldOffset, JSMSG_YIELD_IN_DEFAULT);
+            return null();
+        }
+        if (pc->lastAwaitOffset != startAwaitOffset) {
+            reportWithOffset(ParseError, false, pc->lastAwaitOffset, JSMSG_AWAIT_IN_DEFAULT);
+            return null();
+        }
     }
     return res;
 }
 
 template <typename ParseHandler>
 bool
 Parser<ParseHandler>::argumentList(YieldHandling yieldHandling, Node listNode, bool* isSpread)
 {
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -310,16 +310,21 @@ class ParseContext : public Nestable<Par
     bool superScopeNeedsHomeObject_;
 
   public:
     // lastYieldOffset stores the offset of the last yield that was parsed.
     // NoYieldOffset is its initial value.
     static const uint32_t NoYieldOffset = UINT32_MAX;
     uint32_t lastYieldOffset;
 
+    // lastAwaitOffset stores the offset of the last await that was parsed.
+    // NoAwaitOffset is its initial value.
+    static const uint32_t NoAwaitOffset = UINT32_MAX;
+    uint32_t         lastAwaitOffset;
+
     // All inner functions in this context. Only used when syntax parsing.
     Rooted<GCVector<JSFunction*, 8>> innerFunctionsForLazy;
 
     // In a function context, points to a Directive struct that can be updated
     // to reflect new directives encountered in the Directive Prologue that
     // require reparsing the function. In global/module/generator-tail contexts,
     // we don't need to reparse when encountering a DirectivePrologue so this
     // pointer may be nullptr.
@@ -353,16 +358,17 @@ class ParseContext : public Nestable<Par
         varScope_(nullptr),
         innerFunctionBoxesForAnnexB_(prs->context->frontendCollectionPool()),
         positionalFormalParameterNames_(prs->context->frontendCollectionPool()),
         closedOverBindingsForLazy_(prs->context->frontendCollectionPool()),
         scriptId_(prs->usedNames.nextScriptId()),
         isStandaloneFunctionBody_(false),
         superScopeNeedsHomeObject_(false),
         lastYieldOffset(NoYieldOffset),
+        lastAwaitOffset(NoAwaitOffset),
         innerFunctionsForLazy(prs->context, GCVector<JSFunction*, 8>(prs->context)),
         newDirectives(newDirectives),
         funHasReturnExpr(false),
         funHasReturnVoid(false)
     {
         if (isFunctionBox()) {
             if (functionBox()->function()->isNamedLambda())
                 namedLambdaScope_.emplace(prs);
@@ -984,16 +990,17 @@ class Parser final : private JS::AutoGCR
     bool appendToCallSiteObj(Node callSiteObj);
     bool addExprAndGetNextTemplStrToken(YieldHandling yieldHandling, Node nodeList,
                                         TokenKind* ttp);
     bool checkStatementsEOF();
 
     inline Node newName(PropertyName* name);
     inline Node newName(PropertyName* name, TokenPos pos);
     inline Node newYieldExpression(uint32_t begin, Node expr, bool isYieldStar = false);
+    inline Node newAwaitExpression(uint32_t begin, Node expr);
 
     inline bool abortIfSyntaxParser();
 
   public:
     /* Public entry points for parsing. */
     Node statement(YieldHandling yieldHandling);
     Node statementListItem(YieldHandling yieldHandling, bool canHaveDirectives = false);
 
@@ -1180,17 +1187,17 @@ class Parser final : private JS::AutoGCR
                                       Node* forInOrOfExpression);
 
     Node expr(InHandling inHandling, YieldHandling yieldHandling,
               TripledotHandling tripledotHandling, PossibleError* possibleError = nullptr,
               InvokedPrediction invoked = PredictUninvoked);
     Node assignExpr(InHandling inHandling, YieldHandling yieldHandling,
                     TripledotHandling tripledotHandling, PossibleError* possibleError = nullptr,
                     InvokedPrediction invoked = PredictUninvoked);
-    Node assignExprWithoutYield(YieldHandling yieldHandling, unsigned err);
+    Node assignExprWithoutYieldOrAwait(YieldHandling yieldHandling);
     Node yieldExpression(InHandling inHandling);
     Node condExpr1(InHandling inHandling, YieldHandling yieldHandling,
                    TripledotHandling tripledotHandling,
                    PossibleError* possibleError,
                    InvokedPrediction invoked = PredictUninvoked);
     Node orExpr1(InHandling inHandling, YieldHandling yieldHandling,
                  TripledotHandling tripledotHandling,
                  PossibleError* possibleError,
@@ -1241,18 +1248,18 @@ class Parser final : private JS::AutoGCR
     Node comprehensionTail(GeneratorKind comprehensionKind);
     Node comprehension(GeneratorKind comprehensionKind);
     Node arrayComprehension(uint32_t begin);
     Node generatorComprehension(uint32_t begin);
 
     bool argumentList(YieldHandling yieldHandling, Node listNode, bool* isSpread);
     Node destructuringDeclaration(DeclarationKind kind, YieldHandling yieldHandling,
                                   TokenKind tt);
-    Node destructuringDeclarationWithoutYield(DeclarationKind kind, YieldHandling yieldHandling,
-                                              TokenKind tt, unsigned msg);
+    Node destructuringDeclarationWithoutYieldOrAwait(DeclarationKind kind, YieldHandling yieldHandling,
+                                                     TokenKind tt);
 
     bool namedImportsOrNamespaceImport(TokenKind tt, Node importSpecSet);
     bool checkExportedName(JSAtom* exportName);
     bool checkExportedNamesForDeclaration(Node node);
 
     enum ClassContext { ClassStatement, ClassExpression };
     Node classDefinition(YieldHandling yieldHandling, ClassContext classContext,
                          DefaultHandling defaultHandling);
--- a/js/src/frontend/SyntaxParseHandler.h
+++ b/js/src/frontend/SyntaxParseHandler.h
@@ -284,16 +284,17 @@ class SyntaxParseHandler
 
     MOZ_MUST_USE bool addPrototypeMutation(Node literal, uint32_t begin, Node expr) { return true; }
     MOZ_MUST_USE bool addPropertyDefinition(Node literal, Node name, Node expr) { return true; }
     MOZ_MUST_USE bool addShorthand(Node literal, Node name, Node expr) { return true; }
     MOZ_MUST_USE bool addObjectMethodDefinition(Node literal, Node name, Node fn, JSOp op) { return true; }
     MOZ_MUST_USE bool addClassMethodDefinition(Node literal, Node name, Node fn, JSOp op, bool isStatic) { return true; }
     Node newYieldExpression(uint32_t begin, Node value, Node gen) { return NodeGeneric; }
     Node newYieldStarExpression(uint32_t begin, Node value, Node gen) { return NodeGeneric; }
+    Node newAwaitExpression(uint32_t begin, Node value, Node gen) { return NodeGeneric; }
 
     // Statements
 
     Node newStatementList(const TokenPos& pos) { return NodeGeneric; }
     void addStatementToList(Node list, Node stmt) {}
     void addCaseStatementToList(Node list, Node stmt) {}
     MOZ_MUST_USE bool prependInitialYield(Node stmtList, Node gen) { return true; }
     Node newEmptyStatement(const TokenPos& pos) { return NodeEmptyStatement; }
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -177,16 +177,17 @@ MSG_DEF(JSMSG_UNKNOWN_FORMAT,          1
 
 // Frontend
 MSG_DEF(JSMSG_ACCESSOR_WRONG_ARGS,     3, JSEXN_SYNTAXERR, "{0} functions must have {1} argument{2}")
 MSG_DEF(JSMSG_ARRAY_COMP_LEFTSIDE,     0, JSEXN_SYNTAXERR, "invalid array comprehension left-hand side")
 MSG_DEF(JSMSG_ARRAY_INIT_TOO_BIG,      0, JSEXN_INTERNALERR, "array initializer too large")
 MSG_DEF(JSMSG_AS_AFTER_IMPORT_STAR,    0, JSEXN_SYNTAXERR, "missing keyword 'as' after import *")
 MSG_DEF(JSMSG_AS_AFTER_RESERVED_WORD,  1, JSEXN_SYNTAXERR, "missing keyword 'as' after reserved word '{0}'")
 MSG_DEF(JSMSG_ASYNC_GENERATOR,         0, JSEXN_SYNTAXERR, "generator function or method can't be async")
+MSG_DEF(JSMSG_AWAIT_IN_DEFAULT,        0, JSEXN_SYNTAXERR, "await can't be used in default expression")
 MSG_DEF(JSMSG_BAD_ANON_GENERATOR_RETURN, 0, JSEXN_TYPEERR, "anonymous generator function returns a value")
 MSG_DEF(JSMSG_BAD_ARROW_ARGS,          0, JSEXN_SYNTAXERR, "invalid arrow-function arguments (parentheses around the arrow-function may help)")
 MSG_DEF(JSMSG_BAD_BINDING,             1, JSEXN_SYNTAXERR, "redefining {0} is deprecated")
 MSG_DEF(JSMSG_BAD_CONST_DECL,          0, JSEXN_SYNTAXERR, "missing = in const declaration")
 MSG_DEF(JSMSG_BAD_CONTINUE,            0, JSEXN_SYNTAXERR, "continue must be inside loop")
 MSG_DEF(JSMSG_BAD_DESTRUCT_ASS,        0, JSEXN_REFERENCEERR, "invalid destructuring assignment operator")
 MSG_DEF(JSMSG_BAD_DESTRUCT_TARGET,     0, JSEXN_SYNTAXERR, "invalid destructuring target")
 MSG_DEF(JSMSG_BAD_DESTRUCT_PARENS,     0, JSEXN_SYNTAXERR, "destructuring patterns in assignments can't be parenthesized")
@@ -258,16 +259,17 @@ MSG_DEF(JSMSG_GARBAGE_AFTER_INPUT,     2
 MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER,    0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal")
 MSG_DEF(JSMSG_ILLEGAL_CHARACTER,       0, JSEXN_SYNTAXERR, "illegal character")
 MSG_DEF(JSMSG_IMPORT_DECL_AT_TOP_LEVEL, 0, JSEXN_SYNTAXERR, "import declarations may only appear at top level of a module")
 MSG_DEF(JSMSG_INVALID_FOR_IN_DECL_WITH_INIT,0,JSEXN_SYNTAXERR,"for-in loop head declarations may not have initializers")
 MSG_DEF(JSMSG_LABEL_NOT_FOUND,         0, JSEXN_SYNTAXERR, "label not found")
 MSG_DEF(JSMSG_LET_COMP_BINDING,        0, JSEXN_SYNTAXERR, "'let' is not a valid name for a comprehension variable")
 MSG_DEF(JSMSG_LEXICAL_DECL_NOT_IN_BLOCK,   1, JSEXN_SYNTAXERR, "{0} declaration not directly within block")
 MSG_DEF(JSMSG_LEXICAL_DECL_LABEL,      1, JSEXN_SYNTAXERR, "{0} declarations cannot be labelled")
+MSG_DEF(JSMSG_LINE_BREAK_AFTER_AWAIT,  0, JSEXN_SYNTAXERR, "no line break is allowed after 'await'")
 MSG_DEF(JSMSG_GENERATOR_LABEL,         0, JSEXN_SYNTAXERR, "generator functions cannot be labelled")
 MSG_DEF(JSMSG_FUNCTION_LABEL,          0, JSEXN_SYNTAXERR, "functions cannot be labelled")
 MSG_DEF(JSMSG_SLOPPY_FUNCTION_LABEL,   0, JSEXN_SYNTAXERR, "functions can only be labelled inside blocks")
 MSG_DEF(JSMSG_LINE_BREAK_AFTER_THROW,  0, JSEXN_SYNTAXERR, "no line break is allowed between 'throw' and its expression")
 MSG_DEF(JSMSG_LINE_BREAK_BEFORE_ARROW, 0, JSEXN_SYNTAXERR, "no line break is allowed before '=>'")
 MSG_DEF(JSMSG_MALFORMED_ESCAPE,        1, JSEXN_SYNTAXERR, "malformed {0} character escape sequence")
 MSG_DEF(JSMSG_MISSING_BINARY_DIGITS,   0, JSEXN_SYNTAXERR, "missing binary digits after '0b'")
 MSG_DEF(JSMSG_MISSING_EXPONENT,        0, JSEXN_SYNTAXERR, "missing exponent")