--- 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")