summaryrefslogtreecommitdiffstats
path: root/js/src/frontend/Parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/frontend/Parser.cpp')
-rw-r--r--js/src/frontend/Parser.cpp22
1 files changed, 21 insertions, 1 deletions
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
index 7704cf65a..2d2f17fd1 100644
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -5972,6 +5972,7 @@ Parser<ParseHandler>::matchInOrOf(bool* isForInp, bool* isForOfp)
template <class ParseHandler>
bool
Parser<ParseHandler>::forHeadStart(YieldHandling yieldHandling,
+ IteratorKind iterKind,
ParseNodeKind* forHeadKind,
Node* forInitialPart,
Maybe<ParseContext::Scope>& forLoopLexicalScope,
@@ -6062,6 +6063,11 @@ Parser<ParseHandler>::forHeadStart(YieldHandling yieldHandling,
if (!matchInOrOf(&isForIn, &isForOf))
return false;
+ if (iterKind == IteratorKind::Async && !isForOf) {
+ error(JSMSG_FOR_AWAIT_NOT_OF);
+ return false;
+ }
+
// If we don't encounter 'in'/'of', we have a for(;;) loop. We've handled
// the init expression; the caller handles the rest. Allow the Operand
// modifier when regetting: Operand must be used to examine the ';' in
@@ -6135,6 +6141,7 @@ Parser<ParseHandler>::forStatement(YieldHandling yieldHandling)
ParseContext::Statement stmt(pc, StatementKind::ForLoop);
bool isForEach = false;
+ IteratorKind iterKind = IteratorKind::Sync;
unsigned iflags = 0;
if (allowsForEachIn()) {
@@ -6149,6 +6156,19 @@ Parser<ParseHandler>::forStatement(YieldHandling yieldHandling)
}
}
+#ifndef RELEASE_OR_BETA
+ if (pc->isAsync()) {
+ bool matched;
+ if (!tokenStream.matchToken(&matched, TOK_AWAIT))
+ return null();
+
+ if (matched) {
+ iflags |= JSITER_FORAWAITOF;
+ iterKind = IteratorKind::Async;
+ }
+ }
+#endif
+
MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_AFTER_FOR);
// PNK_FORHEAD, PNK_FORIN, or PNK_FOROF depending on the loop type.
@@ -6186,7 +6206,7 @@ Parser<ParseHandler>::forStatement(YieldHandling yieldHandling)
//
// In either case the subsequent token can be consistently accessed using
// TokenStream::None semantics.
- if (!forHeadStart(yieldHandling, &headKind, &startNode, forLoopLexicalScope,
+ if (!forHeadStart(yieldHandling, iterKind, &headKind, &startNode, forLoopLexicalScope,
&iteratedExpr))
{
return null();