tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Parser.cpp (416735B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 /*
      8 * JS parser.
      9 *
     10 * This is a recursive-descent parser for the JavaScript language specified by
     11 * "The ECMAScript Language Specification" (Standard ECMA-262).  It uses
     12 * lexical and semantic feedback to disambiguate non-LL(1) structures.  It
     13 * generates trees of nodes induced by the recursive parsing (not precise
     14 * syntax trees, see Parser.h).  After tree construction, it rewrites trees to
     15 * fold constants and evaluate compile-time expressions.
     16 *
     17 * This parser attempts no error recovery.
     18 */
     19 
     20 #include "frontend/Parser.h"
     21 
     22 #include "mozilla/ArrayUtils.h"
     23 #include "mozilla/Assertions.h"
     24 #include "mozilla/Casting.h"
     25 #include "mozilla/Range.h"
     26 #include "mozilla/Sprintf.h"
     27 #include "mozilla/Try.h"  // MOZ_TRY*
     28 #include "mozilla/Utf8.h"
     29 #include "mozilla/Variant.h"
     30 
     31 #include <memory>
     32 #include <new>
     33 #include <type_traits>
     34 
     35 #include "jsnum.h"
     36 #include "jstypes.h"
     37 
     38 #include "frontend/FoldConstants.h"
     39 #include "frontend/FunctionSyntaxKind.h"  // FunctionSyntaxKind
     40 #include "frontend/ModuleSharedContext.h"
     41 #include "frontend/ParseNode.h"
     42 #include "frontend/ParseNodeVerify.h"
     43 #include "frontend/Parser-macros.h"  // MOZ_TRY_VAR_OR_RETURN
     44 #include "frontend/ParserAtom.h"  // TaggedParserAtomIndex, ParserAtomsTable, ParserAtom
     45 #include "frontend/ScriptIndex.h"  // ScriptIndex
     46 #include "frontend/TokenStream.h"  // IsKeyword, ReservedWordTokenKind, ReservedWordToCharZ, DeprecatedContent, *TokenStream*, CharBuffer, TokenKindToDesc
     47 #include "irregexp/RegExpAPI.h"
     48 #include "js/ColumnNumber.h"  // JS::LimitedColumnNumberOneOrigin, JS::ColumnNumberOneOrigin
     49 #include "js/ErrorReport.h"           // JSErrorBase
     50 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
     51 #include "js/HashTable.h"
     52 #include "js/RegExpFlags.h"  // JS::RegExpFlags
     53 #include "js/Stack.h"        // JS::NativeStackLimit
     54 #include "util/DifferentialTesting.h"
     55 #include "util/StringBuilder.h"  // StringBuilder
     56 #include "vm/BytecodeUtil.h"
     57 #include "vm/FunctionFlags.h"          // js::FunctionFlags
     58 #include "vm/GeneratorAndAsyncKind.h"  // js::GeneratorKind, js::FunctionAsyncKind
     59 #include "vm/JSContext.h"
     60 #include "vm/JSScript.h"
     61 #include "vm/ModuleBuilder.h"  // js::ModuleBuilder
     62 #include "vm/Scope.h"          // GetScopeDataTrailingNames
     63 #include "wasm/AsmJS.h"
     64 
     65 #include "frontend/ParseContext-inl.h"
     66 #include "frontend/SharedContext-inl.h"
     67 
     68 using namespace js;
     69 
     70 using mozilla::AssertedCast;
     71 using mozilla::AsVariant;
     72 using mozilla::Maybe;
     73 using mozilla::Nothing;
     74 using mozilla::PointerRangeSize;
     75 using mozilla::Some;
     76 using mozilla::Utf8Unit;
     77 
     78 using JS::ReadOnlyCompileOptions;
     79 using JS::RegExpFlags;
     80 
     81 namespace js::frontend {
     82 
     83 using DeclaredNamePtr = ParseContext::Scope::DeclaredNamePtr;
     84 using AddDeclaredNamePtr = ParseContext::Scope::AddDeclaredNamePtr;
     85 using BindingIter = ParseContext::Scope::BindingIter;
     86 using UsedNamePtr = UsedNameTracker::UsedNameMap::Ptr;
     87 
     88 using ParserBindingNameVector = Vector<ParserBindingName, 6>;
     89 
     90 static inline void PropagateTransitiveParseFlags(const FunctionBox* inner,
     91                                                 SharedContext* outer) {
     92  if (inner->bindingsAccessedDynamically()) {
     93    outer->setBindingsAccessedDynamically();
     94  }
     95  if (inner->hasDirectEval()) {
     96    outer->setHasDirectEval();
     97  }
     98 }
     99 
    100 static bool StatementKindIsBraced(StatementKind kind) {
    101  return kind == StatementKind::Block || kind == StatementKind::Switch ||
    102         kind == StatementKind::Try || kind == StatementKind::Catch ||
    103         kind == StatementKind::Finally;
    104 }
    105 
    106 template <class ParseHandler, typename Unit>
    107 inline typename GeneralParser<ParseHandler, Unit>::FinalParser*
    108 GeneralParser<ParseHandler, Unit>::asFinalParser() {
    109  static_assert(
    110      std::is_base_of_v<GeneralParser<ParseHandler, Unit>, FinalParser>,
    111      "inheritance relationship required by the static_cast<> below");
    112 
    113  return static_cast<FinalParser*>(this);
    114 }
    115 
    116 template <class ParseHandler, typename Unit>
    117 inline const typename GeneralParser<ParseHandler, Unit>::FinalParser*
    118 GeneralParser<ParseHandler, Unit>::asFinalParser() const {
    119  static_assert(
    120      std::is_base_of_v<GeneralParser<ParseHandler, Unit>, FinalParser>,
    121      "inheritance relationship required by the static_cast<> below");
    122 
    123  return static_cast<const FinalParser*>(this);
    124 }
    125 
    126 template <class ParseHandler, typename Unit>
    127 template <typename ConditionT, typename ErrorReportT>
    128 bool GeneralParser<ParseHandler, Unit>::mustMatchTokenInternal(
    129    ConditionT condition, ErrorReportT errorReport) {
    130  MOZ_ASSERT(condition(TokenKind::Div) == false);
    131  MOZ_ASSERT(condition(TokenKind::DivAssign) == false);
    132  MOZ_ASSERT(condition(TokenKind::RegExp) == false);
    133 
    134  TokenKind actual;
    135  if (!tokenStream.getToken(&actual, TokenStream::SlashIsInvalid)) {
    136    return false;
    137  }
    138  if (!condition(actual)) {
    139    errorReport(actual);
    140    return false;
    141  }
    142  return true;
    143 }
    144 
    145 ParserSharedBase::ParserSharedBase(FrontendContext* fc,
    146                                   CompilationState& compilationState,
    147                                   Kind kind)
    148    : fc_(fc),
    149      alloc_(compilationState.parserAllocScope.alloc()),
    150      compilationState_(compilationState),
    151      pc_(nullptr),
    152      usedNames_(compilationState.usedNames) {
    153  fc_->nameCollectionPool().addActiveCompilation();
    154 }
    155 
    156 ParserSharedBase::~ParserSharedBase() {
    157  fc_->nameCollectionPool().removeActiveCompilation();
    158 }
    159 
    160 #if defined(DEBUG) || defined(JS_JITSPEW)
    161 void ParserSharedBase::dumpAtom(TaggedParserAtomIndex index) const {
    162  parserAtoms().dump(index);
    163 }
    164 #endif
    165 
    166 ParserBase::ParserBase(FrontendContext* fc,
    167                       const ReadOnlyCompileOptions& options,
    168                       CompilationState& compilationState)
    169    : ParserSharedBase(fc, compilationState, ParserSharedBase::Kind::Parser),
    170      anyChars(fc, options, this),
    171      ss(nullptr),
    172 #ifdef DEBUG
    173      checkOptionsCalled_(false),
    174 #endif
    175      isUnexpectedEOF_(false),
    176      awaitHandling_(AwaitIsName),
    177      inParametersOfAsyncFunction_(false) {
    178 }
    179 
    180 bool ParserBase::checkOptions() {
    181 #ifdef DEBUG
    182  checkOptionsCalled_ = true;
    183 #endif
    184 
    185  return anyChars.checkOptions();
    186 }
    187 
    188 ParserBase::~ParserBase() { MOZ_ASSERT(checkOptionsCalled_); }
    189 
    190 JSAtom* ParserBase::liftParserAtomToJSAtom(TaggedParserAtomIndex index) {
    191  JSContext* cx = fc_->maybeCurrentJSContext();
    192  MOZ_ASSERT(cx);
    193  return parserAtoms().toJSAtom(cx, fc_, index,
    194                                compilationState_.input.atomCache);
    195 }
    196 
    197 template <class ParseHandler>
    198 PerHandlerParser<ParseHandler>::PerHandlerParser(
    199    FrontendContext* fc, const ReadOnlyCompileOptions& options,
    200    CompilationState& compilationState, void* internalSyntaxParser)
    201    : ParserBase(fc, options, compilationState),
    202      handler_(fc, compilationState),
    203      internalSyntaxParser_(internalSyntaxParser) {
    204  MOZ_ASSERT(compilationState.isInitialStencil() ==
    205             compilationState.input.isInitialStencil());
    206 }
    207 
    208 template <class ParseHandler, typename Unit>
    209 GeneralParser<ParseHandler, Unit>::GeneralParser(
    210    FrontendContext* fc, const ReadOnlyCompileOptions& options,
    211    const Unit* units, size_t length, CompilationState& compilationState,
    212    SyntaxParser* syntaxParser)
    213    : Base(fc, options, compilationState, syntaxParser),
    214      tokenStream(fc, &compilationState.parserAtoms, options, units, length) {}
    215 
    216 template <typename Unit>
    217 void Parser<SyntaxParseHandler, Unit>::setAwaitHandling(
    218    AwaitHandling awaitHandling) {
    219  this->awaitHandling_ = awaitHandling;
    220 }
    221 
    222 template <typename Unit>
    223 void Parser<FullParseHandler, Unit>::setAwaitHandling(
    224    AwaitHandling awaitHandling) {
    225  this->awaitHandling_ = awaitHandling;
    226  if (SyntaxParser* syntaxParser = getSyntaxParser()) {
    227    syntaxParser->setAwaitHandling(awaitHandling);
    228  }
    229 }
    230 
    231 template <class ParseHandler, typename Unit>
    232 inline void GeneralParser<ParseHandler, Unit>::setAwaitHandling(
    233    AwaitHandling awaitHandling) {
    234  asFinalParser()->setAwaitHandling(awaitHandling);
    235 }
    236 
    237 template <typename Unit>
    238 void Parser<SyntaxParseHandler, Unit>::setInParametersOfAsyncFunction(
    239    bool inParameters) {
    240  this->inParametersOfAsyncFunction_ = inParameters;
    241 }
    242 
    243 template <typename Unit>
    244 void Parser<FullParseHandler, Unit>::setInParametersOfAsyncFunction(
    245    bool inParameters) {
    246  this->inParametersOfAsyncFunction_ = inParameters;
    247  if (SyntaxParser* syntaxParser = getSyntaxParser()) {
    248    syntaxParser->setInParametersOfAsyncFunction(inParameters);
    249  }
    250 }
    251 
    252 template <class ParseHandler, typename Unit>
    253 inline void GeneralParser<ParseHandler, Unit>::setInParametersOfAsyncFunction(
    254    bool inParameters) {
    255  asFinalParser()->setInParametersOfAsyncFunction(inParameters);
    256 }
    257 
    258 template <class ParseHandler>
    259 FunctionBox* PerHandlerParser<ParseHandler>::newFunctionBox(
    260    FunctionNodeType funNode, TaggedParserAtomIndex explicitName,
    261    FunctionFlags flags, uint32_t toStringStart, Directives inheritedDirectives,
    262    GeneratorKind generatorKind, FunctionAsyncKind asyncKind) {
    263  MOZ_ASSERT(funNode);
    264 
    265  ScriptIndex index = ScriptIndex(compilationState_.scriptData.length());
    266  if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
    267    ReportAllocationOverflow(fc_);
    268    return nullptr;
    269  }
    270  if (!compilationState_.appendScriptStencilAndData(fc_)) {
    271    return nullptr;
    272  }
    273 
    274  bool isInitialStencil = compilationState_.isInitialStencil();
    275 
    276  // This source extent will be further filled in during the remainder of parse.
    277  SourceExtent extent;
    278  extent.toStringStart = toStringStart;
    279 
    280  FunctionBox* funbox = alloc_.new_<FunctionBox>(
    281      fc_, extent, compilationState_, inheritedDirectives, generatorKind,
    282      asyncKind, isInitialStencil, explicitName, flags, index);
    283  if (!funbox) {
    284    ReportOutOfMemory(fc_);
    285    return nullptr;
    286  }
    287 
    288  handler_.setFunctionBox(funNode, funbox);
    289 
    290  return funbox;
    291 }
    292 
    293 template <class ParseHandler>
    294 FunctionBox* PerHandlerParser<ParseHandler>::newFunctionBox(
    295    FunctionNodeType funNode, const ScriptStencil& cachedScriptData,
    296    const ScriptStencilExtra& cachedScriptExtra) {
    297  MOZ_ASSERT(funNode);
    298 
    299  ScriptIndex index = ScriptIndex(compilationState_.scriptData.length());
    300  if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
    301    ReportAllocationOverflow(fc_);
    302    return nullptr;
    303  }
    304  if (!compilationState_.appendScriptStencilAndData(fc_)) {
    305    return nullptr;
    306  }
    307 
    308  FunctionBox* funbox = alloc_.new_<FunctionBox>(
    309      fc_, cachedScriptExtra.extent, compilationState_,
    310      Directives(/* strict = */ false), cachedScriptExtra.generatorKind(),
    311      cachedScriptExtra.asyncKind(), compilationState_.isInitialStencil(),
    312      cachedScriptData.functionAtom, cachedScriptData.functionFlags, index);
    313  if (!funbox) {
    314    ReportOutOfMemory(fc_);
    315    return nullptr;
    316  }
    317 
    318  handler_.setFunctionBox(funNode, funbox);
    319  funbox->initFromScriptStencilExtra(cachedScriptExtra);
    320 
    321  return funbox;
    322 }
    323 
    324 bool ParserBase::setSourceMapInfo() {
    325  // If support for source pragmas have been fully disabled, we can skip
    326  // processing of all of these values.
    327  if (!options().sourcePragmas()) {
    328    return true;
    329  }
    330 
    331  // Not all clients initialize ss. Can't update info to an object that isn't
    332  // there.
    333  if (!ss) {
    334    return true;
    335  }
    336 
    337  if (anyChars.hasDisplayURL()) {
    338    if (!ss->setDisplayURL(fc_, anyChars.displayURL())) {
    339      return false;
    340    }
    341  }
    342 
    343  if (anyChars.hasSourceMapURL()) {
    344    MOZ_ASSERT(!ss->hasSourceMapURL());
    345    if (!ss->setSourceMapURL(fc_, anyChars.sourceMapURL())) {
    346      return false;
    347    }
    348  }
    349 
    350  /*
    351   * Source map URLs passed as a compile option (usually via a HTTP source map
    352   * header) override any source map urls passed as comment pragmas.
    353   */
    354  if (options().sourceMapURL()) {
    355    // Warn about the replacement, but use the new one.
    356    if (ss->hasSourceMapURL()) {
    357      if (!warningNoOffset(JSMSG_ALREADY_HAS_PRAGMA, ss->filename(),
    358                           "//# sourceMappingURL")) {
    359        return false;
    360      }
    361    }
    362 
    363    if (!ss->setSourceMapURL(fc_, options().sourceMapURL())) {
    364      return false;
    365    }
    366  }
    367 
    368  return true;
    369 }
    370 
    371 /*
    372 * Parse a top-level JS script.
    373 */
    374 template <class ParseHandler, typename Unit>
    375 typename ParseHandler::ListNodeResult
    376 GeneralParser<ParseHandler, Unit>::parse() {
    377  MOZ_ASSERT(checkOptionsCalled_);
    378 
    379  SourceExtent extent = SourceExtent::makeGlobalExtent(
    380      /* len = */ 0, options().lineno,
    381      JS::LimitedColumnNumberOneOrigin::fromUnlimited(
    382          JS::ColumnNumberOneOrigin(options().column)));
    383  Directives directives(options().forceStrictMode());
    384  GlobalSharedContext globalsc(this->fc_, ScopeKind::Global, options(),
    385                               directives, extent);
    386  SourceParseContext globalpc(this, &globalsc, /* newDirectives = */ nullptr);
    387  if (!globalpc.init()) {
    388    return errorResult();
    389  }
    390 
    391  ParseContext::VarScope varScope(this);
    392  if (!varScope.init(pc_)) {
    393    return errorResult();
    394  }
    395 
    396  ListNodeType stmtList = MOZ_TRY(statementList(YieldIsName));
    397 
    398  TokenKind tt;
    399  if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
    400    return errorResult();
    401  }
    402  if (tt != TokenKind::Eof) {
    403    error(JSMSG_GARBAGE_AFTER_INPUT, "script", TokenKindToDesc(tt));
    404    return errorResult();
    405  }
    406 
    407  if (!CheckParseTree(this->fc_, alloc_, stmtList)) {
    408    return errorResult();
    409  }
    410 
    411  return stmtList;
    412 }
    413 
    414 /*
    415 * Strict mode forbids introducing new definitions for 'eval', 'arguments',
    416 * 'let', 'static', 'yield', or for any strict mode reserved word.
    417 */
    418 bool ParserBase::isValidStrictBinding(TaggedParserAtomIndex name) {
    419  TokenKind tt = ReservedWordTokenKind(name);
    420  if (tt == TokenKind::Limit) {
    421    return name != TaggedParserAtomIndex::WellKnown::eval() &&
    422           name != TaggedParserAtomIndex::WellKnown::arguments();
    423  }
    424  return tt != TokenKind::Let && tt != TokenKind::Static &&
    425         tt != TokenKind::Yield && !TokenKindIsStrictReservedWord(tt);
    426 }
    427 
    428 /*
    429 * Returns true if all parameter names are valid strict mode binding names and
    430 * no duplicate parameter names are present.
    431 */
    432 bool ParserBase::hasValidSimpleStrictParameterNames() {
    433  MOZ_ASSERT(pc_->isFunctionBox() &&
    434             pc_->functionBox()->hasSimpleParameterList());
    435 
    436  if (pc_->functionBox()->hasDuplicateParameters) {
    437    return false;
    438  }
    439 
    440  for (auto name : pc_->positionalFormalParameterNames()) {
    441    MOZ_ASSERT(name);
    442    if (!isValidStrictBinding(name)) {
    443      return false;
    444    }
    445  }
    446  return true;
    447 }
    448 
    449 template <class ParseHandler, typename Unit>
    450 void GeneralParser<ParseHandler, Unit>::reportMissingClosing(
    451    unsigned errorNumber, unsigned noteNumber, uint32_t openedPos) {
    452  auto notes = MakeUnique<JSErrorNotes>();
    453  if (!notes) {
    454    ReportOutOfMemory(this->fc_);
    455    return;
    456  }
    457 
    458  uint32_t line;
    459  JS::LimitedColumnNumberOneOrigin column;
    460  tokenStream.computeLineAndColumn(openedPos, &line, &column);
    461 
    462  const size_t MaxWidth = sizeof("4294967295");
    463  char columnNumber[MaxWidth];
    464  SprintfLiteral(columnNumber, "%" PRIu32, column.oneOriginValue());
    465  char lineNumber[MaxWidth];
    466  SprintfLiteral(lineNumber, "%" PRIu32, line);
    467 
    468  if (!notes->addNoteASCII(this->fc_, getFilename().c_str(), 0, line,
    469                           JS::ColumnNumberOneOrigin(column), GetErrorMessage,
    470                           nullptr, noteNumber, lineNumber, columnNumber)) {
    471    return;
    472  }
    473 
    474  errorWithNotes(std::move(notes), errorNumber);
    475 }
    476 
    477 template <class ParseHandler, typename Unit>
    478 void GeneralParser<ParseHandler, Unit>::reportRedeclarationHelper(
    479    TaggedParserAtomIndex& name, DeclarationKind& prevKind, TokenPos& pos,
    480    uint32_t& prevPos, const unsigned& errorNumber,
    481    const unsigned& noteErrorNumber) {
    482  UniqueChars bytes = this->parserAtoms().toPrintableString(name);
    483  if (!bytes) {
    484    ReportOutOfMemory(this->fc_);
    485    return;
    486  }
    487 
    488  if (prevPos == DeclaredNameInfo::npos) {
    489    errorAt(pos.begin, errorNumber, DeclarationKindString(prevKind),
    490            bytes.get());
    491    return;
    492  }
    493 
    494  auto notes = MakeUnique<JSErrorNotes>();
    495  if (!notes) {
    496    ReportOutOfMemory(this->fc_);
    497    return;
    498  }
    499 
    500  uint32_t line;
    501  JS::LimitedColumnNumberOneOrigin column;
    502  tokenStream.computeLineAndColumn(prevPos, &line, &column);
    503 
    504  const size_t MaxWidth = sizeof("4294967295");
    505  char columnNumber[MaxWidth];
    506  SprintfLiteral(columnNumber, "%" PRIu32, column.oneOriginValue());
    507  char lineNumber[MaxWidth];
    508  SprintfLiteral(lineNumber, "%" PRIu32, line);
    509 
    510  if (!notes->addNoteASCII(this->fc_, getFilename().c_str(), 0, line,
    511                           JS::ColumnNumberOneOrigin(column), GetErrorMessage,
    512                           nullptr, noteErrorNumber, lineNumber,
    513                           columnNumber)) {
    514    return;
    515  }
    516 
    517  errorWithNotesAt(std::move(notes), pos.begin, errorNumber,
    518                   DeclarationKindString(prevKind), bytes.get());
    519 }
    520 
    521 template <class ParseHandler, typename Unit>
    522 void GeneralParser<ParseHandler, Unit>::reportRedeclaration(
    523    TaggedParserAtomIndex name, DeclarationKind prevKind, TokenPos pos,
    524    uint32_t prevPos) {
    525  reportRedeclarationHelper(name, prevKind, pos, prevPos, JSMSG_REDECLARED_VAR,
    526                            JSMSG_PREV_DECLARATION);
    527 }
    528 
    529 template <class ParseHandler, typename Unit>
    530 void GeneralParser<ParseHandler, Unit>::reportMismatchedPlacement(
    531    TaggedParserAtomIndex name, DeclarationKind prevKind, TokenPos pos,
    532    uint32_t prevPos) {
    533  reportRedeclarationHelper(name, prevKind, pos, prevPos,
    534                            JSMSG_MISMATCHED_PLACEMENT, JSMSG_PREV_DECLARATION);
    535 }
    536 
    537 // notePositionalFormalParameter is called for both the arguments of a regular
    538 // function definition and the arguments specified by the Function
    539 // constructor.
    540 //
    541 // The 'disallowDuplicateParams' bool indicates whether the use of another
    542 // feature (destructuring or default arguments) disables duplicate arguments.
    543 // (ECMA-262 requires us to support duplicate parameter names, but, for newer
    544 // features, we consider the code to have "opted in" to higher standards and
    545 // forbid duplicates.)
    546 template <class ParseHandler, typename Unit>
    547 bool GeneralParser<ParseHandler, Unit>::notePositionalFormalParameter(
    548    FunctionNodeType funNode, TaggedParserAtomIndex name, uint32_t beginPos,
    549    bool disallowDuplicateParams, bool* duplicatedParam) {
    550  if (AddDeclaredNamePtr p =
    551          pc_->functionScope().lookupDeclaredNameForAdd(name)) {
    552    if (disallowDuplicateParams) {
    553      error(JSMSG_BAD_DUP_ARGS);
    554      return false;
    555    }
    556 
    557    // Strict-mode disallows duplicate args. We may not know whether we are
    558    // in strict mode or not (since the function body hasn't been parsed).
    559    // In such cases, report will queue up the potential error and return
    560    // 'true'.
    561    if (pc_->sc()->strict()) {
    562      UniqueChars bytes = this->parserAtoms().toPrintableString(name);
    563      if (!bytes) {
    564        ReportOutOfMemory(this->fc_);
    565        return false;
    566      }
    567      if (!strictModeError(JSMSG_DUPLICATE_FORMAL, bytes.get())) {
    568        return false;
    569      }
    570    }
    571 
    572    *duplicatedParam = true;
    573  } else {
    574    DeclarationKind kind = DeclarationKind::PositionalFormalParameter;
    575    if (!pc_->functionScope().addDeclaredName(pc_, p, name, kind, beginPos)) {
    576      return false;
    577    }
    578  }
    579 
    580  if (!pc_->positionalFormalParameterNames().append(
    581          TrivialTaggedParserAtomIndex::from(name))) {
    582    ReportOutOfMemory(this->fc_);
    583    return false;
    584  }
    585 
    586  NameNodeType paramNode;
    587  MOZ_TRY_VAR_OR_RETURN(paramNode, newName(name), false);
    588 
    589  handler_.addFunctionFormalParameter(funNode, paramNode);
    590  return true;
    591 }
    592 
    593 template <class ParseHandler>
    594 bool PerHandlerParser<ParseHandler>::noteDestructuredPositionalFormalParameter(
    595    FunctionNodeType funNode, Node destruct) {
    596  // Append an empty name to the positional formals vector to keep track of
    597  // argument slots when making FunctionScope::ParserData.
    598  if (!pc_->positionalFormalParameterNames().append(
    599          TrivialTaggedParserAtomIndex::null())) {
    600    ReportOutOfMemory(fc_);
    601    return false;
    602  }
    603 
    604  handler_.addFunctionFormalParameter(funNode, destruct);
    605  return true;
    606 }
    607 
    608 template <class ParseHandler, typename Unit>
    609 bool GeneralParser<ParseHandler, Unit>::noteDeclaredName(
    610    TaggedParserAtomIndex name, DeclarationKind kind, TokenPos pos,
    611    ClosedOver isClosedOver) {
    612  // The asm.js validator does all its own symbol-table management so, as an
    613  // optimization, avoid doing any work here.
    614  if (pc_->useAsmOrInsideUseAsm()) {
    615    return true;
    616  }
    617 
    618  switch (kind) {
    619    case DeclarationKind::Var:
    620    case DeclarationKind::BodyLevelFunction: {
    621      Maybe<DeclarationKind> redeclaredKind;
    622      uint32_t prevPos;
    623      if (!pc_->tryDeclareVar(name, this, kind, pos.begin, &redeclaredKind,
    624                              &prevPos)) {
    625        return false;
    626      }
    627 
    628      if (redeclaredKind) {
    629        reportRedeclaration(name, *redeclaredKind, pos, prevPos);
    630        return false;
    631      }
    632 
    633      break;
    634    }
    635 
    636    case DeclarationKind::ModuleBodyLevelFunction: {
    637      MOZ_ASSERT(pc_->atModuleLevel());
    638 
    639      AddDeclaredNamePtr p = pc_->varScope().lookupDeclaredNameForAdd(name);
    640      if (p) {
    641        reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
    642        return false;
    643      }
    644 
    645      if (!pc_->varScope().addDeclaredName(pc_, p, name, kind, pos.begin,
    646                                           isClosedOver)) {
    647        return false;
    648      }
    649 
    650      // Body-level functions in modules are always closed over.
    651      pc_->varScope().lookupDeclaredName(name)->value()->setClosedOver();
    652 
    653      break;
    654    }
    655 
    656    case DeclarationKind::FormalParameter: {
    657      // It is an early error if any non-positional formal parameter name
    658      // (e.g., destructuring formal parameter) is duplicated.
    659 
    660      AddDeclaredNamePtr p =
    661          pc_->functionScope().lookupDeclaredNameForAdd(name);
    662      if (p) {
    663        error(JSMSG_BAD_DUP_ARGS);
    664        return false;
    665      }
    666 
    667      if (!pc_->functionScope().addDeclaredName(pc_, p, name, kind, pos.begin,
    668                                                isClosedOver)) {
    669        return false;
    670      }
    671 
    672      break;
    673    }
    674 
    675    case DeclarationKind::LexicalFunction:
    676    case DeclarationKind::PrivateName:
    677    case DeclarationKind::Synthetic:
    678    case DeclarationKind::PrivateMethod: {
    679      ParseContext::Scope* scope = pc_->innermostScope();
    680      AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
    681      if (p) {
    682        reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
    683        return false;
    684      }
    685 
    686      if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
    687                                  isClosedOver)) {
    688        return false;
    689      }
    690 
    691      break;
    692    }
    693 
    694    case DeclarationKind::SloppyLexicalFunction: {
    695      // Functions in block have complex allowances in sloppy mode for being
    696      // labelled that other lexical declarations do not have. Those checks
    697      // are done in functionStmt.
    698 
    699      ParseContext::Scope* scope = pc_->innermostScope();
    700      if (AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name)) {
    701        // It is usually an early error if there is another declaration
    702        // with the same name in the same scope.
    703        //
    704        // Sloppy lexical functions may redeclare other sloppy lexical
    705        // functions for web compatibility reasons.
    706        if (p->value()->kind() != DeclarationKind::SloppyLexicalFunction) {
    707          reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
    708          return false;
    709        }
    710      } else {
    711        if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
    712                                    isClosedOver)) {
    713          return false;
    714        }
    715      }
    716 
    717      break;
    718    }
    719 
    720    case DeclarationKind::Let:
    721    case DeclarationKind::Const:
    722 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
    723    case DeclarationKind::Using:
    724    case DeclarationKind::AwaitUsing:
    725 #endif
    726    case DeclarationKind::Class:
    727      // The BoundNames of LexicalDeclaration and ForDeclaration must not
    728      // contain 'let'. (CatchParameter is the only lexical binding form
    729      // without this restriction.)
    730      if (name == TaggedParserAtomIndex::WellKnown::let()) {
    731        errorAt(pos.begin, JSMSG_LEXICAL_DECL_DEFINES_LET);
    732        return false;
    733      }
    734 
    735      // For body-level lexically declared names in a function, it is an
    736      // early error if there is a formal parameter of the same name. This
    737      // needs a special check if there is an extra var scope due to
    738      // parameter expressions.
    739      if (pc_->isFunctionExtraBodyVarScopeInnermost()) {
    740        DeclaredNamePtr p = pc_->functionScope().lookupDeclaredName(name);
    741        if (p && DeclarationKindIsParameter(p->value()->kind())) {
    742          reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
    743          return false;
    744        }
    745      }
    746 
    747      [[fallthrough]];
    748 
    749    case DeclarationKind::Import:
    750      // Module code is always strict, so 'let' is always a keyword and never a
    751      // name.
    752      MOZ_ASSERT(name != TaggedParserAtomIndex::WellKnown::let());
    753      [[fallthrough]];
    754 
    755    case DeclarationKind::SimpleCatchParameter:
    756    case DeclarationKind::CatchParameter: {
    757      ParseContext::Scope* scope = pc_->innermostScope();
    758 
    759      // It is an early error if there is another declaration with the same
    760      // name in the same scope.
    761      AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
    762      if (p) {
    763        reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
    764        return false;
    765      }
    766 
    767      if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
    768                                  isClosedOver)) {
    769        return false;
    770      }
    771 
    772      break;
    773    }
    774 
    775    case DeclarationKind::CoverArrowParameter:
    776      // CoverArrowParameter is only used as a placeholder declaration kind.
    777      break;
    778 
    779    case DeclarationKind::PositionalFormalParameter:
    780      MOZ_CRASH(
    781          "Positional formal parameter names should use "
    782          "notePositionalFormalParameter");
    783      break;
    784 
    785    case DeclarationKind::VarForAnnexBLexicalFunction:
    786      MOZ_CRASH(
    787          "Synthesized Annex B vars should go through "
    788          "addPossibleAnnexBFunctionBox, and "
    789          "propagateAndMarkAnnexBFunctionBoxes");
    790      break;
    791  }
    792 
    793  return true;
    794 }
    795 
    796 template <class ParseHandler, typename Unit>
    797 bool GeneralParser<ParseHandler, Unit>::noteDeclaredPrivateName(
    798    Node nameNode, TaggedParserAtomIndex name, PropertyType propType,
    799    FieldPlacement placement, TokenPos pos) {
    800  ParseContext::Scope* scope = pc_->innermostScope();
    801  AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
    802 
    803  DeclarationKind declKind = DeclarationKind::PrivateName;
    804 
    805  // Our strategy for enabling debugger functionality is to mark names as closed
    806  // over, even if they don't necessarily need to be, to ensure that they are
    807  // included in the environment object. This allows us to easily look them up
    808  // by name when needed, even if there is no corresponding property on an
    809  // object, as is the case with getter, setters and private methods.
    810  ClosedOver closedOver = ClosedOver::Yes;
    811  PrivateNameKind kind;
    812  switch (propType) {
    813    case PropertyType::Field:
    814      kind = PrivateNameKind::Field;
    815      closedOver = ClosedOver::No;
    816      break;
    817    case PropertyType::FieldWithAccessor:
    818      // In this case, we create a new private field for the underlying storage,
    819      // and use the current name for the getter and setter.
    820      kind = PrivateNameKind::GetterSetter;
    821      break;
    822    case PropertyType::Method:
    823    case PropertyType::GeneratorMethod:
    824    case PropertyType::AsyncMethod:
    825    case PropertyType::AsyncGeneratorMethod:
    826      if (placement == FieldPlacement::Instance) {
    827        // Optimized private method. Non-optimized paths still get
    828        // DeclarationKind::Synthetic.
    829        declKind = DeclarationKind::PrivateMethod;
    830      }
    831      kind = PrivateNameKind::Method;
    832      break;
    833    case PropertyType::Getter:
    834      kind = PrivateNameKind::Getter;
    835      break;
    836    case PropertyType::Setter:
    837      kind = PrivateNameKind::Setter;
    838      break;
    839    default:
    840      MOZ_CRASH("Invalid Property Type for noteDeclarePrivateName");
    841  }
    842 
    843  if (p) {
    844    PrivateNameKind prevKind = p->value()->privateNameKind();
    845    if ((prevKind == PrivateNameKind::Getter &&
    846         kind == PrivateNameKind::Setter) ||
    847        (prevKind == PrivateNameKind::Setter &&
    848         kind == PrivateNameKind::Getter)) {
    849      // Private methods demands that
    850      //
    851      // class A {
    852      //   static set #x(_) {}
    853      //   get #x() { }
    854      // }
    855      //
    856      // Report a SyntaxError.
    857      if (placement == p->value()->placement()) {
    858        p->value()->setPrivateNameKind(PrivateNameKind::GetterSetter);
    859        handler_.setPrivateNameKind(nameNode, PrivateNameKind::GetterSetter);
    860        return true;
    861      }
    862    }
    863 
    864    reportMismatchedPlacement(name, p->value()->kind(), pos, p->value()->pos());
    865    return false;
    866  }
    867 
    868  if (!scope->addDeclaredName(pc_, p, name, declKind, pos.begin, closedOver)) {
    869    return false;
    870  }
    871 
    872  DeclaredNamePtr declared = scope->lookupDeclaredName(name);
    873  declared->value()->setPrivateNameKind(kind);
    874  declared->value()->setFieldPlacement(placement);
    875  handler_.setPrivateNameKind(nameNode, kind);
    876 
    877  return true;
    878 }
    879 
    880 bool ParserBase::noteUsedNameInternal(TaggedParserAtomIndex name,
    881                                      NameVisibility visibility,
    882                                      mozilla::Maybe<TokenPos> tokenPosition) {
    883  // The asm.js validator does all its own symbol-table management so, as an
    884  // optimization, avoid doing any work here.
    885  if (pc_->useAsmOrInsideUseAsm()) {
    886    return true;
    887  }
    888 
    889  // Global bindings are properties and not actual bindings; we don't need
    890  // to know if they are closed over. So no need to track used name at the
    891  // global scope. It is not incorrect to track them, this is an
    892  // optimization.
    893  //
    894  // Exceptions:
    895  //   (a) Track private name references, as the used names tracker is used to
    896  //       provide early errors for undeclared private name references
    897  //   (b) If the script has extra bindings, track all references to detect
    898  //       references to extra bindings
    899  ParseContext::Scope* scope = pc_->innermostScope();
    900  if (pc_->sc()->isGlobalContext() && scope == &pc_->varScope() &&
    901      visibility == NameVisibility::Public &&
    902      !this->compilationState_.input.hasExtraBindings()) {
    903    return true;
    904  }
    905 
    906  return usedNames_.noteUse(fc_, name, visibility, pc_->scriptId(), scope->id(),
    907                            tokenPosition);
    908 }
    909 
    910 template <class ParseHandler>
    911 bool PerHandlerParser<ParseHandler>::
    912    propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope) {
    913  // Now that we have all the declared names in the scope, check which
    914  // functions should exhibit Annex B semantics.
    915  if (!scope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
    916    return false;
    917  }
    918 
    919  if (handler_.reuseClosedOverBindings()) {
    920    MOZ_ASSERT(pc_->isOutermostOfCurrentCompile());
    921 
    922    // Closed over bindings for all scopes are stored in a contiguous array, in
    923    // the same order as the order in which scopes are visited, and seprated by
    924    // TaggedParserAtomIndex::null().
    925    uint32_t slotCount = scope.declaredCount();
    926    while (auto parserAtom = handler_.nextLazyClosedOverBinding()) {
    927      scope.lookupDeclaredName(parserAtom)->value()->setClosedOver();
    928      MOZ_ASSERT(slotCount > 0);
    929      slotCount--;
    930    }
    931 
    932    if (pc_->isGeneratorOrAsync()) {
    933      scope.setOwnStackSlotCount(slotCount);
    934    }
    935    return true;
    936  }
    937 
    938  constexpr bool isSyntaxParser =
    939      std::is_same_v<ParseHandler, SyntaxParseHandler>;
    940  uint32_t scriptId = pc_->scriptId();
    941  uint32_t scopeId = scope.id();
    942 
    943  uint32_t slotCount = 0;
    944  for (BindingIter bi = scope.bindings(pc_); bi; bi++) {
    945    bool closedOver = false;
    946    if (UsedNamePtr p = usedNames_.lookup(bi.name())) {
    947      p->value().noteBoundInScope(scriptId, scopeId, &closedOver);
    948      if (closedOver) {
    949        bi.setClosedOver();
    950 
    951        if constexpr (isSyntaxParser) {
    952          if (!pc_->closedOverBindingsForLazy().append(
    953                  TrivialTaggedParserAtomIndex::from(bi.name()))) {
    954            ReportOutOfMemory(fc_);
    955            return false;
    956          }
    957        }
    958      }
    959    }
    960 
    961    if constexpr (!isSyntaxParser) {
    962      if (!closedOver) {
    963        slotCount++;
    964      }
    965    }
    966  }
    967  if constexpr (!isSyntaxParser) {
    968    if (pc_->isGeneratorOrAsync()) {
    969      scope.setOwnStackSlotCount(slotCount);
    970    }
    971  }
    972 
    973  // Append a nullptr to denote end-of-scope.
    974  if constexpr (isSyntaxParser) {
    975    if (!pc_->closedOverBindingsForLazy().append(
    976            TrivialTaggedParserAtomIndex::null())) {
    977      ReportOutOfMemory(fc_);
    978      return false;
    979    }
    980  }
    981 
    982  return true;
    983 }
    984 
    985 template <typename Unit>
    986 bool Parser<FullParseHandler, Unit>::checkStatementsEOF() {
    987  // This is designed to be paired with parsing a statement list at the top
    988  // level.
    989  //
    990  // The statementList() call breaks on TokenKind::RightCurly, so make sure
    991  // we've reached EOF here.
    992  TokenKind tt;
    993  if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
    994    return false;
    995  }
    996  if (tt != TokenKind::Eof) {
    997    error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
    998    return false;
    999  }
   1000  return true;
   1001 }
   1002 
   1003 template <typename ScopeT>
   1004 typename ScopeT::ParserData* NewEmptyBindingData(FrontendContext* fc,
   1005                                                 LifoAlloc& alloc,
   1006                                                 uint32_t numBindings) {
   1007  using Data = typename ScopeT::ParserData;
   1008  size_t allocSize = SizeOfScopeData<Data>(numBindings);
   1009  auto* bindings = alloc.newWithSize<Data>(allocSize, numBindings);
   1010  if (!bindings) {
   1011    ReportOutOfMemory(fc);
   1012  }
   1013  return bindings;
   1014 }
   1015 
   1016 GlobalScope::ParserData* NewEmptyGlobalScopeData(FrontendContext* fc,
   1017                                                 LifoAlloc& alloc,
   1018                                                 uint32_t numBindings) {
   1019  return NewEmptyBindingData<GlobalScope>(fc, alloc, numBindings);
   1020 }
   1021 
   1022 LexicalScope::ParserData* NewEmptyLexicalScopeData(FrontendContext* fc,
   1023                                                   LifoAlloc& alloc,
   1024                                                   uint32_t numBindings) {
   1025  return NewEmptyBindingData<LexicalScope>(fc, alloc, numBindings);
   1026 }
   1027 
   1028 FunctionScope::ParserData* NewEmptyFunctionScopeData(FrontendContext* fc,
   1029                                                     LifoAlloc& alloc,
   1030                                                     uint32_t numBindings) {
   1031  return NewEmptyBindingData<FunctionScope>(fc, alloc, numBindings);
   1032 }
   1033 
   1034 namespace detail {
   1035 
   1036 template <class SlotInfo>
   1037 static MOZ_ALWAYS_INLINE ParserBindingName* InitializeIndexedBindings(
   1038    SlotInfo& slotInfo, ParserBindingName* start, ParserBindingName* cursor) {
   1039  return cursor;
   1040 }
   1041 
   1042 template <class SlotInfo, typename UnsignedInteger, typename... Step>
   1043 static MOZ_ALWAYS_INLINE ParserBindingName* InitializeIndexedBindings(
   1044    SlotInfo& slotInfo, ParserBindingName* start, ParserBindingName* cursor,
   1045    UnsignedInteger SlotInfo::* field, const ParserBindingNameVector& bindings,
   1046    Step&&... step) {
   1047  slotInfo.*field =
   1048      AssertedCast<UnsignedInteger>(PointerRangeSize(start, cursor));
   1049 
   1050  ParserBindingName* newCursor =
   1051      std::uninitialized_copy(bindings.begin(), bindings.end(), cursor);
   1052 
   1053  return InitializeIndexedBindings(slotInfo, start, newCursor,
   1054                                   std::forward<Step>(step)...);
   1055 }
   1056 
   1057 }  // namespace detail
   1058 
   1059 // Initialize the trailing name bindings of |data|, then set |data->length| to
   1060 // the count of bindings added (which must equal |count|).
   1061 //
   1062 // First, |firstBindings| are added to the trailing names.  Then any
   1063 // "steps" present are performed first to last.  Each step is 1) a pointer to a
   1064 // member of |data| to be set to the current number of bindings added, and 2) a
   1065 // vector of |ParserBindingName|s to then copy into |data->trailingNames|.
   1066 // (Thus each |data| member field indicates where the corresponding vector's
   1067 //  names start.)
   1068 template <class Data, typename... Step>
   1069 static MOZ_ALWAYS_INLINE void InitializeBindingData(
   1070    Data* data, uint32_t count, const ParserBindingNameVector& firstBindings,
   1071    Step&&... step) {
   1072  MOZ_ASSERT(data->length == 0, "data shouldn't be filled yet");
   1073 
   1074  ParserBindingName* start = GetScopeDataTrailingNamesPointer(data);
   1075  ParserBindingName* cursor = std::uninitialized_copy(
   1076      firstBindings.begin(), firstBindings.end(), start);
   1077 
   1078 #ifdef DEBUG
   1079  ParserBindingName* end =
   1080 #endif
   1081      detail::InitializeIndexedBindings(data->slotInfo, start, cursor,
   1082                                        std::forward<Step>(step)...);
   1083 
   1084  MOZ_ASSERT(PointerRangeSize(start, end) == count);
   1085  data->length = count;
   1086 }
   1087 
   1088 static Maybe<GlobalScope::ParserData*> NewGlobalScopeData(
   1089    FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
   1090    ParseContext* pc) {
   1091  ParserBindingNameVector vars(fc);
   1092  ParserBindingNameVector lets(fc);
   1093  ParserBindingNameVector consts(fc);
   1094 
   1095  bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
   1096  for (BindingIter bi = scope.bindings(pc); bi; bi++) {
   1097    bool closedOver = allBindingsClosedOver || bi.closedOver();
   1098 
   1099    switch (bi.kind()) {
   1100      case BindingKind::Var: {
   1101        bool isTopLevelFunction =
   1102            bi.declarationKind() == DeclarationKind::BodyLevelFunction;
   1103 
   1104        ParserBindingName binding(bi.name(), closedOver, isTopLevelFunction);
   1105        if (!vars.append(binding)) {
   1106          return Nothing();
   1107        }
   1108        break;
   1109      }
   1110      case BindingKind::Let: {
   1111        ParserBindingName binding(bi.name(), closedOver);
   1112        if (!lets.append(binding)) {
   1113          return Nothing();
   1114        }
   1115        break;
   1116      }
   1117      case BindingKind::Const: {
   1118        ParserBindingName binding(bi.name(), closedOver);
   1119        if (!consts.append(binding)) {
   1120          return Nothing();
   1121        }
   1122        break;
   1123      }
   1124      default:
   1125        MOZ_CRASH("Bad global scope BindingKind");
   1126    }
   1127  }
   1128 
   1129  GlobalScope::ParserData* bindings = nullptr;
   1130  uint32_t numBindings = vars.length() + lets.length() + consts.length();
   1131 
   1132  if (numBindings > 0) {
   1133    bindings = NewEmptyBindingData<GlobalScope>(fc, alloc, numBindings);
   1134    if (!bindings) {
   1135      return Nothing();
   1136    }
   1137 
   1138    // The ordering here is important. See comments in GlobalScope.
   1139    InitializeBindingData(bindings, numBindings, vars,
   1140                          &ParserGlobalScopeSlotInfo::letStart, lets,
   1141                          &ParserGlobalScopeSlotInfo::constStart, consts);
   1142  }
   1143 
   1144  return Some(bindings);
   1145 }
   1146 
   1147 Maybe<GlobalScope::ParserData*> ParserBase::newGlobalScopeData(
   1148    ParseContext::Scope& scope) {
   1149  return NewGlobalScopeData(fc_, scope, stencilAlloc(), pc_);
   1150 }
   1151 
   1152 static Maybe<ModuleScope::ParserData*> NewModuleScopeData(
   1153    FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
   1154    ParseContext* pc) {
   1155  ParserBindingNameVector imports(fc);
   1156  ParserBindingNameVector vars(fc);
   1157  ParserBindingNameVector lets(fc);
   1158  ParserBindingNameVector consts(fc);
   1159 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1160  ParserBindingNameVector usings(fc);
   1161 #endif
   1162 
   1163  bool allBindingsClosedOver =
   1164      pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
   1165 
   1166  for (BindingIter bi = scope.bindings(pc); bi; bi++) {
   1167    // Imports are indirect bindings and must not be given known slots.
   1168    ParserBindingName binding(bi.name(),
   1169                              (allBindingsClosedOver || bi.closedOver()) &&
   1170                                  bi.kind() != BindingKind::Import);
   1171    switch (bi.kind()) {
   1172      case BindingKind::Import:
   1173        if (!imports.append(binding)) {
   1174          return Nothing();
   1175        }
   1176        break;
   1177      case BindingKind::Var:
   1178        if (!vars.append(binding)) {
   1179          return Nothing();
   1180        }
   1181        break;
   1182      case BindingKind::Let:
   1183        if (!lets.append(binding)) {
   1184          return Nothing();
   1185        }
   1186        break;
   1187      case BindingKind::Const:
   1188        if (!consts.append(binding)) {
   1189          return Nothing();
   1190        }
   1191        break;
   1192 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1193      case BindingKind::Using:
   1194        if (!usings.append(binding)) {
   1195          return Nothing();
   1196        }
   1197        break;
   1198 #endif
   1199      default:
   1200        MOZ_CRASH("Bad module scope BindingKind");
   1201    }
   1202  }
   1203 
   1204  ModuleScope::ParserData* bindings = nullptr;
   1205  uint32_t numBindings = imports.length() + vars.length() + lets.length() +
   1206                         consts.length()
   1207 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1208                         + usings.length()
   1209 #endif
   1210      ;
   1211 
   1212  if (numBindings > 0) {
   1213    bindings = NewEmptyBindingData<ModuleScope>(fc, alloc, numBindings);
   1214    if (!bindings) {
   1215      return Nothing();
   1216    }
   1217 
   1218    // The ordering here is important. See comments in ModuleScope.
   1219    InitializeBindingData(bindings, numBindings, imports,
   1220                          &ParserModuleScopeSlotInfo::varStart, vars,
   1221                          &ParserModuleScopeSlotInfo::letStart, lets,
   1222                          &ParserModuleScopeSlotInfo::constStart, consts
   1223 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1224                          ,
   1225                          &ParserModuleScopeSlotInfo::usingStart, usings
   1226 #endif
   1227    );
   1228  }
   1229 
   1230  return Some(bindings);
   1231 }
   1232 
   1233 Maybe<ModuleScope::ParserData*> ParserBase::newModuleScopeData(
   1234    ParseContext::Scope& scope) {
   1235  return NewModuleScopeData(fc_, scope, stencilAlloc(), pc_);
   1236 }
   1237 
   1238 static Maybe<EvalScope::ParserData*> NewEvalScopeData(
   1239    FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
   1240    ParseContext* pc) {
   1241  ParserBindingNameVector vars(fc);
   1242 
   1243  // Treat all bindings as closed over in non-strict eval.
   1244  bool allBindingsClosedOver =
   1245      !pc->sc()->strict() || pc->sc()->allBindingsClosedOver();
   1246  for (BindingIter bi = scope.bindings(pc); bi; bi++) {
   1247    // Eval scopes only contain 'var' bindings.
   1248    MOZ_ASSERT(bi.kind() == BindingKind::Var);
   1249    bool isTopLevelFunction =
   1250        bi.declarationKind() == DeclarationKind::BodyLevelFunction;
   1251    bool closedOver = allBindingsClosedOver || bi.closedOver();
   1252 
   1253    ParserBindingName binding(bi.name(), closedOver, isTopLevelFunction);
   1254    if (!vars.append(binding)) {
   1255      return Nothing();
   1256    }
   1257  }
   1258 
   1259  EvalScope::ParserData* bindings = nullptr;
   1260  uint32_t numBindings = vars.length();
   1261 
   1262  if (numBindings > 0) {
   1263    bindings = NewEmptyBindingData<EvalScope>(fc, alloc, numBindings);
   1264    if (!bindings) {
   1265      return Nothing();
   1266    }
   1267 
   1268    InitializeBindingData(bindings, numBindings, vars);
   1269  }
   1270 
   1271  return Some(bindings);
   1272 }
   1273 
   1274 Maybe<EvalScope::ParserData*> ParserBase::newEvalScopeData(
   1275    ParseContext::Scope& scope) {
   1276  return NewEvalScopeData(fc_, scope, stencilAlloc(), pc_);
   1277 }
   1278 
   1279 Maybe<FunctionScope::ParserData*> ParserBase::newFunctionScopeData(
   1280    ParseContext::Scope& scope, bool hasParameterExprs) {
   1281  ParserBindingNameVector positionalFormals(fc_);
   1282  ParserBindingNameVector formals(fc_);
   1283  ParserBindingNameVector vars(fc_);
   1284 
   1285  bool allBindingsClosedOver =
   1286      pc_->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
   1287  bool argumentBindingsClosedOver =
   1288      allBindingsClosedOver || pc_->isGeneratorOrAsync();
   1289  bool hasDuplicateParams = pc_->functionBox()->hasDuplicateParameters;
   1290 
   1291  // Positional parameter names must be added in order of appearance as they are
   1292  // referenced using argument slots.
   1293  for (size_t i = 0; i < pc_->positionalFormalParameterNames().length(); i++) {
   1294    TaggedParserAtomIndex name = pc_->positionalFormalParameterNames()[i];
   1295 
   1296    ParserBindingName bindName;
   1297    if (name) {
   1298      DeclaredNamePtr p = scope.lookupDeclaredName(name);
   1299 
   1300      // Do not consider any positional formal parameters closed over if
   1301      // there are parameter defaults. It is the binding in the defaults
   1302      // scope that is closed over instead.
   1303      bool closedOver =
   1304          argumentBindingsClosedOver || (p && p->value()->closedOver());
   1305 
   1306      // If the parameter name has duplicates, only the final parameter
   1307      // name should be on the environment, as otherwise the environment
   1308      // object would have multiple, same-named properties.
   1309      if (hasDuplicateParams) {
   1310        for (size_t j = pc_->positionalFormalParameterNames().length() - 1;
   1311             j > i; j--) {
   1312          if (TaggedParserAtomIndex(pc_->positionalFormalParameterNames()[j]) ==
   1313              name) {
   1314            closedOver = false;
   1315            break;
   1316          }
   1317        }
   1318      }
   1319 
   1320      bindName = ParserBindingName(name, closedOver);
   1321    }
   1322 
   1323    if (!positionalFormals.append(bindName)) {
   1324      return Nothing();
   1325    }
   1326  }
   1327 
   1328  for (BindingIter bi = scope.bindings(pc_); bi; bi++) {
   1329    ParserBindingName binding(bi.name(),
   1330                              allBindingsClosedOver || bi.closedOver());
   1331    switch (bi.kind()) {
   1332      case BindingKind::FormalParameter:
   1333        // Positional parameter names are already handled above.
   1334        if (bi.declarationKind() == DeclarationKind::FormalParameter) {
   1335          if (!formals.append(binding)) {
   1336            return Nothing();
   1337          }
   1338        }
   1339        break;
   1340      case BindingKind::Var:
   1341        // The only vars in the function scope when there are parameter
   1342        // exprs, which induces a separate var environment, should be the
   1343        // special bindings.
   1344        MOZ_ASSERT_IF(hasParameterExprs,
   1345                      FunctionScope::isSpecialName(bi.name()));
   1346        if (!vars.append(binding)) {
   1347          return Nothing();
   1348        }
   1349        break;
   1350      case BindingKind::Let:
   1351      case BindingKind::Const:
   1352 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1353      case BindingKind::Using:
   1354 #endif
   1355        break;
   1356      default:
   1357        MOZ_CRASH("bad function scope BindingKind");
   1358        break;
   1359    }
   1360  }
   1361 
   1362  // This should already be checked by GeneralParser::functionArguments.
   1363  MOZ_ASSERT(positionalFormals.length() <= UINT16_MAX);
   1364 
   1365  if (positionalFormals.length() + formals.length() > UINT16_MAX) {
   1366    error(JSMSG_TOO_MANY_FUN_ARGS);
   1367    return Nothing();
   1368  }
   1369 
   1370  FunctionScope::ParserData* bindings = nullptr;
   1371  uint32_t numBindings =
   1372      positionalFormals.length() + formals.length() + vars.length();
   1373 
   1374  if (numBindings > 0) {
   1375    bindings =
   1376        NewEmptyBindingData<FunctionScope>(fc_, stencilAlloc(), numBindings);
   1377    if (!bindings) {
   1378      return Nothing();
   1379    }
   1380 
   1381    // The ordering here is important. See comments in FunctionScope.
   1382    InitializeBindingData(
   1383        bindings, numBindings, positionalFormals,
   1384        &ParserFunctionScopeSlotInfo::nonPositionalFormalStart, formals,
   1385        &ParserFunctionScopeSlotInfo::varStart, vars);
   1386  }
   1387 
   1388  return Some(bindings);
   1389 }
   1390 
   1391 // Compute if `newFunctionScopeData` would return any binding list with any
   1392 // entry marked as closed-over. This is done without the need to allocate the
   1393 // binding list. If true, an EnvironmentObject will be needed at runtime.
   1394 bool FunctionScopeHasClosedOverBindings(ParseContext* pc) {
   1395  bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver() ||
   1396                               pc->functionScope().tooBigToOptimize();
   1397 
   1398  for (BindingIter bi = pc->functionScope().bindings(pc); bi; bi++) {
   1399    switch (bi.kind()) {
   1400      case BindingKind::FormalParameter:
   1401      case BindingKind::Var:
   1402        if (allBindingsClosedOver || bi.closedOver()) {
   1403          return true;
   1404        }
   1405        break;
   1406 
   1407      default:
   1408        break;
   1409    }
   1410  }
   1411 
   1412  return false;
   1413 }
   1414 
   1415 VarScope::ParserData* NewEmptyVarScopeData(FrontendContext* fc,
   1416                                           LifoAlloc& alloc,
   1417                                           uint32_t numBindings) {
   1418  return NewEmptyBindingData<VarScope>(fc, alloc, numBindings);
   1419 }
   1420 
   1421 static Maybe<VarScope::ParserData*> NewVarScopeData(FrontendContext* fc,
   1422                                                    ParseContext::Scope& scope,
   1423                                                    LifoAlloc& alloc,
   1424                                                    ParseContext* pc) {
   1425  ParserBindingNameVector vars(fc);
   1426 
   1427  bool allBindingsClosedOver =
   1428      pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
   1429 
   1430  for (BindingIter bi = scope.bindings(pc); bi; bi++) {
   1431    if (bi.kind() == BindingKind::Var) {
   1432      ParserBindingName binding(bi.name(),
   1433                                allBindingsClosedOver || bi.closedOver());
   1434      if (!vars.append(binding)) {
   1435        return Nothing();
   1436      }
   1437    } else {
   1438      MOZ_ASSERT(bi.kind() == BindingKind::Let ||
   1439                     bi.kind() == BindingKind::Const
   1440 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1441                     || bi.kind() == BindingKind::Using
   1442 #endif
   1443                 ,
   1444                 "bad var scope BindingKind");
   1445    }
   1446  }
   1447 
   1448  VarScope::ParserData* bindings = nullptr;
   1449  uint32_t numBindings = vars.length();
   1450 
   1451  if (numBindings > 0) {
   1452    bindings = NewEmptyBindingData<VarScope>(fc, alloc, numBindings);
   1453    if (!bindings) {
   1454      return Nothing();
   1455    }
   1456 
   1457    InitializeBindingData(bindings, numBindings, vars);
   1458  }
   1459 
   1460  return Some(bindings);
   1461 }
   1462 
   1463 // Compute if `NewVarScopeData` would return any binding list. This is done
   1464 // without allocate the binding list.
   1465 static bool VarScopeHasBindings(ParseContext* pc) {
   1466  for (BindingIter bi = pc->varScope().bindings(pc); bi; bi++) {
   1467    if (bi.kind() == BindingKind::Var) {
   1468      return true;
   1469    }
   1470  }
   1471 
   1472  return false;
   1473 }
   1474 
   1475 Maybe<VarScope::ParserData*> ParserBase::newVarScopeData(
   1476    ParseContext::Scope& scope) {
   1477  return NewVarScopeData(fc_, scope, stencilAlloc(), pc_);
   1478 }
   1479 
   1480 static Maybe<LexicalScope::ParserData*> NewLexicalScopeData(
   1481    FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
   1482    ParseContext* pc) {
   1483  ParserBindingNameVector lets(fc);
   1484  ParserBindingNameVector consts(fc);
   1485 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1486  ParserBindingNameVector usings(fc);
   1487 #endif
   1488 
   1489  bool allBindingsClosedOver =
   1490      pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
   1491 
   1492  for (BindingIter bi = scope.bindings(pc); bi; bi++) {
   1493    ParserBindingName binding(bi.name(),
   1494                              allBindingsClosedOver || bi.closedOver());
   1495    switch (bi.kind()) {
   1496      case BindingKind::Let:
   1497        if (!lets.append(binding)) {
   1498          return Nothing();
   1499        }
   1500        break;
   1501      case BindingKind::Const:
   1502        if (!consts.append(binding)) {
   1503          return Nothing();
   1504        }
   1505        break;
   1506 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1507      case BindingKind::Using:
   1508        if (!usings.append(binding)) {
   1509          return Nothing();
   1510        }
   1511        break;
   1512 #endif
   1513      case BindingKind::Var:
   1514      case BindingKind::FormalParameter:
   1515        break;
   1516      default:
   1517        MOZ_CRASH("Bad lexical scope BindingKind");
   1518        break;
   1519    }
   1520  }
   1521 
   1522  LexicalScope::ParserData* bindings = nullptr;
   1523  uint32_t numBindings = lets.length() + consts.length()
   1524 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1525                         + usings.length()
   1526 #endif
   1527      ;
   1528 
   1529  if (numBindings > 0) {
   1530    bindings = NewEmptyBindingData<LexicalScope>(fc, alloc, numBindings);
   1531    if (!bindings) {
   1532      return Nothing();
   1533    }
   1534 
   1535    // The ordering here is important. See comments in LexicalScope.
   1536    InitializeBindingData(bindings, numBindings, lets,
   1537                          &ParserLexicalScopeSlotInfo::constStart, consts
   1538 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1539                          ,
   1540                          &ParserLexicalScopeSlotInfo::usingStart, usings
   1541 #endif
   1542    );
   1543  }
   1544 
   1545  return Some(bindings);
   1546 }
   1547 
   1548 // Compute if `NewLexicalScopeData` would return any binding list with any entry
   1549 // marked as closed-over. This is done without the need to allocate the binding
   1550 // list. If true, an EnvironmentObject will be needed at runtime.
   1551 bool LexicalScopeHasClosedOverBindings(ParseContext* pc,
   1552                                       ParseContext::Scope& scope) {
   1553  bool allBindingsClosedOver =
   1554      pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
   1555 
   1556  for (BindingIter bi = scope.bindings(pc); bi; bi++) {
   1557    switch (bi.kind()) {
   1558      case BindingKind::Let:
   1559      case BindingKind::Const:
   1560        if (allBindingsClosedOver || bi.closedOver()) {
   1561          return true;
   1562        }
   1563        break;
   1564 
   1565      default:
   1566        break;
   1567    }
   1568  }
   1569 
   1570  return false;
   1571 }
   1572 
   1573 Maybe<LexicalScope::ParserData*> ParserBase::newLexicalScopeData(
   1574    ParseContext::Scope& scope) {
   1575  return NewLexicalScopeData(fc_, scope, stencilAlloc(), pc_);
   1576 }
   1577 
   1578 static Maybe<ClassBodyScope::ParserData*> NewClassBodyScopeData(
   1579    FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
   1580    ParseContext* pc) {
   1581  ParserBindingNameVector privateBrand(fc);
   1582  ParserBindingNameVector synthetics(fc);
   1583  ParserBindingNameVector privateMethods(fc);
   1584 
   1585  bool allBindingsClosedOver =
   1586      pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
   1587 
   1588  for (BindingIter bi = scope.bindings(pc); bi; bi++) {
   1589    ParserBindingName binding(bi.name(),
   1590                              allBindingsClosedOver || bi.closedOver());
   1591    switch (bi.kind()) {
   1592      case BindingKind::Synthetic:
   1593        if (bi.name() ==
   1594            TaggedParserAtomIndex::WellKnown::dot_privateBrand_()) {
   1595          MOZ_ASSERT(privateBrand.empty());
   1596          if (!privateBrand.append(binding)) {
   1597            return Nothing();
   1598          }
   1599        } else {
   1600          if (!synthetics.append(binding)) {
   1601            return Nothing();
   1602          }
   1603        }
   1604        break;
   1605 
   1606      case BindingKind::PrivateMethod:
   1607        if (!privateMethods.append(binding)) {
   1608          return Nothing();
   1609        }
   1610        break;
   1611 
   1612      default:
   1613        MOZ_CRASH("bad class body scope BindingKind");
   1614        break;
   1615    }
   1616  }
   1617 
   1618  // We should have zero or one private brands.
   1619  MOZ_ASSERT(privateBrand.length() == 0 || privateBrand.length() == 1);
   1620 
   1621  ClassBodyScope::ParserData* bindings = nullptr;
   1622  uint32_t numBindings =
   1623      privateBrand.length() + synthetics.length() + privateMethods.length();
   1624 
   1625  if (numBindings > 0) {
   1626    bindings = NewEmptyBindingData<ClassBodyScope>(fc, alloc, numBindings);
   1627    if (!bindings) {
   1628      return Nothing();
   1629    }
   1630    // To simplify initialization of the bindings, we concatenate the
   1631    // synthetics+privateBrand vector such that the private brand is always the
   1632    // first element, as ordering is important. See comments in ClassBodyScope.
   1633    ParserBindingNameVector brandAndSynthetics(fc);
   1634    if (!brandAndSynthetics.appendAll(privateBrand)) {
   1635      return Nothing();
   1636    }
   1637    if (!brandAndSynthetics.appendAll(synthetics)) {
   1638      return Nothing();
   1639    }
   1640 
   1641    // The ordering here is important. See comments in ClassBodyScope.
   1642    InitializeBindingData(bindings, numBindings, brandAndSynthetics,
   1643                          &ParserClassBodyScopeSlotInfo::privateMethodStart,
   1644                          privateMethods);
   1645  }
   1646 
   1647  // `EmitterScope::lookupPrivate()` requires `.privateBrand` to be stored in a
   1648  // predictable slot: the first slot available in the environment object,
   1649  // `ClassBodyLexicalEnvironmentObject::privateBrandSlot()`. We assume that
   1650  // if `.privateBrand` is first in the scope, it will be stored there.
   1651  MOZ_ASSERT_IF(!privateBrand.empty(),
   1652                GetScopeDataTrailingNames(bindings)[0].name() ==
   1653                    TaggedParserAtomIndex::WellKnown::dot_privateBrand_());
   1654 
   1655  return Some(bindings);
   1656 }
   1657 
   1658 Maybe<ClassBodyScope::ParserData*> ParserBase::newClassBodyScopeData(
   1659    ParseContext::Scope& scope) {
   1660  return NewClassBodyScopeData(fc_, scope, stencilAlloc(), pc_);
   1661 }
   1662 
   1663 template <>
   1664 SyntaxParseHandler::LexicalScopeNodeResult
   1665 PerHandlerParser<SyntaxParseHandler>::finishLexicalScope(
   1666    ParseContext::Scope& scope, Node body, ScopeKind kind) {
   1667  if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
   1668    return errorResult();
   1669  }
   1670 
   1671  return handler_.newLexicalScope(body);
   1672 }
   1673 
   1674 template <>
   1675 FullParseHandler::LexicalScopeNodeResult
   1676 PerHandlerParser<FullParseHandler>::finishLexicalScope(
   1677    ParseContext::Scope& scope, ParseNode* body, ScopeKind kind) {
   1678  if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
   1679    return errorResult();
   1680  }
   1681 
   1682  Maybe<LexicalScope::ParserData*> bindings = newLexicalScopeData(scope);
   1683  if (!bindings) {
   1684    return errorResult();
   1685  }
   1686 
   1687  return handler_.newLexicalScope(*bindings, body, kind);
   1688 }
   1689 
   1690 template <>
   1691 SyntaxParseHandler::ClassBodyScopeNodeResult
   1692 PerHandlerParser<SyntaxParseHandler>::finishClassBodyScope(
   1693    ParseContext::Scope& scope, ListNodeType body) {
   1694  if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
   1695    return errorResult();
   1696  }
   1697 
   1698  return handler_.newClassBodyScope(body);
   1699 }
   1700 
   1701 template <>
   1702 FullParseHandler::ClassBodyScopeNodeResult
   1703 PerHandlerParser<FullParseHandler>::finishClassBodyScope(
   1704    ParseContext::Scope& scope, ListNode* body) {
   1705  if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
   1706    return errorResult();
   1707  }
   1708 
   1709  Maybe<ClassBodyScope::ParserData*> bindings = newClassBodyScopeData(scope);
   1710  if (!bindings) {
   1711    return errorResult();
   1712  }
   1713 
   1714  return handler_.newClassBodyScope(*bindings, body);
   1715 }
   1716 
   1717 template <class ParseHandler>
   1718 bool PerHandlerParser<ParseHandler>::checkForUndefinedPrivateFields(
   1719    EvalSharedContext* evalSc) {
   1720  if (!this->compilationState_.isInitialStencil()) {
   1721    // We're delazifying -- so we already checked private names during first
   1722    // parse.
   1723    return true;
   1724  }
   1725 
   1726  Vector<UnboundPrivateName, 8> unboundPrivateNames(fc_);
   1727  if (!usedNames_.getUnboundPrivateNames(unboundPrivateNames)) {
   1728    return false;
   1729  }
   1730 
   1731  // No unbound names, let's get out of here!
   1732  if (unboundPrivateNames.empty()) {
   1733    return true;
   1734  }
   1735 
   1736  // It is an early error if there's private name references unbound,
   1737  // unless it's an eval, in which case we need to check the scope
   1738  // chain.
   1739  if (!evalSc) {
   1740    // The unbound private names are sorted, so just grab the first one.
   1741    UnboundPrivateName minimum = unboundPrivateNames[0];
   1742    UniqueChars str = this->parserAtoms().toPrintableString(minimum.atom);
   1743    if (!str) {
   1744      ReportOutOfMemory(this->fc_);
   1745      return false;
   1746    }
   1747 
   1748    errorAt(minimum.position.begin, JSMSG_MISSING_PRIVATE_DECL, str.get());
   1749    return false;
   1750  }
   1751 
   1752  // It's important that the unbound private names are sorted, as we
   1753  // want our errors to always be issued to the first textually.
   1754  for (UnboundPrivateName unboundName : unboundPrivateNames) {
   1755    // If the enclosingScope is non-syntactic, then we are in a
   1756    // Debugger.Frame.prototype.eval call. In order to find the declared private
   1757    // names, we must use the effective scope that was determined when creating
   1758    // the scopeContext.
   1759    if (!this->compilationState_.scopeContext
   1760             .effectiveScopePrivateFieldCacheHas(unboundName.atom)) {
   1761      UniqueChars str = this->parserAtoms().toPrintableString(unboundName.atom);
   1762      if (!str) {
   1763        ReportOutOfMemory(this->fc_);
   1764        return false;
   1765      }
   1766      errorAt(unboundName.position.begin, JSMSG_MISSING_PRIVATE_DECL,
   1767              str.get());
   1768      return false;
   1769    }
   1770  }
   1771 
   1772  return true;
   1773 }
   1774 
   1775 template <typename Unit>
   1776 FullParseHandler::LexicalScopeNodeResult
   1777 Parser<FullParseHandler, Unit>::evalBody(EvalSharedContext* evalsc) {
   1778  SourceParseContext evalpc(this, evalsc, /* newDirectives = */ nullptr);
   1779  if (!evalpc.init()) {
   1780    return errorResult();
   1781  }
   1782 
   1783  ParseContext::VarScope varScope(this);
   1784  if (!varScope.init(pc_)) {
   1785    return errorResult();
   1786  }
   1787 
   1788  LexicalScopeNode* body;
   1789  {
   1790    // All evals have an implicit non-extensible lexical scope.
   1791    ParseContext::Scope lexicalScope(this);
   1792    if (!lexicalScope.init(pc_)) {
   1793      return errorResult();
   1794    }
   1795 
   1796    ListNode* list = MOZ_TRY(statementList(YieldIsName));
   1797 
   1798    if (!checkStatementsEOF()) {
   1799      return errorResult();
   1800    }
   1801 
   1802    // Private names not lexically defined must trigger a syntax error.
   1803    if (!checkForUndefinedPrivateFields(evalsc)) {
   1804      return errorResult();
   1805    }
   1806 
   1807    body = MOZ_TRY(finishLexicalScope(lexicalScope, list));
   1808  }
   1809 
   1810 #ifdef DEBUG
   1811  if (evalpc.superScopeNeedsHomeObject() &&
   1812      !this->compilationState_.input.enclosingScope.isNull()) {
   1813    // If superScopeNeedsHomeObject_ is set and we are an entry-point
   1814    // ParseContext, then we must be emitting an eval script, and the
   1815    // outer function must already be marked as needing a home object
   1816    // since it contains an eval.
   1817    MOZ_ASSERT(
   1818        this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain,
   1819        "Eval must have found an enclosing function box scope that "
   1820        "allows super.property");
   1821  }
   1822 #endif
   1823 
   1824  if (!CheckParseTree(this->fc_, alloc_, body)) {
   1825    return errorResult();
   1826  }
   1827 
   1828  ParseNode* node = body;
   1829  // Don't constant-fold inside "use asm" code, as this could create a parse
   1830  // tree that doesn't type-check as asm.js.
   1831  if (!pc_->useAsmOrInsideUseAsm()) {
   1832    if (!FoldConstants(this->fc_, this->parserAtoms(), this->bigInts(), &node,
   1833                       &handler_)) {
   1834      return errorResult();
   1835    }
   1836  }
   1837  body = handler_.asLexicalScopeNode(node);
   1838 
   1839  if (!this->setSourceMapInfo()) {
   1840    return errorResult();
   1841  }
   1842 
   1843  if (pc_->sc()->strict()) {
   1844    if (!propagateFreeNamesAndMarkClosedOverBindings(varScope)) {
   1845      return errorResult();
   1846    }
   1847  } else {
   1848    // For non-strict eval scripts, since all bindings are automatically
   1849    // considered closed over, we don't need to call propagateFreeNames-
   1850    // AndMarkClosedOverBindings. However, Annex B.3.3 functions still need to
   1851    // be marked.
   1852    if (!varScope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
   1853      return errorResult();
   1854    }
   1855  }
   1856 
   1857  Maybe<EvalScope::ParserData*> bindings = newEvalScopeData(pc_->varScope());
   1858  if (!bindings) {
   1859    return errorResult();
   1860  }
   1861  evalsc->bindings = *bindings;
   1862 
   1863  return body;
   1864 }
   1865 
   1866 template <typename Unit>
   1867 FullParseHandler::ListNodeResult Parser<FullParseHandler, Unit>::globalBody(
   1868    GlobalSharedContext* globalsc) {
   1869  SourceParseContext globalpc(this, globalsc, /* newDirectives = */ nullptr);
   1870  if (!globalpc.init()) {
   1871    return errorResult();
   1872  }
   1873 
   1874  ParseContext::VarScope varScope(this);
   1875  if (!varScope.init(pc_)) {
   1876    return errorResult();
   1877  }
   1878 
   1879  ListNode* body = MOZ_TRY(statementList(YieldIsName));
   1880 
   1881  if (!checkStatementsEOF()) {
   1882    return errorResult();
   1883  }
   1884 
   1885  if (!CheckParseTree(this->fc_, alloc_, body)) {
   1886    return errorResult();
   1887  }
   1888 
   1889  if (!checkForUndefinedPrivateFields()) {
   1890    return errorResult();
   1891  }
   1892 
   1893  ParseNode* node = body;
   1894  // Don't constant-fold inside "use asm" code, as this could create a parse
   1895  // tree that doesn't type-check as asm.js.
   1896  if (!pc_->useAsmOrInsideUseAsm()) {
   1897    if (!FoldConstants(this->fc_, this->parserAtoms(), this->bigInts(), &node,
   1898                       &handler_)) {
   1899      return errorResult();
   1900    }
   1901  }
   1902  body = &node->as<ListNode>();
   1903 
   1904  if (!this->setSourceMapInfo()) {
   1905    return errorResult();
   1906  }
   1907 
   1908  // For global scripts, whether bindings are closed over or not doesn't
   1909  // matter, so no need to call propagateFreeNamesAndMarkClosedOver-
   1910  // Bindings. However, Annex B.3.3 functions still need to be marked.
   1911  if (!varScope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
   1912    return errorResult();
   1913  }
   1914 
   1915  Maybe<GlobalScope::ParserData*> bindings =
   1916      newGlobalScopeData(pc_->varScope());
   1917  if (!bindings) {
   1918    return errorResult();
   1919  }
   1920  globalsc->bindings = *bindings;
   1921 
   1922  return body;
   1923 }
   1924 
   1925 template <typename Unit>
   1926 FullParseHandler::ModuleNodeResult Parser<FullParseHandler, Unit>::moduleBody(
   1927    ModuleSharedContext* modulesc) {
   1928  MOZ_ASSERT(checkOptionsCalled_);
   1929 
   1930  this->compilationState_.moduleMetadata =
   1931      fc_->getAllocator()->template new_<StencilModuleMetadata>();
   1932  if (!this->compilationState_.moduleMetadata) {
   1933    return errorResult();
   1934  }
   1935 
   1936  SourceParseContext modulepc(this, modulesc, nullptr);
   1937  if (!modulepc.init()) {
   1938    return errorResult();
   1939  }
   1940 
   1941  ParseContext::VarScope varScope(this);
   1942  if (!varScope.init(pc_)) {
   1943    return errorResult();
   1944  }
   1945 
   1946  ModuleNodeType moduleNode = MOZ_TRY(handler_.newModule(pos()));
   1947 
   1948  AutoAwaitIsKeyword<FullParseHandler, Unit> awaitIsKeyword(
   1949      this, AwaitIsModuleKeyword);
   1950  ListNode* stmtList = MOZ_TRY(statementList(YieldIsName));
   1951 
   1952  MOZ_ASSERT(stmtList->isKind(ParseNodeKind::StatementList));
   1953  moduleNode->setBody(&stmtList->template as<ListNode>());
   1954 
   1955  if (pc_->isAsync()) {
   1956    if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_generator_())) {
   1957      return errorResult();
   1958    }
   1959 
   1960    if (!pc_->declareTopLevelDotGeneratorName()) {
   1961      return errorResult();
   1962    }
   1963  }
   1964 
   1965  TokenKind tt;
   1966  if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
   1967    return errorResult();
   1968  }
   1969  if (tt != TokenKind::Eof) {
   1970    error(JSMSG_GARBAGE_AFTER_INPUT, "module", TokenKindToDesc(tt));
   1971    return errorResult();
   1972  }
   1973 
   1974  // Set the module to async if an await keyword was found at the top level.
   1975  if (pc_->isAsync()) {
   1976    pc_->sc()->asModuleContext()->builder.noteAsync(
   1977        *this->compilationState_.moduleMetadata);
   1978  }
   1979 
   1980  // Generate the Import/Export tables and store in CompilationState.
   1981  if (!modulesc->builder.buildTables(*this->compilationState_.moduleMetadata)) {
   1982    return errorResult();
   1983  }
   1984 
   1985  // Check exported local bindings exist and mark them as closed over.
   1986  StencilModuleMetadata& moduleMetadata =
   1987      *this->compilationState_.moduleMetadata;
   1988  for (auto entry : moduleMetadata.localExportEntries) {
   1989    DeclaredNamePtr p = modulepc.varScope().lookupDeclaredName(entry.localName);
   1990    if (!p) {
   1991      UniqueChars str = this->parserAtoms().toPrintableString(entry.localName);
   1992      if (!str) {
   1993        ReportOutOfMemory(this->fc_);
   1994        return errorResult();
   1995      }
   1996 
   1997      errorNoOffset(JSMSG_MISSING_EXPORT, str.get());
   1998      return errorResult();
   1999    }
   2000 
   2001    p->value()->setClosedOver();
   2002  }
   2003 
   2004  // Reserve an environment slot for a "*namespace*" psuedo-binding and mark as
   2005  // closed-over. We do not know until module linking if this will be used.
   2006  if (!noteDeclaredName(
   2007          TaggedParserAtomIndex::WellKnown::star_namespace_star_(),
   2008          DeclarationKind::Const, pos())) {
   2009    return errorResult();
   2010  }
   2011  modulepc.varScope()
   2012      .lookupDeclaredName(
   2013          TaggedParserAtomIndex::WellKnown::star_namespace_star_())
   2014      ->value()
   2015      ->setClosedOver();
   2016 
   2017  if (!CheckParseTree(this->fc_, alloc_, stmtList)) {
   2018    return errorResult();
   2019  }
   2020 
   2021  ParseNode* node = stmtList;
   2022  // Don't constant-fold inside "use asm" code, as this could create a parse
   2023  // tree that doesn't type-check as asm.js.
   2024  if (!pc_->useAsmOrInsideUseAsm()) {
   2025    if (!FoldConstants(this->fc_, this->parserAtoms(), this->bigInts(), &node,
   2026                       &handler_)) {
   2027      return errorResult();
   2028    }
   2029  }
   2030  stmtList = &node->as<ListNode>();
   2031 
   2032  if (!this->setSourceMapInfo()) {
   2033    return errorResult();
   2034  }
   2035 
   2036  // Private names not lexically defined must trigger a syntax error.
   2037  if (!checkForUndefinedPrivateFields()) {
   2038    return errorResult();
   2039  }
   2040 
   2041  if (!propagateFreeNamesAndMarkClosedOverBindings(modulepc.varScope())) {
   2042    return errorResult();
   2043  }
   2044 
   2045  Maybe<ModuleScope::ParserData*> bindings =
   2046      newModuleScopeData(modulepc.varScope());
   2047  if (!bindings) {
   2048    return errorResult();
   2049  }
   2050 
   2051  modulesc->bindings = *bindings;
   2052  return moduleNode;
   2053 }
   2054 
   2055 template <typename Unit>
   2056 SyntaxParseHandler::ModuleNodeResult
   2057 Parser<SyntaxParseHandler, Unit>::moduleBody(ModuleSharedContext* modulesc) {
   2058  MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
   2059  return errorResult();
   2060 }
   2061 
   2062 template <class ParseHandler>
   2063 typename ParseHandler::NameNodeResult
   2064 PerHandlerParser<ParseHandler>::newInternalDotName(TaggedParserAtomIndex name) {
   2065  NameNodeType nameNode = MOZ_TRY(newName(name));
   2066  if (!noteUsedName(name)) {
   2067    return errorResult();
   2068  }
   2069  return nameNode;
   2070 }
   2071 
   2072 template <class ParseHandler>
   2073 typename ParseHandler::NameNodeResult
   2074 PerHandlerParser<ParseHandler>::newThisName() {
   2075  return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_this_());
   2076 }
   2077 
   2078 template <class ParseHandler>
   2079 typename ParseHandler::NameNodeResult
   2080 PerHandlerParser<ParseHandler>::newNewTargetName() {
   2081  return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_newTarget_());
   2082 }
   2083 
   2084 template <class ParseHandler>
   2085 typename ParseHandler::NameNodeResult
   2086 PerHandlerParser<ParseHandler>::newDotGeneratorName() {
   2087  return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_generator_());
   2088 }
   2089 
   2090 template <class ParseHandler>
   2091 bool PerHandlerParser<ParseHandler>::finishFunctionScopes(
   2092    bool isStandaloneFunction) {
   2093  FunctionBox* funbox = pc_->functionBox();
   2094 
   2095  if (funbox->hasParameterExprs) {
   2096    if (!propagateFreeNamesAndMarkClosedOverBindings(pc_->functionScope())) {
   2097      return false;
   2098    }
   2099 
   2100    // Functions with parameter expressions utilize the FunctionScope for vars
   2101    // generated by sloppy-direct-evals, as well as arguments (which are
   2102    // lexicals bindings). If the function body has var bindings (or has a
   2103    // sloppy-direct-eval that might), then an extra VarScope must be created
   2104    // for them.
   2105    if (VarScopeHasBindings(pc_) ||
   2106        funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings()) {
   2107      funbox->setFunctionHasExtraBodyVarScope();
   2108    }
   2109  }
   2110 
   2111  // See: JSFunction::needsCallObject()
   2112  if (FunctionScopeHasClosedOverBindings(pc_) ||
   2113      funbox->needsCallObjectRegardlessOfBindings()) {
   2114    funbox->setNeedsFunctionEnvironmentObjects();
   2115  }
   2116 
   2117  if (funbox->isNamedLambda() && !isStandaloneFunction) {
   2118    if (!propagateFreeNamesAndMarkClosedOverBindings(pc_->namedLambdaScope())) {
   2119      return false;
   2120    }
   2121 
   2122    // See: JSFunction::needsNamedLambdaEnvironment()
   2123    if (LexicalScopeHasClosedOverBindings(pc_, pc_->namedLambdaScope())) {
   2124      funbox->setNeedsFunctionEnvironmentObjects();
   2125    }
   2126  }
   2127 
   2128  return true;
   2129 }
   2130 
   2131 template <>
   2132 bool PerHandlerParser<FullParseHandler>::finishFunction(
   2133    bool isStandaloneFunction /* = false */) {
   2134  if (!finishFunctionScopes(isStandaloneFunction)) {
   2135    return false;
   2136  }
   2137 
   2138  FunctionBox* funbox = pc_->functionBox();
   2139  ScriptStencil& script = funbox->functionStencil();
   2140 
   2141  if (funbox->isInterpreted()) {
   2142    // BCE will need to generate bytecode for this.
   2143    funbox->emitBytecode = true;
   2144    this->compilationState_.nonLazyFunctionCount++;
   2145  }
   2146 
   2147  bool hasParameterExprs = funbox->hasParameterExprs;
   2148 
   2149  if (hasParameterExprs) {
   2150    Maybe<VarScope::ParserData*> bindings = newVarScopeData(pc_->varScope());
   2151    if (!bindings) {
   2152      return false;
   2153    }
   2154    funbox->setExtraVarScopeBindings(*bindings);
   2155 
   2156    MOZ_ASSERT(bool(*bindings) == VarScopeHasBindings(pc_));
   2157    MOZ_ASSERT_IF(!funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings(),
   2158                  bool(*bindings) == funbox->functionHasExtraBodyVarScope());
   2159  }
   2160 
   2161  {
   2162    Maybe<FunctionScope::ParserData*> bindings =
   2163        newFunctionScopeData(pc_->functionScope(), hasParameterExprs);
   2164    if (!bindings) {
   2165      return false;
   2166    }
   2167    funbox->setFunctionScopeBindings(*bindings);
   2168  }
   2169 
   2170  if (funbox->isNamedLambda() && !isStandaloneFunction) {
   2171    Maybe<LexicalScope::ParserData*> bindings =
   2172        newLexicalScopeData(pc_->namedLambdaScope());
   2173    if (!bindings) {
   2174      return false;
   2175    }
   2176    funbox->setNamedLambdaBindings(*bindings);
   2177  }
   2178 
   2179  funbox->finishScriptFlags();
   2180  funbox->copyFunctionFields(script);
   2181 
   2182  if (this->compilationState_.isInitialStencil()) {
   2183    ScriptStencilExtra& scriptExtra = funbox->functionExtraStencil();
   2184    funbox->copyFunctionExtraFields(scriptExtra);
   2185    funbox->copyScriptExtraFields(scriptExtra);
   2186  }
   2187 
   2188  return true;
   2189 }
   2190 
   2191 template <>
   2192 bool PerHandlerParser<SyntaxParseHandler>::finishFunction(
   2193    bool isStandaloneFunction /* = false */) {
   2194  // The BaseScript for a lazily parsed function needs to know its set of
   2195  // free variables and inner functions so that when it is fully parsed, we
   2196  // can skip over any already syntax parsed inner functions and still
   2197  // retain correct scope information.
   2198 
   2199  if (!finishFunctionScopes(isStandaloneFunction)) {
   2200    return false;
   2201  }
   2202 
   2203  FunctionBox* funbox = pc_->functionBox();
   2204  ScriptStencil& script = funbox->functionStencil();
   2205 
   2206  funbox->finishScriptFlags();
   2207  funbox->copyFunctionFields(script);
   2208 
   2209  ScriptStencilExtra& scriptExtra = funbox->functionExtraStencil();
   2210  funbox->copyFunctionExtraFields(scriptExtra);
   2211  funbox->copyScriptExtraFields(scriptExtra);
   2212 
   2213  // Elide nullptr sentinels from end of binding list. These are inserted for
   2214  // each scope regardless of if any bindings are actually closed over.
   2215  {
   2216    AtomVector& closedOver = pc_->closedOverBindingsForLazy();
   2217    while (!closedOver.empty() && !closedOver.back()) {
   2218      closedOver.popBack();
   2219    }
   2220  }
   2221 
   2222  // Check if we will overflow the `ngcthings` field later.
   2223  mozilla::CheckedUint32 ngcthings =
   2224      mozilla::CheckedUint32(pc_->innerFunctionIndexesForLazy.length()) +
   2225      mozilla::CheckedUint32(pc_->closedOverBindingsForLazy().length());
   2226  if (!ngcthings.isValid()) {
   2227    ReportAllocationOverflow(fc_);
   2228    return false;
   2229  }
   2230 
   2231  // If there are no script-things, we can return early without allocating.
   2232  if (ngcthings.value() == 0) {
   2233    MOZ_ASSERT(!script.hasGCThings());
   2234    return true;
   2235  }
   2236 
   2237  TaggedScriptThingIndex* cursor = nullptr;
   2238  if (!this->compilationState_.allocateGCThingsUninitialized(
   2239          fc_, funbox->index(), ngcthings.value(), &cursor)) {
   2240    return false;
   2241  }
   2242 
   2243  // Copy inner-function and closed-over-binding info for the stencil. The order
   2244  // is important here. We emit functions first, followed by the bindings info.
   2245  // The bindings list uses nullptr as delimiter to separates the bindings per
   2246  // scope.
   2247  //
   2248  // See: FullParseHandler::nextLazyInnerFunction(),
   2249  //      FullParseHandler::nextLazyClosedOverBinding()
   2250  for (const ScriptIndex& index : pc_->innerFunctionIndexesForLazy) {
   2251    void* raw = &(*cursor++);
   2252    new (raw) TaggedScriptThingIndex(index);
   2253  }
   2254  for (auto binding : pc_->closedOverBindingsForLazy()) {
   2255    void* raw = &(*cursor++);
   2256    if (binding) {
   2257      this->parserAtoms().markUsedByStencil(binding, ParserAtom::Atomize::Yes);
   2258      new (raw) TaggedScriptThingIndex(binding);
   2259    } else {
   2260      new (raw) TaggedScriptThingIndex();
   2261    }
   2262  }
   2263 
   2264  return true;
   2265 }
   2266 
   2267 static YieldHandling GetYieldHandling(GeneratorKind generatorKind) {
   2268  if (generatorKind == GeneratorKind::NotGenerator) {
   2269    return YieldIsName;
   2270  }
   2271  return YieldIsKeyword;
   2272 }
   2273 
   2274 static AwaitHandling GetAwaitHandling(FunctionAsyncKind asyncKind) {
   2275  if (asyncKind == FunctionAsyncKind::SyncFunction) {
   2276    return AwaitIsName;
   2277  }
   2278  return AwaitIsKeyword;
   2279 }
   2280 
   2281 static FunctionFlags InitialFunctionFlags(FunctionSyntaxKind kind,
   2282                                          GeneratorKind generatorKind,
   2283                                          FunctionAsyncKind asyncKind,
   2284                                          bool isSelfHosting) {
   2285  FunctionFlags flags = {};
   2286 
   2287  switch (kind) {
   2288    case FunctionSyntaxKind::Expression:
   2289      flags = (generatorKind == GeneratorKind::NotGenerator &&
   2290                       asyncKind == FunctionAsyncKind::SyncFunction
   2291                   ? FunctionFlags::INTERPRETED_LAMBDA
   2292                   : FunctionFlags::INTERPRETED_LAMBDA_GENERATOR_OR_ASYNC);
   2293      break;
   2294    case FunctionSyntaxKind::Arrow:
   2295      flags = FunctionFlags::INTERPRETED_LAMBDA_ARROW;
   2296      break;
   2297    case FunctionSyntaxKind::Method:
   2298    case FunctionSyntaxKind::FieldInitializer:
   2299    case FunctionSyntaxKind::StaticClassBlock:
   2300      flags = FunctionFlags::INTERPRETED_METHOD;
   2301      break;
   2302    case FunctionSyntaxKind::ClassConstructor:
   2303    case FunctionSyntaxKind::DerivedClassConstructor:
   2304      flags = FunctionFlags::INTERPRETED_CLASS_CTOR;
   2305      break;
   2306    case FunctionSyntaxKind::Getter:
   2307      flags = FunctionFlags::INTERPRETED_GETTER;
   2308      break;
   2309    case FunctionSyntaxKind::Setter:
   2310      flags = FunctionFlags::INTERPRETED_SETTER;
   2311      break;
   2312    default:
   2313      MOZ_ASSERT(kind == FunctionSyntaxKind::Statement);
   2314      flags = (generatorKind == GeneratorKind::NotGenerator &&
   2315                       asyncKind == FunctionAsyncKind::SyncFunction
   2316                   ? FunctionFlags::INTERPRETED_NORMAL
   2317                   : FunctionFlags::INTERPRETED_GENERATOR_OR_ASYNC);
   2318  }
   2319 
   2320  if (isSelfHosting) {
   2321    flags.setIsSelfHostedBuiltin();
   2322  }
   2323 
   2324  return flags;
   2325 }
   2326 
   2327 template <typename Unit>
   2328 FullParseHandler::FunctionNodeResult
   2329 Parser<FullParseHandler, Unit>::standaloneFunction(
   2330    const Maybe<uint32_t>& parameterListEnd, FunctionSyntaxKind syntaxKind,
   2331    GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
   2332    Directives inheritedDirectives, Directives* newDirectives) {
   2333  MOZ_ASSERT(checkOptionsCalled_);
   2334  // Skip prelude.
   2335  TokenKind tt;
   2336  if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
   2337    return errorResult();
   2338  }
   2339  if (asyncKind == FunctionAsyncKind::AsyncFunction) {
   2340    MOZ_ASSERT(tt == TokenKind::Async);
   2341    if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
   2342      return errorResult();
   2343    }
   2344  }
   2345  MOZ_ASSERT(tt == TokenKind::Function);
   2346 
   2347  if (!tokenStream.getToken(&tt)) {
   2348    return errorResult();
   2349  }
   2350  if (generatorKind == GeneratorKind::Generator) {
   2351    MOZ_ASSERT(tt == TokenKind::Mul);
   2352    if (!tokenStream.getToken(&tt)) {
   2353      return errorResult();
   2354    }
   2355  }
   2356 
   2357  // Skip function name, if present.
   2358  TaggedParserAtomIndex explicitName;
   2359  if (TokenKindIsPossibleIdentifierName(tt)) {
   2360    explicitName = anyChars.currentName();
   2361  } else {
   2362    anyChars.ungetToken();
   2363  }
   2364 
   2365  FunctionNodeType funNode = MOZ_TRY(handler_.newFunction(syntaxKind, pos()));
   2366 
   2367  ParamsBodyNodeType argsbody = MOZ_TRY(handler_.newParamsBody(pos()));
   2368  funNode->setBody(argsbody);
   2369 
   2370  bool isSelfHosting = options().selfHostingMode;
   2371  FunctionFlags flags =
   2372      InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
   2373  FunctionBox* funbox =
   2374      newFunctionBox(funNode, explicitName, flags, /* toStringStart = */ 0,
   2375                     inheritedDirectives, generatorKind, asyncKind);
   2376  if (!funbox) {
   2377    return errorResult();
   2378  }
   2379 
   2380  // Function is not syntactically part of another script.
   2381  MOZ_ASSERT(funbox->index() == CompilationStencil::TopLevelIndex);
   2382 
   2383  funbox->initStandalone(this->compilationState_.scopeContext, syntaxKind);
   2384 
   2385  SourceParseContext funpc(this, funbox, newDirectives);
   2386  if (!funpc.init()) {
   2387    return errorResult();
   2388  }
   2389 
   2390  YieldHandling yieldHandling = GetYieldHandling(generatorKind);
   2391  AwaitHandling awaitHandling = GetAwaitHandling(asyncKind);
   2392  AutoAwaitIsKeyword<FullParseHandler, Unit> awaitIsKeyword(this,
   2393                                                            awaitHandling);
   2394  if (!functionFormalParametersAndBody(InAllowed, yieldHandling, &funNode,
   2395                                       syntaxKind, parameterListEnd,
   2396                                       /* isStandaloneFunction = */ true)) {
   2397    return errorResult();
   2398  }
   2399 
   2400  if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
   2401    return errorResult();
   2402  }
   2403  if (tt != TokenKind::Eof) {
   2404    error(JSMSG_GARBAGE_AFTER_INPUT, "function body", TokenKindToDesc(tt));
   2405    return errorResult();
   2406  }
   2407 
   2408  if (!CheckParseTree(this->fc_, alloc_, funNode)) {
   2409    return errorResult();
   2410  }
   2411 
   2412  ParseNode* node = funNode;
   2413  // Don't constant-fold inside "use asm" code, as this could create a parse
   2414  // tree that doesn't type-check as asm.js.
   2415  if (!pc_->useAsmOrInsideUseAsm()) {
   2416    if (!FoldConstants(this->fc_, this->parserAtoms(), this->bigInts(), &node,
   2417                       &handler_)) {
   2418      return errorResult();
   2419    }
   2420  }
   2421  funNode = &node->as<FunctionNode>();
   2422 
   2423  if (!checkForUndefinedPrivateFields(nullptr)) {
   2424    return errorResult();
   2425  }
   2426 
   2427  if (!this->setSourceMapInfo()) {
   2428    return errorResult();
   2429  }
   2430 
   2431  return funNode;
   2432 }
   2433 
   2434 template <class ParseHandler, typename Unit>
   2435 typename ParseHandler::LexicalScopeNodeResult
   2436 GeneralParser<ParseHandler, Unit>::functionBody(InHandling inHandling,
   2437                                                YieldHandling yieldHandling,
   2438                                                FunctionSyntaxKind kind,
   2439                                                FunctionBodyType type) {
   2440  MOZ_ASSERT(pc_->isFunctionBox());
   2441 
   2442 #ifdef DEBUG
   2443  uint32_t startYieldOffset = pc_->lastYieldOffset;
   2444 #endif
   2445 
   2446  Node body;
   2447  if (type == StatementListBody) {
   2448    bool inheritedStrict = pc_->sc()->strict();
   2449    body = MOZ_TRY(statementList(yieldHandling));
   2450 
   2451    // When we transitioned from non-strict to strict mode, we need to
   2452    // validate that all parameter names are valid strict mode names.
   2453    if (!inheritedStrict && pc_->sc()->strict()) {
   2454      MOZ_ASSERT(pc_->sc()->hasExplicitUseStrict(),
   2455                 "strict mode should only change when a 'use strict' directive "
   2456                 "is present");
   2457      if (!hasValidSimpleStrictParameterNames()) {
   2458        // Request that this function be reparsed as strict to report
   2459        // the invalid parameter name at the correct source location.
   2460        pc_->newDirectives->setStrict();
   2461        return errorResult();
   2462      }
   2463    }
   2464  } else {
   2465    MOZ_ASSERT(type == ExpressionBody);
   2466 
   2467    // Async functions are implemented as generators, and generators are
   2468    // assumed to be statement lists, to prepend initial `yield`.
   2469    ListNodeType stmtList = null();
   2470    if (pc_->isAsync()) {
   2471      stmtList = MOZ_TRY(handler_.newStatementList(pos()));
   2472    }
   2473 
   2474    Node kid =
   2475        MOZ_TRY(assignExpr(inHandling, yieldHandling, TripledotProhibited));
   2476 
   2477    body = MOZ_TRY(handler_.newExpressionBody(kid));
   2478 
   2479    if (pc_->isAsync()) {
   2480      handler_.addStatementToList(stmtList, body);
   2481      body = stmtList;
   2482    }
   2483  }
   2484 
   2485  MOZ_ASSERT_IF(!pc_->isGenerator() && !pc_->isAsync(),
   2486                pc_->lastYieldOffset == startYieldOffset);
   2487  MOZ_ASSERT_IF(pc_->isGenerator(), kind != FunctionSyntaxKind::Arrow);
   2488  MOZ_ASSERT_IF(pc_->isGenerator(), type == StatementListBody);
   2489 
   2490  if (pc_->needsDotGeneratorName()) {
   2491    MOZ_ASSERT_IF(!pc_->isAsync(), type == StatementListBody);
   2492    if (!pc_->declareDotGeneratorName()) {
   2493      return errorResult();
   2494    }
   2495    if (pc_->isGenerator()) {
   2496      NameNodeType generator = MOZ_TRY(newDotGeneratorName());
   2497      if (!handler_.prependInitialYield(handler_.asListNode(body), generator)) {
   2498        return errorResult();
   2499      }
   2500    }
   2501  }
   2502 
   2503  if (pc_->numberOfArgumentsNames > 0 || kind == FunctionSyntaxKind::Arrow) {
   2504    MOZ_ASSERT(pc_->isFunctionBox());
   2505    pc_->sc()->setIneligibleForArgumentsLength();
   2506  }
   2507 
   2508  // Declare the 'arguments', 'this', and 'new.target' bindings if necessary
   2509  // before finishing up the scope so these special bindings get marked as
   2510  // closed over if necessary. Arrow functions don't have these bindings.
   2511  if (kind != FunctionSyntaxKind::Arrow) {
   2512    bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
   2513    if (!pc_->declareFunctionArgumentsObject(usedNames_,
   2514                                             canSkipLazyClosedOverBindings)) {
   2515      return errorResult();
   2516    }
   2517    if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
   2518      return errorResult();
   2519    }
   2520    if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
   2521      return errorResult();
   2522    }
   2523  }
   2524 
   2525  return finishLexicalScope(pc_->varScope(), body, ScopeKind::FunctionLexical);
   2526 }
   2527 
   2528 template <class ParseHandler, typename Unit>
   2529 bool GeneralParser<ParseHandler, Unit>::matchOrInsertSemicolon(
   2530    Modifier modifier /* = TokenStream::SlashIsRegExp */) {
   2531  TokenKind tt = TokenKind::Eof;
   2532  if (!tokenStream.peekTokenSameLine(&tt, modifier)) {
   2533    return false;
   2534  }
   2535  if (tt != TokenKind::Eof && tt != TokenKind::Eol && tt != TokenKind::Semi &&
   2536      tt != TokenKind::RightCurly) {
   2537    /*
   2538     * When current token is `await` and it's outside of async function,
   2539     * it's possibly intended to be an await expression.
   2540     *
   2541     *   await f();
   2542     *        ^
   2543     *        |
   2544     *        tried to insert semicolon here
   2545     *
   2546     * Detect this situation and throw an understandable error.  Otherwise
   2547     * we'd throw a confusing "unexpected token: (unexpected token)" error.
   2548     */
   2549    if (!pc_->isAsync() && anyChars.currentToken().type == TokenKind::Await) {
   2550      error(JSMSG_AWAIT_OUTSIDE_ASYNC_OR_MODULE);
   2551      return false;
   2552    }
   2553    if (!yieldExpressionsSupported() &&
   2554        anyChars.currentToken().type == TokenKind::Yield) {
   2555      error(JSMSG_YIELD_OUTSIDE_GENERATOR);
   2556      return false;
   2557    }
   2558 
   2559 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   2560    if (options().explicitResourceManagement() &&
   2561        anyChars.currentToken().type == TokenKind::Using &&
   2562        !this->pc_->isUsingSyntaxAllowed()) {
   2563      error(JSMSG_USING_OUTSIDE_BLOCK_OR_MODULE);
   2564      return false;
   2565    }
   2566 #endif
   2567 
   2568    /* Advance the scanner for proper error location reporting. */
   2569    tokenStream.consumeKnownToken(tt, modifier);
   2570    error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(tt));
   2571    return false;
   2572  }
   2573  bool matched;
   2574  return tokenStream.matchToken(&matched, TokenKind::Semi, modifier);
   2575 }
   2576 
   2577 bool ParserBase::leaveInnerFunction(ParseContext* outerpc) {
   2578  MOZ_ASSERT(pc_ != outerpc);
   2579 
   2580  MOZ_ASSERT_IF(outerpc->isFunctionBox(),
   2581                outerpc->functionBox()->index() < pc_->functionBox()->index());
   2582 
   2583  // If the current function allows super.property but cannot have a home
   2584  // object, i.e., it is an arrow function, we need to propagate the flag to
   2585  // the outer ParseContext.
   2586  if (pc_->superScopeNeedsHomeObject()) {
   2587    if (!pc_->isArrowFunction()) {
   2588      MOZ_ASSERT(pc_->functionBox()->needsHomeObject());
   2589    } else {
   2590      outerpc->setSuperScopeNeedsHomeObject();
   2591    }
   2592  }
   2593 
   2594  // Lazy functions inner to another lazy function need to be remembered by
   2595  // the inner function so that if the outer function is eventually parsed
   2596  // we do not need any further parsing or processing of the inner function.
   2597  //
   2598  // Append the inner function index here unconditionally; the vector is only
   2599  // used if the Parser using outerpc is a syntax parsing. See
   2600  // GeneralParser<SyntaxParseHandler>::finishFunction.
   2601  if (!outerpc->innerFunctionIndexesForLazy.append(
   2602          pc_->functionBox()->index())) {
   2603    return false;
   2604  }
   2605 
   2606  PropagateTransitiveParseFlags(pc_->functionBox(), outerpc->sc());
   2607 
   2608  return true;
   2609 }
   2610 
   2611 TaggedParserAtomIndex ParserBase::prefixAccessorName(
   2612    PropertyType propType, TaggedParserAtomIndex propAtom) {
   2613  StringBuilder prefixed(fc_);
   2614  if (propType == PropertyType::Setter) {
   2615    if (!prefixed.append("set ")) {
   2616      return TaggedParserAtomIndex::null();
   2617    }
   2618  } else {
   2619    if (!prefixed.append("get ")) {
   2620      return TaggedParserAtomIndex::null();
   2621    }
   2622  }
   2623  if (!prefixed.append(this->parserAtoms(), propAtom)) {
   2624    return TaggedParserAtomIndex::null();
   2625  }
   2626  return prefixed.finishParserAtom(this->parserAtoms(), fc_);
   2627 }
   2628 
   2629 template <class ParseHandler, typename Unit>
   2630 void GeneralParser<ParseHandler, Unit>::setFunctionStartAtPosition(
   2631    FunctionBox* funbox, TokenPos pos) const {
   2632  uint32_t startLine;
   2633  JS::LimitedColumnNumberOneOrigin startColumn;
   2634  tokenStream.computeLineAndColumn(pos.begin, &startLine, &startColumn);
   2635 
   2636  // NOTE: `Debugger::CallData::findScripts` relies on sourceStart and
   2637  //       lineno/column referring to the same location.
   2638  funbox->setStart(pos.begin, startLine, startColumn);
   2639 }
   2640 
   2641 template <class ParseHandler, typename Unit>
   2642 void GeneralParser<ParseHandler, Unit>::setFunctionStartAtCurrentToken(
   2643    FunctionBox* funbox) const {
   2644  setFunctionStartAtPosition(funbox, anyChars.currentToken().pos);
   2645 }
   2646 
   2647 template <class ParseHandler, typename Unit>
   2648 bool GeneralParser<ParseHandler, Unit>::functionArguments(
   2649    YieldHandling yieldHandling, FunctionSyntaxKind kind,
   2650    FunctionNodeType funNode) {
   2651  FunctionBox* funbox = pc_->functionBox();
   2652 
   2653  // Modifier for the following tokens.
   2654  // TokenStream::SlashIsDiv for the following cases:
   2655  //   async a => 1
   2656  //         ^
   2657  //
   2658  //   (a) => 1
   2659  //   ^
   2660  //
   2661  //   async (a) => 1
   2662  //         ^
   2663  //
   2664  //   function f(a) {}
   2665  //             ^
   2666  //
   2667  // TokenStream::SlashIsRegExp for the following case:
   2668  //   a => 1
   2669  //   ^
   2670  Modifier firstTokenModifier =
   2671      kind != FunctionSyntaxKind::Arrow || funbox->isAsync()
   2672          ? TokenStream::SlashIsDiv
   2673          : TokenStream::SlashIsRegExp;
   2674  TokenKind tt;
   2675  if (!tokenStream.getToken(&tt, firstTokenModifier)) {
   2676    return false;
   2677  }
   2678 
   2679  if (kind == FunctionSyntaxKind::Arrow && TokenKindIsPossibleIdentifier(tt)) {
   2680    // Record the start of function source (for FunctionToString).
   2681    setFunctionStartAtCurrentToken(funbox);
   2682 
   2683    ParamsBodyNodeType argsbody;
   2684    MOZ_TRY_VAR_OR_RETURN(argsbody, handler_.newParamsBody(pos()), false);
   2685    handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
   2686 
   2687    TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
   2688    if (!name) {
   2689      return false;
   2690    }
   2691 
   2692    constexpr bool disallowDuplicateParams = true;
   2693    bool duplicatedParam = false;
   2694    if (!notePositionalFormalParameter(funNode, name, pos().begin,
   2695                                       disallowDuplicateParams,
   2696                                       &duplicatedParam)) {
   2697      return false;
   2698    }
   2699    MOZ_ASSERT(!duplicatedParam);
   2700    MOZ_ASSERT(pc_->positionalFormalParameterNames().length() == 1);
   2701 
   2702    funbox->setLength(1);
   2703    funbox->setArgCount(1);
   2704    return true;
   2705  }
   2706 
   2707  if (tt != TokenKind::LeftParen) {
   2708    error(kind == FunctionSyntaxKind::Arrow ? JSMSG_BAD_ARROW_ARGS
   2709                                            : JSMSG_PAREN_BEFORE_FORMAL);
   2710    return false;
   2711  }
   2712 
   2713  // Record the start of function source (for FunctionToString).
   2714  setFunctionStartAtCurrentToken(funbox);
   2715 
   2716  ParamsBodyNodeType argsbody;
   2717  MOZ_TRY_VAR_OR_RETURN(argsbody, handler_.newParamsBody(pos()), false);
   2718  handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
   2719 
   2720  bool matched;
   2721  if (!tokenStream.matchToken(&matched, TokenKind::RightParen,
   2722                              TokenStream::SlashIsRegExp)) {
   2723    return false;
   2724  }
   2725  if (!matched) {
   2726    bool hasRest = false;
   2727    bool hasDefault = false;
   2728    bool duplicatedParam = false;
   2729    bool disallowDuplicateParams =
   2730        kind == FunctionSyntaxKind::Arrow ||
   2731        kind == FunctionSyntaxKind::Method ||
   2732        kind == FunctionSyntaxKind::FieldInitializer ||
   2733        kind == FunctionSyntaxKind::ClassConstructor;
   2734    AtomVector& positionalFormals = pc_->positionalFormalParameterNames();
   2735 
   2736    if (kind == FunctionSyntaxKind::Getter) {
   2737      error(JSMSG_ACCESSOR_WRONG_ARGS, "getter", "no", "s");
   2738      return false;
   2739    }
   2740 
   2741    while (true) {
   2742      if (hasRest) {
   2743        error(JSMSG_PARAMETER_AFTER_REST);
   2744        return false;
   2745      }
   2746 
   2747      TokenKind tt;
   2748      if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
   2749        return false;
   2750      }
   2751 
   2752      if (tt == TokenKind::TripleDot) {
   2753        if (kind == FunctionSyntaxKind::Setter) {
   2754          error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
   2755          return false;
   2756        }
   2757 
   2758        disallowDuplicateParams = true;
   2759        if (duplicatedParam) {
   2760          // Has duplicated args before the rest parameter.
   2761          error(JSMSG_BAD_DUP_ARGS);
   2762          return false;
   2763        }
   2764 
   2765        hasRest = true;
   2766        funbox->setHasRest();
   2767 
   2768        if (!tokenStream.getToken(&tt)) {
   2769          return false;
   2770        }
   2771 
   2772        if (!TokenKindIsPossibleIdentifier(tt) &&
   2773            tt != TokenKind::LeftBracket && tt != TokenKind::LeftCurly) {
   2774          error(JSMSG_NO_REST_NAME);
   2775          return false;
   2776        }
   2777      }
   2778 
   2779      switch (tt) {
   2780        case TokenKind::LeftBracket:
   2781        case TokenKind::LeftCurly: {
   2782          disallowDuplicateParams = true;
   2783          if (duplicatedParam) {
   2784            // Has duplicated args before the destructuring parameter.
   2785            error(JSMSG_BAD_DUP_ARGS);
   2786            return false;
   2787          }
   2788 
   2789          funbox->hasDestructuringArgs = true;
   2790 
   2791          Node destruct;
   2792          MOZ_TRY_VAR_OR_RETURN(
   2793              destruct,
   2794              destructuringDeclarationWithoutYieldOrAwait(
   2795                  DeclarationKind::FormalParameter, yieldHandling, tt),
   2796              false);
   2797 
   2798          if (!noteDestructuredPositionalFormalParameter(funNode, destruct)) {
   2799            return false;
   2800          }
   2801 
   2802          break;
   2803        }
   2804 
   2805        default: {
   2806          if (!TokenKindIsPossibleIdentifier(tt)) {
   2807            error(JSMSG_MISSING_FORMAL);
   2808            return false;
   2809          }
   2810 
   2811          TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
   2812          if (!name) {
   2813            return false;
   2814          }
   2815 
   2816          if (!notePositionalFormalParameter(funNode, name, pos().begin,
   2817                                             disallowDuplicateParams,
   2818                                             &duplicatedParam)) {
   2819            return false;
   2820          }
   2821          if (duplicatedParam) {
   2822            funbox->hasDuplicateParameters = true;
   2823          }
   2824 
   2825          break;
   2826        }
   2827      }
   2828 
   2829      if (positionalFormals.length() >= ARGNO_LIMIT) {
   2830        error(JSMSG_TOO_MANY_FUN_ARGS);
   2831        return false;
   2832      }
   2833 
   2834      bool matched;
   2835      if (!tokenStream.matchToken(&matched, TokenKind::Assign,
   2836                                  TokenStream::SlashIsRegExp)) {
   2837        return false;
   2838      }
   2839      if (matched) {
   2840        if (hasRest) {
   2841          error(JSMSG_REST_WITH_DEFAULT);
   2842          return false;
   2843        }
   2844        disallowDuplicateParams = true;
   2845        if (duplicatedParam) {
   2846          error(JSMSG_BAD_DUP_ARGS);
   2847          return false;
   2848        }
   2849 
   2850        if (!hasDefault) {
   2851          hasDefault = true;
   2852 
   2853          // The Function.length property is the number of formals
   2854          // before the first default argument.
   2855          funbox->setLength(positionalFormals.length() - 1);
   2856        }
   2857        funbox->hasParameterExprs = true;
   2858 
   2859        Node def_expr;
   2860        MOZ_TRY_VAR_OR_RETURN(
   2861            def_expr, assignExprWithoutYieldOrAwait(yieldHandling), false);
   2862        if (!handler_.setLastFunctionFormalParameterDefault(funNode,
   2863                                                            def_expr)) {
   2864          return false;
   2865        }
   2866      }
   2867 
   2868      // Setter syntax uniquely requires exactly one argument.
   2869      if (kind == FunctionSyntaxKind::Setter) {
   2870        break;
   2871      }
   2872 
   2873      if (!tokenStream.matchToken(&matched, TokenKind::Comma,
   2874                                  TokenStream::SlashIsRegExp)) {
   2875        return false;
   2876      }
   2877      if (!matched) {
   2878        break;
   2879      }
   2880 
   2881      if (!hasRest) {
   2882        if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
   2883          return false;
   2884        }
   2885        if (tt == TokenKind::RightParen) {
   2886          break;
   2887        }
   2888      }
   2889    }
   2890 
   2891    TokenKind tt;
   2892    if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
   2893      return false;
   2894    }
   2895    if (tt != TokenKind::RightParen) {
   2896      if (kind == FunctionSyntaxKind::Setter) {
   2897        error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
   2898        return false;
   2899      }
   2900 
   2901      error(JSMSG_PAREN_AFTER_FORMAL);
   2902      return false;
   2903    }
   2904 
   2905    if (!hasDefault) {
   2906      funbox->setLength(positionalFormals.length() - hasRest);
   2907    }
   2908 
   2909    funbox->setArgCount(positionalFormals.length());
   2910  } else if (kind == FunctionSyntaxKind::Setter) {
   2911    error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
   2912    return false;
   2913  }
   2914 
   2915  return true;
   2916 }
   2917 
   2918 template <typename Unit>
   2919 bool Parser<FullParseHandler, Unit>::skipLazyInnerFunction(
   2920    FunctionNode* funNode, uint32_t toStringStart, bool tryAnnexB) {
   2921  // When a lazily-parsed function is called, we only fully parse (and emit)
   2922  // that function, not any of its nested children. The initial syntax-only
   2923  // parse recorded the free variables of nested functions and their extents,
   2924  // so we can skip over them after accounting for their free variables.
   2925 
   2926  MOZ_ASSERT(pc_->isOutermostOfCurrentCompile());
   2927  handler_.nextLazyInnerFunction();
   2928  const ScriptStencil& cachedData = handler_.cachedScriptData();
   2929  const ScriptStencilExtra& cachedExtra = handler_.cachedScriptExtra();
   2930  MOZ_ASSERT(toStringStart == cachedExtra.extent.toStringStart);
   2931 
   2932  FunctionBox* funbox = newFunctionBox(funNode, cachedData, cachedExtra);
   2933  if (!funbox) {
   2934    return false;
   2935  }
   2936 
   2937  ScriptStencil& script = funbox->functionStencil();
   2938  funbox->copyFunctionFields(script);
   2939 
   2940  // If the inner lazy function is class constructor, connect it to the class
   2941  // statement/expression we are parsing.
   2942  if (funbox->isClassConstructor()) {
   2943    auto classStmt =
   2944        pc_->template findInnermostStatement<ParseContext::ClassStatement>();
   2945    MOZ_ASSERT(!classStmt->constructorBox);
   2946    classStmt->constructorBox = funbox;
   2947  }
   2948 
   2949  MOZ_ASSERT_IF(pc_->isFunctionBox(),
   2950                pc_->functionBox()->index() < funbox->index());
   2951 
   2952  PropagateTransitiveParseFlags(funbox, pc_->sc());
   2953 
   2954  if (!tokenStream.advance(funbox->extent().sourceEnd)) {
   2955    return false;
   2956  }
   2957 
   2958  // Append possible Annex B function box only upon successfully parsing.
   2959  if (tryAnnexB &&
   2960      !pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
   2961    return false;
   2962  }
   2963 
   2964  return true;
   2965 }
   2966 
   2967 template <typename Unit>
   2968 bool Parser<SyntaxParseHandler, Unit>::skipLazyInnerFunction(
   2969    FunctionNodeType funNode, uint32_t toStringStart, bool tryAnnexB) {
   2970  MOZ_CRASH("Cannot skip lazy inner functions when syntax parsing");
   2971 }
   2972 
   2973 template <class ParseHandler, typename Unit>
   2974 bool GeneralParser<ParseHandler, Unit>::skipLazyInnerFunction(
   2975    FunctionNodeType funNode, uint32_t toStringStart, bool tryAnnexB) {
   2976  return asFinalParser()->skipLazyInnerFunction(funNode, toStringStart,
   2977                                                tryAnnexB);
   2978 }
   2979 
   2980 template <class ParseHandler, typename Unit>
   2981 bool GeneralParser<ParseHandler, Unit>::addExprAndGetNextTemplStrToken(
   2982    YieldHandling yieldHandling, ListNodeType nodeList, TokenKind* ttp) {
   2983  Node pn;
   2984  MOZ_TRY_VAR_OR_RETURN(pn, expr(InAllowed, yieldHandling, TripledotProhibited),
   2985                        false);
   2986  handler_.addList(nodeList, pn);
   2987 
   2988  TokenKind tt;
   2989  if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
   2990    return false;
   2991  }
   2992  if (tt != TokenKind::RightCurly) {
   2993    error(JSMSG_TEMPLSTR_UNTERM_EXPR);
   2994    return false;
   2995  }
   2996 
   2997  return tokenStream.getTemplateToken(ttp);
   2998 }
   2999 
   3000 template <class ParseHandler, typename Unit>
   3001 bool GeneralParser<ParseHandler, Unit>::taggedTemplate(
   3002    YieldHandling yieldHandling, ListNodeType tagArgsList, TokenKind tt) {
   3003  CallSiteNodeType callSiteObjNode;
   3004  MOZ_TRY_VAR_OR_RETURN(callSiteObjNode,
   3005                        handler_.newCallSiteObject(pos().begin), false);
   3006  handler_.addList(tagArgsList, callSiteObjNode);
   3007 
   3008  pc_->sc()->setHasCallSiteObj();
   3009 
   3010  while (true) {
   3011    if (!appendToCallSiteObj(callSiteObjNode)) {
   3012      return false;
   3013    }
   3014    if (tt != TokenKind::TemplateHead) {
   3015      break;
   3016    }
   3017 
   3018    if (!addExprAndGetNextTemplStrToken(yieldHandling, tagArgsList, &tt)) {
   3019      return false;
   3020    }
   3021  }
   3022  handler_.setEndPosition(tagArgsList, callSiteObjNode);
   3023  return true;
   3024 }
   3025 
   3026 template <class ParseHandler, typename Unit>
   3027 typename ParseHandler::ListNodeResult
   3028 GeneralParser<ParseHandler, Unit>::templateLiteral(
   3029    YieldHandling yieldHandling) {
   3030  NameNodeType literal = MOZ_TRY(noSubstitutionUntaggedTemplate());
   3031 
   3032  ListNodeType nodeList =
   3033      MOZ_TRY(handler_.newList(ParseNodeKind::TemplateStringListExpr, literal));
   3034 
   3035  TokenKind tt;
   3036  do {
   3037    if (!addExprAndGetNextTemplStrToken(yieldHandling, nodeList, &tt)) {
   3038      return errorResult();
   3039    }
   3040 
   3041    literal = MOZ_TRY(noSubstitutionUntaggedTemplate());
   3042 
   3043    handler_.addList(nodeList, literal);
   3044  } while (tt == TokenKind::TemplateHead);
   3045  return nodeList;
   3046 }
   3047 
   3048 template <class ParseHandler, typename Unit>
   3049 typename ParseHandler::FunctionNodeResult
   3050 GeneralParser<ParseHandler, Unit>::functionDefinition(
   3051    FunctionNodeType funNode, uint32_t toStringStart, InHandling inHandling,
   3052    YieldHandling yieldHandling, TaggedParserAtomIndex funName,
   3053    FunctionSyntaxKind kind, GeneratorKind generatorKind,
   3054    FunctionAsyncKind asyncKind, bool tryAnnexB /* = false */) {
   3055  MOZ_ASSERT_IF(kind == FunctionSyntaxKind::Statement, funName);
   3056 
   3057  // If we see any inner function, note it on our current context. The bytecode
   3058  // emitter may eliminate the function later, but we use a conservative
   3059  // definition for consistency between lazy and full parsing.
   3060  pc_->sc()->setHasInnerFunctions();
   3061 
   3062  // When fully parsing a lazy script, we do not fully reparse its inner
   3063  // functions, which are also lazy. Instead, their free variables and source
   3064  // extents are recorded and may be skipped.
   3065  if (handler_.reuseLazyInnerFunctions()) {
   3066    if (!skipLazyInnerFunction(funNode, toStringStart, tryAnnexB)) {
   3067      return errorResult();
   3068    }
   3069 
   3070    return funNode;
   3071  }
   3072 
   3073  bool isSelfHosting = options().selfHostingMode;
   3074  FunctionFlags flags =
   3075      InitialFunctionFlags(kind, generatorKind, asyncKind, isSelfHosting);
   3076 
   3077  // Self-hosted functions with special function names require extended slots
   3078  // for various purposes.
   3079  bool forceExtended =
   3080      isSelfHosting && funName &&
   3081      this->parserAtoms().isExtendedUnclonedSelfHostedFunctionName(funName);
   3082  if (forceExtended) {
   3083    flags.setIsExtended();
   3084  }
   3085 
   3086  // Speculatively parse using the directives of the parent parsing context.
   3087  // If a directive is encountered (e.g., "use strict") that changes how the
   3088  // function should have been parsed, we backup and reparse with the new set
   3089  // of directives.
   3090  Directives directives(pc_);
   3091  Directives newDirectives = directives;
   3092 
   3093  Position start(tokenStream);
   3094  auto startObj = this->compilationState_.getPosition();
   3095 
   3096  // Parse the inner function. The following is a loop as we may attempt to
   3097  // reparse a function due to failed syntax parsing and encountering new
   3098  // "use foo" directives.
   3099  while (true) {
   3100    if (trySyntaxParseInnerFunction(&funNode, funName, flags, toStringStart,
   3101                                    inHandling, yieldHandling, kind,
   3102                                    generatorKind, asyncKind, tryAnnexB,
   3103                                    directives, &newDirectives)) {
   3104      break;
   3105    }
   3106 
   3107    // Return on error.
   3108    if (anyChars.hadError() || directives == newDirectives) {
   3109      return errorResult();
   3110    }
   3111 
   3112    // Assignment must be monotonic to prevent infinitely attempting to
   3113    // reparse.
   3114    MOZ_ASSERT_IF(directives.strict(), newDirectives.strict());
   3115    MOZ_ASSERT_IF(directives.asmJS(), newDirectives.asmJS());
   3116    directives = newDirectives;
   3117 
   3118    // Rewind to retry parsing with new directives applied.
   3119    tokenStream.rewind(start);
   3120    this->compilationState_.rewind(startObj);
   3121 
   3122    // functionFormalParametersAndBody may have already set body before failing.
   3123    handler_.setFunctionFormalParametersAndBody(funNode, null());
   3124  }
   3125 
   3126  return funNode;
   3127 }
   3128 
   3129 template <typename Unit>
   3130 bool Parser<FullParseHandler, Unit>::advancePastSyntaxParsedFunction(
   3131    SyntaxParser* syntaxParser) {
   3132  MOZ_ASSERT(getSyntaxParser() == syntaxParser);
   3133 
   3134  // Advance this parser over tokens processed by the syntax parser.
   3135  Position currentSyntaxPosition(syntaxParser->tokenStream);
   3136  if (!tokenStream.fastForward(currentSyntaxPosition, syntaxParser->anyChars)) {
   3137    return false;
   3138  }
   3139 
   3140  anyChars.adoptState(syntaxParser->anyChars);
   3141  tokenStream.adoptState(syntaxParser->tokenStream);
   3142  return true;
   3143 }
   3144 
   3145 template <typename Unit>
   3146 bool Parser<FullParseHandler, Unit>::trySyntaxParseInnerFunction(
   3147    FunctionNode** funNode, TaggedParserAtomIndex explicitName,
   3148    FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
   3149    YieldHandling yieldHandling, FunctionSyntaxKind kind,
   3150    GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
   3151    Directives inheritedDirectives, Directives* newDirectives) {
   3152  // Try a syntax parse for this inner function.
   3153  do {
   3154    // If we're assuming this function is an IIFE, always perform a full
   3155    // parse to avoid the overhead of a lazy syntax-only parse. Although
   3156    // the prediction may be incorrect, IIFEs are common enough that it
   3157    // pays off for lots of code.
   3158    if ((*funNode)->isLikelyIIFE() &&
   3159        generatorKind == GeneratorKind::NotGenerator &&
   3160        asyncKind == FunctionAsyncKind::SyncFunction) {
   3161      break;
   3162    }
   3163 
   3164    SyntaxParser* syntaxParser = getSyntaxParser();
   3165    if (!syntaxParser) {
   3166      break;
   3167    }
   3168 
   3169    UsedNameTracker::RewindToken token = usedNames_.getRewindToken();
   3170    auto statePosition = this->compilationState_.getPosition();
   3171 
   3172    // Move the syntax parser to the current position in the stream.  In the
   3173    // common case this seeks forward, but it'll also seek backward *at least*
   3174    // when arrow functions appear inside arrow function argument defaults
   3175    // (because we rewind to reparse arrow functions once we're certain they're
   3176    // arrow functions):
   3177    //
   3178    //   var x = (y = z => 2) => q;
   3179    //   //           ^ we first seek to here to syntax-parse this function
   3180    //   //      ^ then we seek back to here to syntax-parse the outer function
   3181    Position currentPosition(tokenStream);
   3182    if (!syntaxParser->tokenStream.seekTo(currentPosition, anyChars)) {
   3183      return false;
   3184    }
   3185 
   3186    // Make a FunctionBox before we enter the syntax parser, because |pn|
   3187    // still expects a FunctionBox to be attached to it during BCE, and
   3188    // the syntax parser cannot attach one to it.
   3189    FunctionBox* funbox =
   3190        newFunctionBox(*funNode, explicitName, flags, toStringStart,
   3191                       inheritedDirectives, generatorKind, asyncKind);
   3192    if (!funbox) {
   3193      return false;
   3194    }
   3195    funbox->initWithEnclosingParseContext(pc_, kind);
   3196 
   3197    auto syntaxNodeResult = syntaxParser->innerFunctionForFunctionBox(
   3198        SyntaxParseHandler::Node::NodeGeneric, pc_, funbox, inHandling,
   3199        yieldHandling, kind, newDirectives);
   3200    if (syntaxNodeResult.isErr()) {
   3201      if (syntaxParser->hadAbortedSyntaxParse()) {
   3202        // Try again with a full parse. UsedNameTracker needs to be
   3203        // rewound to just before we tried the syntax parse for
   3204        // correctness.
   3205        syntaxParser->clearAbortedSyntaxParse();
   3206        usedNames_.rewind(token);
   3207        this->compilationState_.rewind(statePosition);
   3208        MOZ_ASSERT(!fc_->hadErrors());
   3209        break;
   3210      }
   3211      return false;
   3212    }
   3213 
   3214    if (!advancePastSyntaxParsedFunction(syntaxParser)) {
   3215      return false;
   3216    }
   3217 
   3218    // Update the end position of the parse node.
   3219    (*funNode)->pn_pos.end = anyChars.currentToken().pos.end;
   3220 
   3221    // Append possible Annex B function box only upon successfully parsing.
   3222    if (tryAnnexB) {
   3223      if (!pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
   3224        return false;
   3225      }
   3226    }
   3227 
   3228    return true;
   3229  } while (false);
   3230 
   3231  // We failed to do a syntax parse above, so do the full parse.
   3232  FunctionNodeType innerFunc;
   3233  MOZ_TRY_VAR_OR_RETURN(
   3234      innerFunc,
   3235      innerFunction(*funNode, pc_, explicitName, flags, toStringStart,
   3236                    inHandling, yieldHandling, kind, generatorKind, asyncKind,
   3237                    tryAnnexB, inheritedDirectives, newDirectives),
   3238      false);
   3239 
   3240  *funNode = innerFunc;
   3241  return true;
   3242 }
   3243 
   3244 template <typename Unit>
   3245 bool Parser<SyntaxParseHandler, Unit>::trySyntaxParseInnerFunction(
   3246    FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
   3247    FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
   3248    YieldHandling yieldHandling, FunctionSyntaxKind kind,
   3249    GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
   3250    Directives inheritedDirectives, Directives* newDirectives) {
   3251  // This is already a syntax parser, so just parse the inner function.
   3252  FunctionNodeType innerFunc;
   3253  MOZ_TRY_VAR_OR_RETURN(
   3254      innerFunc,
   3255      innerFunction(*funNode, pc_, explicitName, flags, toStringStart,
   3256                    inHandling, yieldHandling, kind, generatorKind, asyncKind,
   3257                    tryAnnexB, inheritedDirectives, newDirectives),
   3258      false);
   3259 
   3260  *funNode = innerFunc;
   3261  return true;
   3262 }
   3263 
   3264 template <class ParseHandler, typename Unit>
   3265 inline bool GeneralParser<ParseHandler, Unit>::trySyntaxParseInnerFunction(
   3266    FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
   3267    FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
   3268    YieldHandling yieldHandling, FunctionSyntaxKind kind,
   3269    GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
   3270    Directives inheritedDirectives, Directives* newDirectives) {
   3271  return asFinalParser()->trySyntaxParseInnerFunction(
   3272      funNode, explicitName, flags, toStringStart, inHandling, yieldHandling,
   3273      kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives,
   3274      newDirectives);
   3275 }
   3276 
   3277 template <class ParseHandler, typename Unit>
   3278 typename ParseHandler::FunctionNodeResult
   3279 GeneralParser<ParseHandler, Unit>::innerFunctionForFunctionBox(
   3280    FunctionNodeType funNode, ParseContext* outerpc, FunctionBox* funbox,
   3281    InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind,
   3282    Directives* newDirectives) {
   3283  // Note that it is possible for outerpc != this->pc_, as we may be
   3284  // attempting to syntax parse an inner function from an outer full
   3285  // parser. In that case, outerpc is a SourceParseContext from the full parser
   3286  // instead of the current top of the stack of the syntax parser.
   3287 
   3288  // Push a new ParseContext.
   3289  SourceParseContext funpc(this, funbox, newDirectives);
   3290  if (!funpc.init()) {
   3291    return errorResult();
   3292  }
   3293 
   3294  if (!functionFormalParametersAndBody(inHandling, yieldHandling, &funNode,
   3295                                       kind)) {
   3296    return errorResult();
   3297  }
   3298 
   3299  if (!leaveInnerFunction(outerpc)) {
   3300    return errorResult();
   3301  }
   3302 
   3303  return funNode;
   3304 }
   3305 
   3306 template <class ParseHandler, typename Unit>
   3307 typename ParseHandler::FunctionNodeResult
   3308 GeneralParser<ParseHandler, Unit>::innerFunction(
   3309    FunctionNodeType funNode, ParseContext* outerpc,
   3310    TaggedParserAtomIndex explicitName, FunctionFlags flags,
   3311    uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling,
   3312    FunctionSyntaxKind kind, GeneratorKind generatorKind,
   3313    FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives,
   3314    Directives* newDirectives) {
   3315  // Note that it is possible for outerpc != this->pc_, as we may be
   3316  // attempting to syntax parse an inner function from an outer full
   3317  // parser. In that case, outerpc is a SourceParseContext from the full parser
   3318  // instead of the current top of the stack of the syntax parser.
   3319 
   3320  FunctionBox* funbox =
   3321      newFunctionBox(funNode, explicitName, flags, toStringStart,
   3322                     inheritedDirectives, generatorKind, asyncKind);
   3323  if (!funbox) {
   3324    return errorResult();
   3325  }
   3326  funbox->initWithEnclosingParseContext(outerpc, kind);
   3327 
   3328  FunctionNodeType innerFunc =
   3329      MOZ_TRY(innerFunctionForFunctionBox(funNode, outerpc, funbox, inHandling,
   3330                                          yieldHandling, kind, newDirectives));
   3331 
   3332  // Append possible Annex B function box only upon successfully parsing.
   3333  if (tryAnnexB) {
   3334    if (!pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
   3335      return errorResult();
   3336    }
   3337  }
   3338 
   3339  return innerFunc;
   3340 }
   3341 
   3342 template <class ParseHandler, typename Unit>
   3343 bool GeneralParser<ParseHandler, Unit>::appendToCallSiteObj(
   3344    CallSiteNodeType callSiteObj) {
   3345  Node cookedNode;
   3346  MOZ_TRY_VAR_OR_RETURN(cookedNode, noSubstitutionTaggedTemplate(), false);
   3347 
   3348  auto atom = tokenStream.getRawTemplateStringAtom();
   3349  if (!atom) {
   3350    return false;
   3351  }
   3352  NameNodeType rawNode;
   3353  MOZ_TRY_VAR_OR_RETURN(rawNode, handler_.newTemplateStringLiteral(atom, pos()),
   3354                        false);
   3355 
   3356  handler_.addToCallSiteObject(callSiteObj, rawNode, cookedNode);
   3357  return true;
   3358 }
   3359 
   3360 template <typename Unit>
   3361 FullParseHandler::FunctionNodeResult
   3362 Parser<FullParseHandler, Unit>::standaloneLazyFunction(
   3363    CompilationInput& input, uint32_t toStringStart, bool strict,
   3364    GeneratorKind generatorKind, FunctionAsyncKind asyncKind) {
   3365  MOZ_ASSERT(checkOptionsCalled_);
   3366 
   3367  FunctionSyntaxKind syntaxKind = input.functionSyntaxKind();
   3368  FunctionNodeType funNode = MOZ_TRY(handler_.newFunction(syntaxKind, pos()));
   3369 
   3370  TaggedParserAtomIndex displayAtom =
   3371      this->getCompilationState().previousParseCache.displayAtom();
   3372 
   3373  Directives directives(strict);
   3374  FunctionBox* funbox =
   3375      newFunctionBox(funNode, displayAtom, input.functionFlags(), toStringStart,
   3376                     directives, generatorKind, asyncKind);
   3377  if (!funbox) {
   3378    return errorResult();
   3379  }
   3380  const ScriptStencilExtra& funExtra =
   3381      this->getCompilationState().previousParseCache.funExtra();
   3382  funbox->initFromLazyFunction(
   3383      funExtra, this->getCompilationState().scopeContext, syntaxKind);
   3384  if (funbox->useMemberInitializers()) {
   3385    funbox->setMemberInitializers(funExtra.memberInitializers());
   3386  }
   3387 
   3388  Directives newDirectives = directives;
   3389  SourceParseContext funpc(this, funbox, &newDirectives);
   3390  if (!funpc.init()) {
   3391    return errorResult();
   3392  }
   3393 
   3394  // Our tokenStream has no current token, so funNode's position is garbage.
   3395  // Substitute the position of the first token in our source.  If the
   3396  // function is a not-async arrow, use TokenStream::SlashIsRegExp to keep
   3397  // verifyConsistentModifier from complaining (we will use
   3398  // TokenStream::SlashIsRegExp in functionArguments).
   3399  Modifier modifier = (input.functionFlags().isArrow() &&
   3400                       asyncKind == FunctionAsyncKind::SyncFunction)
   3401                          ? TokenStream::SlashIsRegExp
   3402                          : TokenStream::SlashIsDiv;
   3403  if (!tokenStream.peekTokenPos(&funNode->pn_pos, modifier)) {
   3404    return errorResult();
   3405  }
   3406 
   3407  YieldHandling yieldHandling = GetYieldHandling(generatorKind);
   3408 
   3409  if (funbox->isSyntheticFunction()) {
   3410    // Currently default class constructors are the only synthetic function that
   3411    // supports delazification.
   3412    MOZ_ASSERT(funbox->isClassConstructor());
   3413    MOZ_ASSERT(funbox->extent().toStringStart == funbox->extent().sourceStart);
   3414 
   3415    HasHeritage hasHeritage = funbox->isDerivedClassConstructor()
   3416                                  ? HasHeritage::Yes
   3417                                  : HasHeritage::No;
   3418    TokenPos synthesizedBodyPos(funbox->extent().toStringStart,
   3419                                funbox->extent().toStringEnd);
   3420 
   3421    // Reset pos() to the `class` keyword for predictable results.
   3422    tokenStream.consumeKnownToken(TokenKind::Class);
   3423 
   3424    if (!this->synthesizeConstructorBody(synthesizedBodyPos, hasHeritage,
   3425                                         funNode, funbox)) {
   3426      return errorResult();
   3427    }
   3428  } else {
   3429    if (!functionFormalParametersAndBody(InAllowed, yieldHandling, &funNode,
   3430                                         syntaxKind)) {
   3431      MOZ_ASSERT(directives == newDirectives);
   3432      return errorResult();
   3433    }
   3434  }
   3435 
   3436  if (!CheckParseTree(this->fc_, alloc_, funNode)) {
   3437    return errorResult();
   3438  }
   3439 
   3440  ParseNode* node = funNode;
   3441  // Don't constant-fold inside "use asm" code, as this could create a parse
   3442  // tree that doesn't type-check as asm.js.
   3443  if (!pc_->useAsmOrInsideUseAsm()) {
   3444    if (!FoldConstants(this->fc_, this->parserAtoms(), this->bigInts(), &node,
   3445                       &handler_)) {
   3446      return errorResult();
   3447    }
   3448  }
   3449  funNode = &node->as<FunctionNode>();
   3450 
   3451  return funNode;
   3452 }
   3453 
   3454 void ParserBase::setFunctionEndFromCurrentToken(FunctionBox* funbox) const {
   3455  if (compilationState_.isInitialStencil()) {
   3456    MOZ_ASSERT(anyChars.currentToken().type != TokenKind::Eof);
   3457    MOZ_ASSERT(anyChars.currentToken().type < TokenKind::Limit);
   3458    funbox->setEnd(anyChars.currentToken().pos.end);
   3459  } else {
   3460    // If we're delazifying an arrow function with expression body and
   3461    // the expression is also a function, we arrive here immediately after
   3462    // skipping the function by Parser::skipLazyInnerFunction.
   3463    //
   3464    //   a => b => c
   3465    //              ^
   3466    //              |
   3467    //              we're here
   3468    //
   3469    // In that case, the current token's type field is either Limit or
   3470    // poisoned.
   3471    // We shouldn't read the value if it's poisoned.
   3472    // See TokenStreamSpecific<Unit, AnyCharsAccess>::advance and
   3473    // mfbt/MemoryChecking.h for more details.
   3474    //
   3475    // Also, in delazification, the FunctionBox should already have the
   3476    // correct extent, and we shouldn't overwrite it here.
   3477    // See ScriptStencil variant of PerHandlerParser::newFunctionBox.
   3478 #if !defined(MOZ_ASAN) && !defined(MOZ_MSAN) && !defined(MOZ_VALGRIND)
   3479    MOZ_ASSERT(anyChars.currentToken().type != TokenKind::Eof);
   3480 #endif
   3481    MOZ_ASSERT(funbox->extent().sourceEnd == anyChars.currentToken().pos.end);
   3482  }
   3483 }
   3484 
   3485 template <class ParseHandler, typename Unit>
   3486 bool GeneralParser<ParseHandler, Unit>::functionFormalParametersAndBody(
   3487    InHandling inHandling, YieldHandling yieldHandling,
   3488    FunctionNodeType* funNode, FunctionSyntaxKind kind,
   3489    const Maybe<uint32_t>& parameterListEnd /* = Nothing() */,
   3490    bool isStandaloneFunction /* = false */) {
   3491  // Given a properly initialized parse context, try to parse an actual
   3492  // function without concern for conversion to strict mode, use of lazy
   3493  // parsing and such.
   3494 
   3495  FunctionBox* funbox = pc_->functionBox();
   3496 
   3497  if (kind == FunctionSyntaxKind::ClassConstructor ||
   3498      kind == FunctionSyntaxKind::DerivedClassConstructor) {
   3499    if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
   3500      return false;
   3501    }
   3502 #ifdef ENABLE_DECORATORS
   3503    if (!noteUsedName(TaggedParserAtomIndex::WellKnown::
   3504                          dot_instanceExtraInitializers_())) {
   3505      return false;
   3506    }
   3507 #endif
   3508  }
   3509 
   3510  // See below for an explanation why arrow function parameters and arrow
   3511  // function bodies are parsed with different yield/await settings.
   3512  {
   3513    AwaitHandling awaitHandling =
   3514        kind == FunctionSyntaxKind::StaticClassBlock ? AwaitIsDisallowed
   3515        : (funbox->isAsync() ||
   3516           (kind == FunctionSyntaxKind::Arrow && awaitIsKeyword()))
   3517            ? AwaitIsKeyword
   3518            : AwaitIsName;
   3519    AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(this, awaitHandling);
   3520    AutoInParametersOfAsyncFunction<ParseHandler, Unit> inParameters(
   3521        this, funbox->isAsync());
   3522    if (!functionArguments(yieldHandling, kind, *funNode)) {
   3523      return false;
   3524    }
   3525  }
   3526 
   3527  Maybe<ParseContext::VarScope> varScope;
   3528  if (funbox->hasParameterExprs) {
   3529    varScope.emplace(this);
   3530    if (!varScope->init(pc_)) {
   3531      return false;
   3532    }
   3533  } else {
   3534    pc_->functionScope().useAsVarScope(pc_);
   3535  }
   3536 
   3537  if (kind == FunctionSyntaxKind::Arrow) {
   3538    TokenKind tt;
   3539    if (!tokenStream.peekTokenSameLine(&tt)) {
   3540      return false;
   3541    }
   3542 
   3543    if (tt == TokenKind::Eol) {
   3544      error(JSMSG_UNEXPECTED_TOKEN,
   3545            "'=>' on the same line after an argument list",
   3546            TokenKindToDesc(tt));
   3547      return false;
   3548    }
   3549    if (tt != TokenKind::Arrow) {
   3550      error(JSMSG_BAD_ARROW_ARGS);
   3551      return false;
   3552    }
   3553    tokenStream.consumeKnownToken(TokenKind::Arrow);
   3554  }
   3555 
   3556  // When parsing something for new Function() we have to make sure to
   3557  // only treat a certain part of the source as a parameter list.
   3558  if (parameterListEnd.isSome() && parameterListEnd.value() != pos().begin) {
   3559    error(JSMSG_UNEXPECTED_PARAMLIST_END);
   3560    return false;
   3561  }
   3562 
   3563  // Parse the function body.
   3564  FunctionBodyType bodyType = StatementListBody;
   3565  TokenKind tt;
   3566  if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
   3567    return false;
   3568  }
   3569  uint32_t openedPos = 0;
   3570  if (tt != TokenKind::LeftCurly) {
   3571    if (kind != FunctionSyntaxKind::Arrow) {
   3572      error(JSMSG_CURLY_BEFORE_BODY);
   3573      return false;
   3574    }
   3575 
   3576    anyChars.ungetToken();
   3577    bodyType = ExpressionBody;
   3578    funbox->setHasExprBody();
   3579  } else {
   3580    openedPos = pos().begin;
   3581  }
   3582 
   3583  // Arrow function parameters inherit yieldHandling from the enclosing
   3584  // context, but the arrow body doesn't. E.g. in |(a = yield) => yield|,
   3585  // |yield| in the parameters is either a name or keyword, depending on
   3586  // whether the arrow function is enclosed in a generator function or not.
   3587  // Whereas the |yield| in the function body is always parsed as a name.
   3588  // The same goes when parsing |await| in arrow functions.
   3589  YieldHandling bodyYieldHandling = GetYieldHandling(pc_->generatorKind());
   3590  AwaitHandling bodyAwaitHandling = GetAwaitHandling(pc_->asyncKind());
   3591  bool inheritedStrict = pc_->sc()->strict();
   3592  LexicalScopeNodeType body;
   3593  {
   3594    AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(this,
   3595                                                          bodyAwaitHandling);
   3596    AutoInParametersOfAsyncFunction<ParseHandler, Unit> inParameters(this,
   3597                                                                     false);
   3598    MOZ_TRY_VAR_OR_RETURN(
   3599        body, functionBody(inHandling, bodyYieldHandling, kind, bodyType),
   3600        false);
   3601  }
   3602 
   3603  // Revalidate the function name when we transitioned to strict mode.
   3604  if ((kind == FunctionSyntaxKind::Statement ||
   3605       kind == FunctionSyntaxKind::Expression) &&
   3606      funbox->explicitName() && !inheritedStrict && pc_->sc()->strict()) {
   3607    MOZ_ASSERT(pc_->sc()->hasExplicitUseStrict(),
   3608               "strict mode should only change when a 'use strict' directive "
   3609               "is present");
   3610 
   3611    auto propertyName = funbox->explicitName();
   3612    YieldHandling nameYieldHandling;
   3613    if (kind == FunctionSyntaxKind::Expression) {
   3614      // Named lambda has binding inside it.
   3615      nameYieldHandling = bodyYieldHandling;
   3616    } else {
   3617      // Otherwise YieldHandling cannot be checked at this point
   3618      // because of different context.
   3619      // It should already be checked before this point.
   3620      nameYieldHandling = YieldIsName;
   3621    }
   3622 
   3623    // We already use the correct await-handling at this point, therefore
   3624    // we don't need call AutoAwaitIsKeyword here.
   3625 
   3626    uint32_t nameOffset = handler_.getFunctionNameOffset(*funNode, anyChars);
   3627    if (!checkBindingIdentifier(propertyName, nameOffset, nameYieldHandling)) {
   3628      return false;
   3629    }
   3630  }
   3631 
   3632  if (bodyType == StatementListBody) {
   3633    // Cannot use mustMatchToken here because of internal compiler error on
   3634    // gcc 6.4.0, with linux 64 SM hazard build.
   3635    TokenKind actual;
   3636    if (!tokenStream.getToken(&actual, TokenStream::SlashIsRegExp)) {
   3637      return false;
   3638    }
   3639    if (actual != TokenKind::RightCurly) {
   3640      reportMissingClosing(JSMSG_CURLY_AFTER_BODY, JSMSG_CURLY_OPENED,
   3641                           openedPos);
   3642      return false;
   3643    }
   3644 
   3645    setFunctionEndFromCurrentToken(funbox);
   3646  } else {
   3647    MOZ_ASSERT(kind == FunctionSyntaxKind::Arrow);
   3648 
   3649    if (anyChars.hadError()) {
   3650      return false;
   3651    }
   3652 
   3653    setFunctionEndFromCurrentToken(funbox);
   3654 
   3655    if (kind == FunctionSyntaxKind::Statement) {
   3656      if (!matchOrInsertSemicolon()) {
   3657        return false;
   3658      }
   3659    }
   3660  }
   3661 
   3662  if (IsMethodDefinitionKind(kind) && pc_->superScopeNeedsHomeObject()) {
   3663    funbox->setNeedsHomeObject();
   3664  }
   3665 
   3666  if (!finishFunction(isStandaloneFunction)) {
   3667    return false;
   3668  }
   3669 
   3670  handler_.setEndPosition(body, pos().begin);
   3671  handler_.setEndPosition(*funNode, pos().end);
   3672  handler_.setFunctionBody(*funNode, body);
   3673 
   3674  return true;
   3675 }
   3676 
   3677 template <class ParseHandler, typename Unit>
   3678 typename ParseHandler::FunctionNodeResult
   3679 GeneralParser<ParseHandler, Unit>::functionStmt(uint32_t toStringStart,
   3680                                                YieldHandling yieldHandling,
   3681                                                DefaultHandling defaultHandling,
   3682                                                FunctionAsyncKind asyncKind) {
   3683  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function));
   3684 
   3685  // In sloppy mode, Annex B.3.2 allows labelled function declarations.
   3686  // Otherwise it's a parse error.
   3687  ParseContext::Statement* declaredInStmt = pc_->innermostStatement();
   3688  if (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
   3689    MOZ_ASSERT(!pc_->sc()->strict(),
   3690               "labeled functions shouldn't be parsed in strict mode");
   3691 
   3692    // Find the innermost non-label statement.  Report an error if it's
   3693    // unbraced: functions can't appear in it.  Otherwise the statement
   3694    // (or its absence) determines the scope the function's bound in.
   3695    while (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
   3696      declaredInStmt = declaredInStmt->enclosing();
   3697    }
   3698 
   3699    if (declaredInStmt && !StatementKindIsBraced(declaredInStmt->kind())) {
   3700      error(JSMSG_SLOPPY_FUNCTION_LABEL);
   3701      return errorResult();
   3702    }
   3703  }
   3704 
   3705  TokenKind tt;
   3706  if (!tokenStream.getToken(&tt)) {
   3707    return errorResult();
   3708  }
   3709 
   3710  GeneratorKind generatorKind = GeneratorKind::NotGenerator;
   3711  if (tt == TokenKind::Mul) {
   3712    generatorKind = GeneratorKind::Generator;
   3713    if (!tokenStream.getToken(&tt)) {
   3714      return errorResult();
   3715    }
   3716  }
   3717 
   3718  TaggedParserAtomIndex name;
   3719  if (TokenKindIsPossibleIdentifier(tt)) {
   3720    name = bindingIdentifier(yieldHandling);
   3721    if (!name) {
   3722      return errorResult();
   3723    }
   3724  } else if (defaultHandling == AllowDefaultName) {
   3725    name = TaggedParserAtomIndex::WellKnown::default_();
   3726    anyChars.ungetToken();
   3727  } else {
   3728    /* Unnamed function expressions are forbidden in statement context. */
   3729    error(JSMSG_UNNAMED_FUNCTION_STMT);
   3730    return errorResult();
   3731  }
   3732 
   3733  // Note the declared name and check for early errors.
   3734  DeclarationKind kind;
   3735  if (declaredInStmt) {
   3736    MOZ_ASSERT(declaredInStmt->kind() != StatementKind::Label);
   3737    MOZ_ASSERT(StatementKindIsBraced(declaredInStmt->kind()));
   3738 
   3739    kind =
   3740        (!pc_->sc()->strict() && generatorKind == GeneratorKind::NotGenerator &&
   3741         asyncKind == FunctionAsyncKind::SyncFunction)
   3742            ? DeclarationKind::SloppyLexicalFunction
   3743            : DeclarationKind::LexicalFunction;
   3744  } else {
   3745    kind = pc_->atModuleLevel() ? DeclarationKind::ModuleBodyLevelFunction
   3746                                : DeclarationKind::BodyLevelFunction;
   3747  }
   3748 
   3749  if (!noteDeclaredName(name, kind, pos())) {
   3750    return errorResult();
   3751  }
   3752 
   3753  FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Statement;
   3754  FunctionNodeType funNode = MOZ_TRY(handler_.newFunction(syntaxKind, pos()));
   3755 
   3756  // Under sloppy mode, try Annex B.3.3 semantics. If making an additional
   3757  // 'var' binding of the same name does not throw an early error, do so.
   3758  // This 'var' binding would be assigned the function object when its
   3759  // declaration is reached, not at the start of the block.
   3760  //
   3761  // This semantics is implemented upon Scope exit in
   3762  // Scope::propagateAndMarkAnnexBFunctionBoxes.
   3763  bool tryAnnexB = kind == DeclarationKind::SloppyLexicalFunction;
   3764 
   3765  YieldHandling newYieldHandling = GetYieldHandling(generatorKind);
   3766  return functionDefinition(funNode, toStringStart, InAllowed, newYieldHandling,
   3767                            name, syntaxKind, generatorKind, asyncKind,
   3768                            tryAnnexB);
   3769 }
   3770 
   3771 template <class ParseHandler, typename Unit>
   3772 typename ParseHandler::FunctionNodeResult
   3773 GeneralParser<ParseHandler, Unit>::functionExpr(uint32_t toStringStart,
   3774                                                InvokedPrediction invoked,
   3775                                                FunctionAsyncKind asyncKind) {
   3776  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function));
   3777 
   3778  AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(
   3779      this, GetAwaitHandling(asyncKind));
   3780  GeneratorKind generatorKind = GeneratorKind::NotGenerator;
   3781  TokenKind tt;
   3782  if (!tokenStream.getToken(&tt)) {
   3783    return errorResult();
   3784  }
   3785 
   3786  if (tt == TokenKind::Mul) {
   3787    generatorKind = GeneratorKind::Generator;
   3788    if (!tokenStream.getToken(&tt)) {
   3789      return errorResult();
   3790    }
   3791  }
   3792 
   3793  YieldHandling yieldHandling = GetYieldHandling(generatorKind);
   3794 
   3795  TaggedParserAtomIndex name;
   3796  if (TokenKindIsPossibleIdentifier(tt)) {
   3797    name = bindingIdentifier(yieldHandling);
   3798    if (!name) {
   3799      return errorResult();
   3800    }
   3801  } else {
   3802    anyChars.ungetToken();
   3803  }
   3804 
   3805  FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Expression;
   3806  FunctionNodeType funNode = MOZ_TRY(handler_.newFunction(syntaxKind, pos()));
   3807 
   3808  if (invoked) {
   3809    funNode = handler_.setLikelyIIFE(funNode);
   3810  }
   3811 
   3812  return functionDefinition(funNode, toStringStart, InAllowed, yieldHandling,
   3813                            name, syntaxKind, generatorKind, asyncKind);
   3814 }
   3815 
   3816 /*
   3817 * Return true if this node, known to be an unparenthesized string literal
   3818 * that never contain escape sequences, could be the string of a directive in a
   3819 * Directive Prologue. Directive strings never contain escape sequences or line
   3820 * continuations.
   3821 */
   3822 static inline bool IsUseStrictDirective(const TokenPos& pos,
   3823                                        TaggedParserAtomIndex atom) {
   3824  // the length of "use strict", including quotation.
   3825  static constexpr size_t useStrictLength = 12;
   3826  return atom == TaggedParserAtomIndex::WellKnown::use_strict_() &&
   3827         pos.begin + useStrictLength == pos.end;
   3828 }
   3829 static inline bool IsUseAsmDirective(const TokenPos& pos,
   3830                                     TaggedParserAtomIndex atom) {
   3831  // the length of "use asm", including quotation.
   3832  static constexpr size_t useAsmLength = 9;
   3833  return atom == TaggedParserAtomIndex::WellKnown::use_asm_() &&
   3834         pos.begin + useAsmLength == pos.end;
   3835 }
   3836 
   3837 template <typename Unit>
   3838 bool Parser<SyntaxParseHandler, Unit>::asmJS(TokenPos directivePos,
   3839                                             ListNodeType list) {
   3840  // While asm.js could technically be validated and compiled during syntax
   3841  // parsing, we have no guarantee that some later JS wouldn't abort the
   3842  // syntax parse and cause us to re-parse (and re-compile) the asm.js module.
   3843  // For simplicity, unconditionally abort the syntax parse when "use asm" is
   3844  // encountered so that asm.js is always validated/compiled exactly once
   3845  // during a full parse.
   3846  MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
   3847  return false;
   3848 }
   3849 
   3850 template <typename Unit>
   3851 bool Parser<FullParseHandler, Unit>::asmJS(TokenPos directivePos,
   3852                                           ListNodeType list) {
   3853  // Disable syntax parsing in anything nested inside the asm.js module.
   3854  disableSyntaxParser();
   3855 
   3856  // We should be encountering the "use asm" directive for the first time; if
   3857  // the directive is already, we must have failed asm.js validation and we're
   3858  // reparsing. In that case, don't try to validate again. A non-null
   3859  // newDirectives means we're not in a normal function.
   3860  if (!pc_->newDirectives || pc_->newDirectives->asmJS()) {
   3861    return true;
   3862  }
   3863 
   3864  // If there is no ScriptSource, then we are doing a non-compiling parse and
   3865  // so we shouldn't (and can't, without a ScriptSource) compile.
   3866  if (ss == nullptr) {
   3867    return true;
   3868  }
   3869 
   3870  // Mark this function as being in a "use asm" directive.
   3871  if (!pc_->functionBox()->setUseAsm()) {
   3872    return false;
   3873  }
   3874 
   3875  // Attempt to validate and compile this asm.js module. On success, the
   3876  // tokenStream has been advanced to the closing }. On failure, the
   3877  // tokenStream is in an indeterminate state and we must reparse the
   3878  // function from the beginning. Reparsing is triggered by marking that a
   3879  // new directive has been encountered and returning 'false'.
   3880  bool validated;
   3881  if (!CompileAsmJS(this->fc_, this->parserAtoms(), *this, list, &validated)) {
   3882    return false;
   3883  }
   3884 
   3885  // Warn about asm.js deprecation even if we failed validation. Do this after
   3886  // compilation so that this warning is the last one we emit. This makes
   3887  // testing in asm.js/disabled-warning.js easier.
   3888  if (!js::SupportDifferentialTesting() &&
   3889      JS::Prefs::warn_asmjs_deprecation()) {
   3890    if (!warningAt(directivePos.begin, JSMSG_USE_ASM_DEPRECATED)) {
   3891      return false;
   3892    }
   3893  }
   3894 
   3895  // If we failed validation, trigger a reparse. See above.
   3896  if (!validated) {
   3897    pc_->newDirectives->setAsmJS();
   3898    return false;
   3899  }
   3900 
   3901  return true;
   3902 }
   3903 
   3904 template <class ParseHandler, typename Unit>
   3905 inline bool GeneralParser<ParseHandler, Unit>::asmJS(TokenPos directivePos,
   3906                                                     ListNodeType list) {
   3907  return asFinalParser()->asmJS(directivePos, list);
   3908 }
   3909 
   3910 /*
   3911 * Recognize Directive Prologue members and directives. Assuming |pn| is a
   3912 * candidate for membership in a directive prologue, recognize directives and
   3913 * set |pc_|'s flags accordingly. If |pn| is indeed part of a prologue, set its
   3914 * |prologue| flag.
   3915 *
   3916 * Note that the following is a strict mode function:
   3917 *
   3918 * function foo() {
   3919 *   "blah" // inserted semi colon
   3920 *        "blurgh"
   3921 *   "use\x20loose"
   3922 *   "use strict"
   3923 * }
   3924 *
   3925 * That is, even though "use\x20loose" can never be a directive, now or in the
   3926 * future (because of the hex escape), the Directive Prologue extends through it
   3927 * to the "use strict" statement, which is indeed a directive.
   3928 */
   3929 template <class ParseHandler, typename Unit>
   3930 bool GeneralParser<ParseHandler, Unit>::maybeParseDirective(
   3931    ListNodeType list, Node possibleDirective, bool* cont) {
   3932  TokenPos directivePos;
   3933  TaggedParserAtomIndex directive =
   3934      handler_.isStringExprStatement(possibleDirective, &directivePos);
   3935 
   3936  *cont = !!directive;
   3937  if (!*cont) {
   3938    return true;
   3939  }
   3940 
   3941  if (IsUseStrictDirective(directivePos, directive)) {
   3942    // Functions with non-simple parameter lists (destructuring,
   3943    // default or rest parameters) must not contain a "use strict"
   3944    // directive.
   3945    if (pc_->isFunctionBox()) {
   3946      FunctionBox* funbox = pc_->functionBox();
   3947      if (!funbox->hasSimpleParameterList()) {
   3948        const char* parameterKind = funbox->hasDestructuringArgs
   3949                                        ? "destructuring"
   3950                                    : funbox->hasParameterExprs ? "default"
   3951                                                                : "rest";
   3952        errorAt(directivePos.begin, JSMSG_STRICT_NON_SIMPLE_PARAMS,
   3953                parameterKind);
   3954        return false;
   3955      }
   3956    }
   3957 
   3958    // We're going to be in strict mode. Note that this scope explicitly
   3959    // had "use strict";
   3960    pc_->sc()->setExplicitUseStrict();
   3961    if (!pc_->sc()->strict()) {
   3962      // Some strict mode violations can appear before a Use Strict Directive
   3963      // is applied.  (See the |DeprecatedContent| enum initializers.)  These
   3964      // violations can manifest in two ways.
   3965      //
   3966      // First, the violation can appear *before* the Use Strict Directive.
   3967      // Numeric literals (and therefore octal literals) can only precede a
   3968      // Use Strict Directive if this function's parameter list is not simple,
   3969      // but we reported an error for non-simple parameter lists above, so
   3970      // octal literals present no issue.  But octal escapes and \8 and \9 can
   3971      // appear in the directive prologue before a Use Strict Directive:
   3972      //
   3973      //   function f()
   3974      //   {
   3975      //     "hell\157 world";  // octal escape
   3976      //     "\8"; "\9";        // NonOctalDecimalEscape
   3977      //     "use strict";      // retroactively makes all the above errors
   3978      //   }
   3979      //
   3980      // Second, the violation can appear *after* the Use Strict Directive but
   3981      // *before* the directive is recognized as terminated.  This only
   3982      // happens when a directive is terminated by ASI, and the next token
   3983      // contains a violation:
   3984      //
   3985      //   function a()
   3986      //   {
   3987      //     "use strict"  // ASI
   3988      //     0755;
   3989      //   }
   3990      //   function b()
   3991      //   {
   3992      //     "use strict"  // ASI
   3993      //     "hell\157 world";
   3994      //   }
   3995      //   function c()
   3996      //   {
   3997      //     "use strict"  // ASI
   3998      //     "\8";
   3999      //   }
   4000      //
   4001      // We note such violations when tokenizing.  Then, if a violation has
   4002      // been observed at the time a "use strict" is applied, we report the
   4003      // error.
   4004      switch (anyChars.sawDeprecatedContent()) {
   4005        case DeprecatedContent::None:
   4006          break;
   4007        case DeprecatedContent::OctalLiteral:
   4008          error(JSMSG_DEPRECATED_OCTAL_LITERAL);
   4009          return false;
   4010        case DeprecatedContent::OctalEscape:
   4011          error(JSMSG_DEPRECATED_OCTAL_ESCAPE);
   4012          return false;
   4013        case DeprecatedContent::EightOrNineEscape:
   4014          error(JSMSG_DEPRECATED_EIGHT_OR_NINE_ESCAPE);
   4015          return false;
   4016      }
   4017 
   4018      pc_->sc()->setStrictScript();
   4019    }
   4020  } else if (IsUseAsmDirective(directivePos, directive)) {
   4021    if (pc_->isFunctionBox()) {
   4022      return asmJS(directivePos, list);
   4023    }
   4024    return warningAt(directivePos.begin, JSMSG_USE_ASM_DIRECTIVE_FAIL);
   4025  }
   4026  return true;
   4027 }
   4028 
   4029 template <class ParseHandler, typename Unit>
   4030 typename ParseHandler::ListNodeResult
   4031 GeneralParser<ParseHandler, Unit>::statementList(YieldHandling yieldHandling) {
   4032  AutoCheckRecursionLimit recursion(this->fc_);
   4033  if (!recursion.check(this->fc_)) {
   4034    return errorResult();
   4035  }
   4036 
   4037  ListNodeType stmtList = MOZ_TRY(handler_.newStatementList(pos()));
   4038 
   4039  bool canHaveDirectives = pc_->atBodyLevel();
   4040  if (canHaveDirectives) {
   4041    // Clear flags for deprecated content that might have been seen in an
   4042    // enclosing context.
   4043    anyChars.clearSawDeprecatedContent();
   4044  }
   4045 
   4046  bool canHaveHashbangComment = pc_->atTopLevel();
   4047  if (canHaveHashbangComment) {
   4048    tokenStream.consumeOptionalHashbangComment();
   4049  }
   4050 
   4051  bool afterReturn = false;
   4052  bool warnedAboutStatementsAfterReturn = false;
   4053  uint32_t statementBegin = 0;
   4054  for (;;) {
   4055    TokenKind tt = TokenKind::Eof;
   4056    if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
   4057      if (anyChars.isEOF()) {
   4058        isUnexpectedEOF_ = true;
   4059      }
   4060      return errorResult();
   4061    }
   4062    if (tt == TokenKind::Eof || tt == TokenKind::RightCurly) {
   4063      TokenPos pos;
   4064      if (!tokenStream.peekTokenPos(&pos, TokenStream::SlashIsRegExp)) {
   4065        return errorResult();
   4066      }
   4067      handler_.setListEndPosition(stmtList, pos);
   4068      break;
   4069    }
   4070    if (afterReturn) {
   4071      if (!tokenStream.peekOffset(&statementBegin,
   4072                                  TokenStream::SlashIsRegExp)) {
   4073        return errorResult();
   4074      }
   4075    }
   4076    auto nextResult = statementListItem(yieldHandling, canHaveDirectives);
   4077    if (nextResult.isErr()) {
   4078      if (anyChars.isEOF()) {
   4079        isUnexpectedEOF_ = true;
   4080      }
   4081      return errorResult();
   4082    }
   4083    Node next = nextResult.unwrap();
   4084    if (!warnedAboutStatementsAfterReturn) {
   4085      if (afterReturn) {
   4086        if (!handler_.isStatementPermittedAfterReturnStatement(next)) {
   4087          if (!warningAt(statementBegin, JSMSG_STMT_AFTER_RETURN)) {
   4088            return errorResult();
   4089          }
   4090 
   4091          warnedAboutStatementsAfterReturn = true;
   4092        }
   4093      } else if (handler_.isReturnStatement(next)) {
   4094        afterReturn = true;
   4095      }
   4096    }
   4097 
   4098    if (canHaveDirectives) {
   4099      if (!maybeParseDirective(stmtList, next, &canHaveDirectives)) {
   4100        return errorResult();
   4101      }
   4102    }
   4103 
   4104    handler_.addStatementToList(stmtList, next);
   4105  }
   4106 
   4107  return stmtList;
   4108 }
   4109 
   4110 template <class ParseHandler, typename Unit>
   4111 typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::condition(
   4112    InHandling inHandling, YieldHandling yieldHandling) {
   4113  if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_COND)) {
   4114    return errorResult();
   4115  }
   4116 
   4117  Node pn =
   4118      MOZ_TRY(exprInParens(inHandling, yieldHandling, TripledotProhibited));
   4119 
   4120  if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_COND)) {
   4121    return errorResult();
   4122  }
   4123 
   4124  return pn;
   4125 }
   4126 
   4127 template <class ParseHandler, typename Unit>
   4128 bool GeneralParser<ParseHandler, Unit>::matchLabel(
   4129    YieldHandling yieldHandling, TaggedParserAtomIndex* labelOut) {
   4130  MOZ_ASSERT(labelOut != nullptr);
   4131  TokenKind tt = TokenKind::Eof;
   4132  if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
   4133    return false;
   4134  }
   4135 
   4136  if (TokenKindIsPossibleIdentifier(tt)) {
   4137    tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
   4138 
   4139    *labelOut = labelIdentifier(yieldHandling);
   4140    if (!*labelOut) {
   4141      return false;
   4142    }
   4143  } else {
   4144    *labelOut = TaggedParserAtomIndex::null();
   4145  }
   4146  return true;
   4147 }
   4148 
   4149 template <class ParseHandler, typename Unit>
   4150 GeneralParser<ParseHandler, Unit>::PossibleError::PossibleError(
   4151    GeneralParser<ParseHandler, Unit>& parser)
   4152    : parser_(parser) {}
   4153 
   4154 template <class ParseHandler, typename Unit>
   4155 typename GeneralParser<ParseHandler, Unit>::PossibleError::Error&
   4156 GeneralParser<ParseHandler, Unit>::PossibleError::error(ErrorKind kind) {
   4157  if (kind == ErrorKind::Expression) {
   4158    return exprError_;
   4159  }
   4160  if (kind == ErrorKind::Destructuring) {
   4161    return destructuringError_;
   4162  }
   4163  MOZ_ASSERT(kind == ErrorKind::DestructuringWarning);
   4164  return destructuringWarning_;
   4165 }
   4166 
   4167 template <class ParseHandler, typename Unit>
   4168 void GeneralParser<ParseHandler, Unit>::PossibleError::setResolved(
   4169    ErrorKind kind) {
   4170  error(kind).state_ = ErrorState::None;
   4171 }
   4172 
   4173 template <class ParseHandler, typename Unit>
   4174 bool GeneralParser<ParseHandler, Unit>::PossibleError::hasError(
   4175    ErrorKind kind) {
   4176  return error(kind).state_ == ErrorState::Pending;
   4177 }
   4178 
   4179 template <class ParseHandler, typename Unit>
   4180 bool GeneralParser<ParseHandler,
   4181                   Unit>::PossibleError::hasPendingDestructuringError() {
   4182  return hasError(ErrorKind::Destructuring);
   4183 }
   4184 
   4185 template <class ParseHandler, typename Unit>
   4186 void GeneralParser<ParseHandler, Unit>::PossibleError::setPending(
   4187    ErrorKind kind, const TokenPos& pos, unsigned errorNumber) {
   4188  // Don't overwrite a previously recorded error.
   4189  if (hasError(kind)) {
   4190    return;
   4191  }
   4192 
   4193  // If we report an error later, we'll do it from the position where we set
   4194  // the state to pending.
   4195  Error& err = error(kind);
   4196  err.offset_ = pos.begin;
   4197  err.errorNumber_ = errorNumber;
   4198  err.state_ = ErrorState::Pending;
   4199 }
   4200 
   4201 template <class ParseHandler, typename Unit>
   4202 void GeneralParser<ParseHandler, Unit>::PossibleError::
   4203    setPendingDestructuringErrorAt(const TokenPos& pos, unsigned errorNumber) {
   4204  setPending(ErrorKind::Destructuring, pos, errorNumber);
   4205 }
   4206 
   4207 template <class ParseHandler, typename Unit>
   4208 void GeneralParser<ParseHandler, Unit>::PossibleError::
   4209    setPendingDestructuringWarningAt(const TokenPos& pos,
   4210                                     unsigned errorNumber) {
   4211  setPending(ErrorKind::DestructuringWarning, pos, errorNumber);
   4212 }
   4213 
   4214 template <class ParseHandler, typename Unit>
   4215 void GeneralParser<ParseHandler, Unit>::PossibleError::
   4216    setPendingExpressionErrorAt(const TokenPos& pos, unsigned errorNumber) {
   4217  setPending(ErrorKind::Expression, pos, errorNumber);
   4218 }
   4219 
   4220 template <class ParseHandler, typename Unit>
   4221 bool GeneralParser<ParseHandler, Unit>::PossibleError::checkForError(
   4222    ErrorKind kind) {
   4223  if (!hasError(kind)) {
   4224    return true;
   4225  }
   4226 
   4227  Error& err = error(kind);
   4228  parser_.errorAt(err.offset_, err.errorNumber_);
   4229  return false;
   4230 }
   4231 
   4232 template <class ParseHandler, typename Unit>
   4233 bool GeneralParser<ParseHandler,
   4234                   Unit>::PossibleError::checkForDestructuringErrorOrWarning() {
   4235  // Clear pending expression error, because we're definitely not in an
   4236  // expression context.
   4237  setResolved(ErrorKind::Expression);
   4238 
   4239  // Report any pending destructuring error.
   4240  return checkForError(ErrorKind::Destructuring);
   4241 }
   4242 
   4243 template <class ParseHandler, typename Unit>
   4244 bool GeneralParser<ParseHandler,
   4245                   Unit>::PossibleError::checkForExpressionError() {
   4246  // Clear pending destructuring error, because we're definitely not
   4247  // in a destructuring context.
   4248  setResolved(ErrorKind::Destructuring);
   4249  setResolved(ErrorKind::DestructuringWarning);
   4250 
   4251  // Report any pending expression error.
   4252  return checkForError(ErrorKind::Expression);
   4253 }
   4254 
   4255 template <class ParseHandler, typename Unit>
   4256 void GeneralParser<ParseHandler, Unit>::PossibleError::transferErrorTo(
   4257    ErrorKind kind, PossibleError* other) {
   4258  if (hasError(kind) && !other->hasError(kind)) {
   4259    Error& err = error(kind);
   4260    Error& otherErr = other->error(kind);
   4261    otherErr.offset_ = err.offset_;
   4262    otherErr.errorNumber_ = err.errorNumber_;
   4263    otherErr.state_ = err.state_;
   4264  }
   4265 }
   4266 
   4267 template <class ParseHandler, typename Unit>
   4268 void GeneralParser<ParseHandler, Unit>::PossibleError::transferErrorsTo(
   4269    PossibleError* other) {
   4270  MOZ_ASSERT(other);
   4271  MOZ_ASSERT(this != other);
   4272  MOZ_ASSERT(&parser_ == &other->parser_,
   4273             "Can't transfer fields to an instance which belongs to a "
   4274             "different parser");
   4275 
   4276  transferErrorTo(ErrorKind::Destructuring, other);
   4277  transferErrorTo(ErrorKind::Expression, other);
   4278 }
   4279 
   4280 template <class ParseHandler, typename Unit>
   4281 typename ParseHandler::BinaryNodeResult
   4282 GeneralParser<ParseHandler, Unit>::bindingInitializer(
   4283    Node lhs, DeclarationKind kind, YieldHandling yieldHandling) {
   4284  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Assign));
   4285 
   4286  if (kind == DeclarationKind::FormalParameter) {
   4287    pc_->functionBox()->hasParameterExprs = true;
   4288  }
   4289 
   4290  Node rhs = MOZ_TRY(assignExpr(InAllowed, yieldHandling, TripledotProhibited));
   4291 
   4292  BinaryNodeType assign =
   4293      MOZ_TRY(handler_.newAssignment(ParseNodeKind::AssignExpr, lhs, rhs));
   4294 
   4295  return assign;
   4296 }
   4297 
   4298 template <class ParseHandler, typename Unit>
   4299 typename ParseHandler::NameNodeResult
   4300 GeneralParser<ParseHandler, Unit>::bindingIdentifier(
   4301    DeclarationKind kind, YieldHandling yieldHandling) {
   4302  TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
   4303  if (!name) {
   4304    return errorResult();
   4305  }
   4306 
   4307  NameNodeType binding = MOZ_TRY(newName(name));
   4308  if (!noteDeclaredName(name, kind, pos())) {
   4309    return errorResult();
   4310  }
   4311 
   4312  return binding;
   4313 }
   4314 
   4315 template <class ParseHandler, typename Unit>
   4316 typename ParseHandler::NodeResult
   4317 GeneralParser<ParseHandler, Unit>::bindingIdentifierOrPattern(
   4318    DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
   4319  if (tt == TokenKind::LeftBracket) {
   4320    return arrayBindingPattern(kind, yieldHandling);
   4321  }
   4322 
   4323  if (tt == TokenKind::LeftCurly) {
   4324    return objectBindingPattern(kind, yieldHandling);
   4325  }
   4326 
   4327  if (!TokenKindIsPossibleIdentifierName(tt)) {
   4328    error(JSMSG_NO_VARIABLE_NAME, TokenKindToDesc(tt));
   4329    return errorResult();
   4330  }
   4331 
   4332  return bindingIdentifier(kind, yieldHandling);
   4333 }
   4334 
   4335 template <class ParseHandler, typename Unit>
   4336 typename ParseHandler::ListNodeResult
   4337 GeneralParser<ParseHandler, Unit>::objectBindingPattern(
   4338    DeclarationKind kind, YieldHandling yieldHandling) {
   4339  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftCurly));
   4340 
   4341  AutoCheckRecursionLimit recursion(this->fc_);
   4342  if (!recursion.check(this->fc_)) {
   4343    return errorResult();
   4344  }
   4345 
   4346  uint32_t begin = pos().begin;
   4347  ListNodeType literal = MOZ_TRY(handler_.newObjectLiteral(begin));
   4348 
   4349  Maybe<DeclarationKind> declKind = Some(kind);
   4350  TaggedParserAtomIndex propAtom;
   4351  for (;;) {
   4352    TokenKind tt;
   4353    if (!tokenStream.peekToken(&tt)) {
   4354      return errorResult();
   4355    }
   4356    if (tt == TokenKind::RightCurly) {
   4357      break;
   4358    }
   4359 
   4360    if (tt == TokenKind::TripleDot) {
   4361      tokenStream.consumeKnownToken(TokenKind::TripleDot);
   4362      uint32_t begin = pos().begin;
   4363 
   4364      TokenKind tt;
   4365      if (!tokenStream.getToken(&tt)) {
   4366        return errorResult();
   4367      }
   4368 
   4369      if (!TokenKindIsPossibleIdentifierName(tt)) {
   4370        error(JSMSG_NO_VARIABLE_NAME, TokenKindToDesc(tt));
   4371        return errorResult();
   4372      }
   4373 
   4374      NameNodeType inner = MOZ_TRY(bindingIdentifier(kind, yieldHandling));
   4375 
   4376      if (!handler_.addSpreadProperty(literal, begin, inner)) {
   4377        return errorResult();
   4378      }
   4379    } else {
   4380      TokenPos namePos = anyChars.nextToken().pos;
   4381 
   4382      PropertyType propType;
   4383      Node propName = MOZ_TRY(
   4384          propertyOrMethodName(yieldHandling, PropertyNameInPattern, declKind,
   4385                               literal, &propType, &propAtom));
   4386 
   4387      if (propType == PropertyType::Normal) {
   4388        // Handle e.g., |var {p: x} = o| and |var {p: x=0} = o|.
   4389 
   4390        if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
   4391          return errorResult();
   4392        }
   4393 
   4394        Node binding =
   4395            MOZ_TRY(bindingIdentifierOrPattern(kind, yieldHandling, tt));
   4396 
   4397        bool hasInitializer;
   4398        if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
   4399                                    TokenStream::SlashIsRegExp)) {
   4400          return errorResult();
   4401        }
   4402 
   4403        Node bindingExpr;
   4404        if (hasInitializer) {
   4405          bindingExpr =
   4406              MOZ_TRY(bindingInitializer(binding, kind, yieldHandling));
   4407        } else {
   4408          bindingExpr = binding;
   4409        }
   4410 
   4411        if (!handler_.addPropertyDefinition(literal, propName, bindingExpr)) {
   4412          return errorResult();
   4413        }
   4414      } else if (propType == PropertyType::Shorthand) {
   4415        // Handle e.g., |var {x, y} = o| as destructuring shorthand
   4416        // for |var {x: x, y: y} = o|.
   4417        MOZ_ASSERT(TokenKindIsPossibleIdentifierName(tt));
   4418 
   4419        NameNodeType binding = MOZ_TRY(bindingIdentifier(kind, yieldHandling));
   4420 
   4421        if (!handler_.addShorthand(literal, handler_.asNameNode(propName),
   4422                                   binding)) {
   4423          return errorResult();
   4424        }
   4425      } else if (propType == PropertyType::CoverInitializedName) {
   4426        // Handle e.g., |var {x=1, y=2} = o| as destructuring
   4427        // shorthand with default values.
   4428        MOZ_ASSERT(TokenKindIsPossibleIdentifierName(tt));
   4429 
   4430        NameNodeType binding = MOZ_TRY(bindingIdentifier(kind, yieldHandling));
   4431 
   4432        tokenStream.consumeKnownToken(TokenKind::Assign);
   4433 
   4434        BinaryNodeType bindingExpr =
   4435            MOZ_TRY(bindingInitializer(binding, kind, yieldHandling));
   4436 
   4437        if (!handler_.addPropertyDefinition(literal, propName, bindingExpr)) {
   4438          return errorResult();
   4439        }
   4440      } else {
   4441        errorAt(namePos.begin, JSMSG_NO_VARIABLE_NAME, TokenKindToDesc(tt));
   4442        return errorResult();
   4443      }
   4444    }
   4445 
   4446    bool matched;
   4447    if (!tokenStream.matchToken(&matched, TokenKind::Comma,
   4448                                TokenStream::SlashIsInvalid)) {
   4449      return errorResult();
   4450    }
   4451    if (!matched) {
   4452      break;
   4453    }
   4454    if (tt == TokenKind::TripleDot) {
   4455      error(JSMSG_REST_WITH_COMMA);
   4456      return errorResult();
   4457    }
   4458  }
   4459 
   4460  if (!mustMatchToken(TokenKind::RightCurly, [this, begin](TokenKind actual) {
   4461        this->reportMissingClosing(JSMSG_CURLY_AFTER_LIST, JSMSG_CURLY_OPENED,
   4462                                   begin);
   4463      })) {
   4464    return errorResult();
   4465  }
   4466 
   4467  handler_.setEndPosition(literal, pos().end);
   4468  return literal;
   4469 }
   4470 
   4471 template <class ParseHandler, typename Unit>
   4472 typename ParseHandler::ListNodeResult
   4473 GeneralParser<ParseHandler, Unit>::arrayBindingPattern(
   4474    DeclarationKind kind, YieldHandling yieldHandling) {
   4475  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftBracket));
   4476 
   4477  AutoCheckRecursionLimit recursion(this->fc_);
   4478  if (!recursion.check(this->fc_)) {
   4479    return errorResult();
   4480  }
   4481 
   4482  uint32_t begin = pos().begin;
   4483  ListNodeType literal = MOZ_TRY(handler_.newArrayLiteral(begin));
   4484 
   4485  uint32_t index = 0;
   4486  for (;; index++) {
   4487    if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
   4488      error(JSMSG_ARRAY_INIT_TOO_BIG);
   4489      return errorResult();
   4490    }
   4491 
   4492    TokenKind tt;
   4493    if (!tokenStream.getToken(&tt)) {
   4494      return errorResult();
   4495    }
   4496 
   4497    if (tt == TokenKind::RightBracket) {
   4498      anyChars.ungetToken();
   4499      break;
   4500    }
   4501 
   4502    if (tt == TokenKind::Comma) {
   4503      if (!handler_.addElision(literal, pos())) {
   4504        return errorResult();
   4505      }
   4506    } else if (tt == TokenKind::TripleDot) {
   4507      uint32_t begin = pos().begin;
   4508 
   4509      TokenKind tt;
   4510      if (!tokenStream.getToken(&tt)) {
   4511        return errorResult();
   4512      }
   4513 
   4514      Node inner = MOZ_TRY(bindingIdentifierOrPattern(kind, yieldHandling, tt));
   4515 
   4516      if (!handler_.addSpreadElement(literal, begin, inner)) {
   4517        return errorResult();
   4518      }
   4519    } else {
   4520      Node binding =
   4521          MOZ_TRY(bindingIdentifierOrPattern(kind, yieldHandling, tt));
   4522 
   4523      bool hasInitializer;
   4524      if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
   4525                                  TokenStream::SlashIsRegExp)) {
   4526        return errorResult();
   4527      }
   4528 
   4529      Node element;
   4530      if (hasInitializer) {
   4531        element = MOZ_TRY(bindingInitializer(binding, kind, yieldHandling));
   4532      } else {
   4533        element = binding;
   4534      }
   4535 
   4536      handler_.addArrayElement(literal, element);
   4537    }
   4538 
   4539    if (tt != TokenKind::Comma) {
   4540      // If we didn't already match TokenKind::Comma in above case.
   4541      bool matched;
   4542      if (!tokenStream.matchToken(&matched, TokenKind::Comma,
   4543                                  TokenStream::SlashIsRegExp)) {
   4544        return errorResult();
   4545      }
   4546      if (!matched) {
   4547        break;
   4548      }
   4549 
   4550      if (tt == TokenKind::TripleDot) {
   4551        error(JSMSG_REST_WITH_COMMA);
   4552        return errorResult();
   4553      }
   4554    }
   4555  }
   4556 
   4557  if (!mustMatchToken(TokenKind::RightBracket, [this, begin](TokenKind actual) {
   4558        this->reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
   4559                                   JSMSG_BRACKET_OPENED, begin);
   4560      })) {
   4561    return errorResult();
   4562  }
   4563 
   4564  handler_.setEndPosition(literal, pos().end);
   4565  return literal;
   4566 }
   4567 
   4568 template <class ParseHandler, typename Unit>
   4569 typename ParseHandler::NodeResult
   4570 GeneralParser<ParseHandler, Unit>::destructuringDeclaration(
   4571    DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
   4572  MOZ_ASSERT(anyChars.isCurrentTokenType(tt));
   4573  MOZ_ASSERT(tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly);
   4574 
   4575  if (tt == TokenKind::LeftBracket) {
   4576    return arrayBindingPattern(kind, yieldHandling);
   4577  }
   4578  return objectBindingPattern(kind, yieldHandling);
   4579 }
   4580 
   4581 template <class ParseHandler, typename Unit>
   4582 typename ParseHandler::NodeResult
   4583 GeneralParser<ParseHandler, Unit>::destructuringDeclarationWithoutYieldOrAwait(
   4584    DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
   4585  uint32_t startYieldOffset = pc_->lastYieldOffset;
   4586  uint32_t startAwaitOffset = pc_->lastAwaitOffset;
   4587 
   4588  Node res = MOZ_TRY(destructuringDeclaration(kind, yieldHandling, tt));
   4589 
   4590  if (pc_->lastYieldOffset != startYieldOffset) {
   4591    errorAt(pc_->lastYieldOffset, JSMSG_YIELD_IN_PARAMETER);
   4592    return errorResult();
   4593  }
   4594  if (pc_->lastAwaitOffset != startAwaitOffset) {
   4595    errorAt(pc_->lastAwaitOffset, JSMSG_AWAIT_IN_PARAMETER);
   4596    return errorResult();
   4597  }
   4598  return res;
   4599 }
   4600 
   4601 template <class ParseHandler, typename Unit>
   4602 typename ParseHandler::LexicalScopeNodeResult
   4603 GeneralParser<ParseHandler, Unit>::blockStatement(YieldHandling yieldHandling,
   4604                                                  unsigned errorNumber) {
   4605  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftCurly));
   4606  uint32_t openedPos = pos().begin;
   4607 
   4608  ParseContext::Statement stmt(pc_, StatementKind::Block);
   4609  ParseContext::Scope scope(this);
   4610  if (!scope.init(pc_)) {
   4611    return errorResult();
   4612  }
   4613 
   4614  ListNodeType list = MOZ_TRY(statementList(yieldHandling));
   4615 
   4616  if (!mustMatchToken(TokenKind::RightCurly, [this, errorNumber,
   4617                                              openedPos](TokenKind actual) {
   4618        this->reportMissingClosing(errorNumber, JSMSG_CURLY_OPENED, openedPos);
   4619      })) {
   4620    return errorResult();
   4621  }
   4622 
   4623  return finishLexicalScope(scope, list);
   4624 }
   4625 
   4626 template <class ParseHandler, typename Unit>
   4627 typename ParseHandler::NodeResult
   4628 GeneralParser<ParseHandler, Unit>::expressionAfterForInOrOf(
   4629    ParseNodeKind forHeadKind, YieldHandling yieldHandling) {
   4630  MOZ_ASSERT(forHeadKind == ParseNodeKind::ForIn ||
   4631             forHeadKind == ParseNodeKind::ForOf);
   4632  if (forHeadKind == ParseNodeKind::ForOf) {
   4633    return assignExpr(InAllowed, yieldHandling, TripledotProhibited);
   4634  }
   4635 
   4636  return expr(InAllowed, yieldHandling, TripledotProhibited);
   4637 }
   4638 
   4639 template <class ParseHandler, typename Unit>
   4640 typename ParseHandler::NodeResult
   4641 GeneralParser<ParseHandler, Unit>::declarationPattern(
   4642    DeclarationKind declKind, TokenKind tt, bool initialDeclaration,
   4643    YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
   4644    Node* forInOrOfExpression) {
   4645  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftBracket) ||
   4646             anyChars.isCurrentTokenType(TokenKind::LeftCurly));
   4647 
   4648  Node pattern = MOZ_TRY(destructuringDeclaration(declKind, yieldHandling, tt));
   4649 
   4650  if (initialDeclaration && forHeadKind) {
   4651    bool isForIn, isForOf;
   4652    if (!matchInOrOf(&isForIn, &isForOf)) {
   4653      return errorResult();
   4654    }
   4655 
   4656    if (isForIn) {
   4657      *forHeadKind = ParseNodeKind::ForIn;
   4658    } else if (isForOf) {
   4659      *forHeadKind = ParseNodeKind::ForOf;
   4660    } else {
   4661      *forHeadKind = ParseNodeKind::ForHead;
   4662    }
   4663 
   4664    if (*forHeadKind != ParseNodeKind::ForHead) {
   4665      *forInOrOfExpression =
   4666          MOZ_TRY(expressionAfterForInOrOf(*forHeadKind, yieldHandling));
   4667 
   4668      return pattern;
   4669    }
   4670  }
   4671 
   4672  if (!mustMatchToken(TokenKind::Assign, JSMSG_BAD_DESTRUCT_DECL)) {
   4673    return errorResult();
   4674  }
   4675 
   4676  Node init = MOZ_TRY(assignExpr(forHeadKind ? InProhibited : InAllowed,
   4677                                 yieldHandling, TripledotProhibited));
   4678 
   4679  return handler_.newAssignment(ParseNodeKind::AssignExpr, pattern, init);
   4680 }
   4681 
   4682 template <class ParseHandler, typename Unit>
   4683 typename ParseHandler::AssignmentNodeResult
   4684 GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
   4685    NameNodeType binding, DeclarationKind declKind, bool initialDeclaration,
   4686    YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
   4687    Node* forInOrOfExpression) {
   4688  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Assign));
   4689 
   4690  uint32_t initializerOffset;
   4691  if (!tokenStream.peekOffset(&initializerOffset, TokenStream::SlashIsRegExp)) {
   4692    return errorResult();
   4693  }
   4694 
   4695  Node initializer = MOZ_TRY(assignExpr(forHeadKind ? InProhibited : InAllowed,
   4696                                        yieldHandling, TripledotProhibited));
   4697 
   4698  if (forHeadKind && initialDeclaration) {
   4699    bool isForIn, isForOf;
   4700    if (!matchInOrOf(&isForIn, &isForOf)) {
   4701      return errorResult();
   4702    }
   4703 
   4704    // An initialized declaration can't appear in a for-of:
   4705    //
   4706    //   for (var/let/const x = ... of ...); // BAD
   4707    if (isForOf) {
   4708      errorAt(initializerOffset, JSMSG_OF_AFTER_FOR_LOOP_DECL);
   4709      return errorResult();
   4710    }
   4711 
   4712    if (isForIn) {
   4713      // Lexical declarations in for-in loops can't be initialized:
   4714      //
   4715      //   for (let/const x = ... in ...); // BAD
   4716      if (DeclarationKindIsLexical(declKind)) {
   4717        errorAt(initializerOffset, JSMSG_IN_AFTER_LEXICAL_FOR_DECL);
   4718        return errorResult();
   4719      }
   4720 
   4721      // This leaves only initialized for-in |var| declarations.  ES6
   4722      // forbids these; later ES un-forbids in non-strict mode code.
   4723      *forHeadKind = ParseNodeKind::ForIn;
   4724      if (!strictModeErrorAt(initializerOffset,
   4725                             JSMSG_INVALID_FOR_IN_DECL_WITH_INIT)) {
   4726        return errorResult();
   4727      }
   4728 
   4729      *forInOrOfExpression = MOZ_TRY(
   4730          expressionAfterForInOrOf(ParseNodeKind::ForIn, yieldHandling));
   4731    } else {
   4732      *forHeadKind = ParseNodeKind::ForHead;
   4733    }
   4734  }
   4735 
   4736  return handler_.finishInitializerAssignment(binding, initializer);
   4737 }
   4738 
   4739 template <class ParseHandler, typename Unit>
   4740 typename ParseHandler::NodeResult
   4741 GeneralParser<ParseHandler, Unit>::declarationName(DeclarationKind declKind,
   4742                                                   TokenKind tt,
   4743                                                   bool initialDeclaration,
   4744                                                   YieldHandling yieldHandling,
   4745                                                   ParseNodeKind* forHeadKind,
   4746                                                   Node* forInOrOfExpression) {
   4747  // Anything other than possible identifier is an error.
   4748  if (!TokenKindIsPossibleIdentifier(tt)) {
   4749    error(JSMSG_NO_VARIABLE_NAME, TokenKindToDesc(tt));
   4750    return errorResult();
   4751  }
   4752 
   4753  TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
   4754  if (!name) {
   4755    return errorResult();
   4756  }
   4757 
   4758  NameNodeType binding = MOZ_TRY(newName(name));
   4759 
   4760  TokenPos namePos = pos();
   4761 
   4762  // The '=' context after a variable name in a declaration is an opportunity
   4763  // for ASI, and thus for the next token to start an ExpressionStatement:
   4764  //
   4765  //  var foo   // VariableDeclaration
   4766  //  /bar/g;   // ExpressionStatement
   4767  //
   4768  // Therefore get the token here with SlashIsRegExp.
   4769  bool matched;
   4770  if (!tokenStream.matchToken(&matched, TokenKind::Assign,
   4771                              TokenStream::SlashIsRegExp)) {
   4772    return errorResult();
   4773  }
   4774 
   4775  Node declaration;
   4776  if (matched) {
   4777    declaration = MOZ_TRY(initializerInNameDeclaration(
   4778        binding, declKind, initialDeclaration, yieldHandling, forHeadKind,
   4779        forInOrOfExpression));
   4780  } else {
   4781    declaration = binding;
   4782 
   4783    if (initialDeclaration && forHeadKind) {
   4784      bool isForIn, isForOf;
   4785      if (!matchInOrOf(&isForIn, &isForOf)) {
   4786        return errorResult();
   4787      }
   4788 
   4789      if (isForIn) {
   4790        *forHeadKind = ParseNodeKind::ForIn;
   4791 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   4792        if (declKind == DeclarationKind::Using ||
   4793            declKind == DeclarationKind::AwaitUsing) {
   4794          errorAt(namePos.begin, JSMSG_NO_IN_WITH_USING);
   4795          return errorResult();
   4796        }
   4797 #endif
   4798      } else if (isForOf) {
   4799        *forHeadKind = ParseNodeKind::ForOf;
   4800      } else {
   4801        *forHeadKind = ParseNodeKind::ForHead;
   4802      }
   4803    }
   4804 
   4805    if (forHeadKind && *forHeadKind != ParseNodeKind::ForHead) {
   4806      *forInOrOfExpression =
   4807          MOZ_TRY(expressionAfterForInOrOf(*forHeadKind, yieldHandling));
   4808    } else {
   4809      // Normal const declarations, and const declarations in for(;;)
   4810      // heads, must be initialized.
   4811      if (declKind == DeclarationKind::Const) {
   4812        errorAt(namePos.begin, JSMSG_BAD_CONST_DECL);
   4813        return errorResult();
   4814      }
   4815 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   4816      if (declKind == DeclarationKind::Using ||
   4817          declKind == DeclarationKind::AwaitUsing) {
   4818        errorAt(namePos.begin, JSMSG_BAD_USING_DECL);
   4819        return errorResult();
   4820      }
   4821 #endif
   4822    }
   4823  }
   4824 
   4825  // Note the declared name after knowing whether or not we are in a for-of
   4826  // loop, due to special early error semantics in Annex B.3.5.
   4827  if (!noteDeclaredName(name, declKind, namePos)) {
   4828    return errorResult();
   4829  }
   4830 
   4831  return declaration;
   4832 }
   4833 
   4834 template <class ParseHandler, typename Unit>
   4835 typename ParseHandler::DeclarationListNodeResult
   4836 GeneralParser<ParseHandler, Unit>::declarationList(
   4837    YieldHandling yieldHandling, ParseNodeKind kind,
   4838    ParseNodeKind* forHeadKind /* = nullptr */,
   4839    Node* forInOrOfExpression /* = nullptr */) {
   4840  MOZ_ASSERT(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl ||
   4841             kind == ParseNodeKind::ConstDecl
   4842 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   4843             || kind == ParseNodeKind::UsingDecl ||
   4844             kind == ParseNodeKind::AwaitUsingDecl
   4845 #endif
   4846  );
   4847 
   4848  DeclarationKind declKind;
   4849  switch (kind) {
   4850    case ParseNodeKind::VarStmt:
   4851      declKind = DeclarationKind::Var;
   4852      break;
   4853    case ParseNodeKind::ConstDecl:
   4854      declKind = DeclarationKind::Const;
   4855      break;
   4856    case ParseNodeKind::LetDecl:
   4857      declKind = DeclarationKind::Let;
   4858      break;
   4859 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   4860    case ParseNodeKind::UsingDecl:
   4861      declKind = DeclarationKind::Using;
   4862      break;
   4863    case ParseNodeKind::AwaitUsingDecl:
   4864      declKind = DeclarationKind::AwaitUsing;
   4865      break;
   4866 #endif
   4867    default:
   4868      MOZ_CRASH("Unknown declaration kind");
   4869  }
   4870 
   4871  DeclarationListNodeType decl =
   4872      MOZ_TRY(handler_.newDeclarationList(kind, pos()));
   4873 
   4874  bool moreDeclarations;
   4875  bool initialDeclaration = true;
   4876  do {
   4877    MOZ_ASSERT_IF(!initialDeclaration && forHeadKind,
   4878                  *forHeadKind == ParseNodeKind::ForHead);
   4879 
   4880    TokenKind tt;
   4881    if (!tokenStream.getToken(&tt)) {
   4882      return errorResult();
   4883    }
   4884 
   4885    Node binding;
   4886    if (tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly) {
   4887      if (declKind == DeclarationKind::Using ||
   4888          declKind == DeclarationKind::AwaitUsing) {
   4889        MOZ_ASSERT(!initialDeclaration);
   4890        error(JSMSG_NO_DESTRUCT_IN_USING);
   4891        return errorResult();
   4892      }
   4893      binding = MOZ_TRY(declarationPattern(declKind, tt, initialDeclaration,
   4894                                           yieldHandling, forHeadKind,
   4895                                           forInOrOfExpression));
   4896    } else {
   4897      binding = MOZ_TRY(declarationName(declKind, tt, initialDeclaration,
   4898                                        yieldHandling, forHeadKind,
   4899                                        forInOrOfExpression));
   4900    }
   4901 
   4902    handler_.addList(decl, binding);
   4903 
   4904    // If we have a for-in/of loop, the above call matches the entirety
   4905    // of the loop head (up to the closing parenthesis).
   4906    if (forHeadKind && *forHeadKind != ParseNodeKind::ForHead) {
   4907      break;
   4908    }
   4909 
   4910    initialDeclaration = false;
   4911 
   4912    if (!tokenStream.matchToken(&moreDeclarations, TokenKind::Comma,
   4913                                TokenStream::SlashIsRegExp)) {
   4914      return errorResult();
   4915    }
   4916  } while (moreDeclarations);
   4917 
   4918  return decl;
   4919 }
   4920 
   4921 template <class ParseHandler, typename Unit>
   4922 typename ParseHandler::DeclarationListNodeResult
   4923 GeneralParser<ParseHandler, Unit>::lexicalDeclaration(
   4924    YieldHandling yieldHandling, DeclarationKind kind) {
   4925  MOZ_ASSERT(kind == DeclarationKind::Const || kind == DeclarationKind::Let
   4926 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   4927             || kind == DeclarationKind::Using ||
   4928             kind == DeclarationKind::AwaitUsing
   4929 #endif
   4930  );
   4931 
   4932  if (options().selfHostingMode) {
   4933    error(JSMSG_SELFHOSTED_LEXICAL);
   4934    return errorResult();
   4935  }
   4936 
   4937  /*
   4938   * Parse body-level lets without a new block object. ES6 specs
   4939   * that an execution environment's initial lexical environment
   4940   * is the VariableEnvironment, i.e., body-level lets are in
   4941   * the same environment record as vars.
   4942   *
   4943   * However, they cannot be parsed exactly as vars, as ES6
   4944   * requires that uninitialized lets throw ReferenceError on use.
   4945   *
   4946   * See 8.1.1.1.6 and the note in 13.2.1.
   4947   */
   4948  ParseNodeKind pnk;
   4949  switch (kind) {
   4950    case DeclarationKind::Const:
   4951      pnk = ParseNodeKind::ConstDecl;
   4952      break;
   4953 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   4954    case DeclarationKind::Using:
   4955      pnk = ParseNodeKind::UsingDecl;
   4956      break;
   4957    case DeclarationKind::AwaitUsing:
   4958      pnk = ParseNodeKind::AwaitUsingDecl;
   4959      break;
   4960 #endif
   4961    case DeclarationKind::Let:
   4962      pnk = ParseNodeKind::LetDecl;
   4963      break;
   4964    default:
   4965      MOZ_CRASH("unexpected node kind");
   4966  }
   4967  DeclarationListNodeType decl = MOZ_TRY(declarationList(yieldHandling, pnk));
   4968  if (!matchOrInsertSemicolon()) {
   4969    return errorResult();
   4970  }
   4971 
   4972  return decl;
   4973 }
   4974 
   4975 template <class ParseHandler, typename Unit>
   4976 typename ParseHandler::NameNodeResult
   4977 GeneralParser<ParseHandler, Unit>::moduleExportName() {
   4978  MOZ_ASSERT(anyChars.currentToken().type == TokenKind::String);
   4979  TaggedParserAtomIndex name = anyChars.currentToken().atom();
   4980  if (!this->parserAtoms().isModuleExportName(name)) {
   4981    error(JSMSG_UNPAIRED_SURROGATE_EXPORT);
   4982    return errorResult();
   4983  }
   4984  return handler_.newStringLiteral(name, pos());
   4985 }
   4986 
   4987 template <class ParseHandler, typename Unit>
   4988 bool GeneralParser<ParseHandler, Unit>::withClause(ListNodeType attributesSet) {
   4989  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::With));
   4990 
   4991  if (!abortIfSyntaxParser()) {
   4992    return false;
   4993  }
   4994 
   4995  if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_AFTER_WITH)) {
   4996    return false;
   4997  }
   4998 
   4999  // Handle the form |... with {}|
   5000  TokenKind token;
   5001  if (!tokenStream.getToken(&token)) {
   5002    return false;
   5003  }
   5004  if (token == TokenKind::RightCurly) {
   5005    return true;
   5006  }
   5007 
   5008  js::HashSet<TaggedParserAtomIndex, TaggedParserAtomIndexHasher,
   5009              js::SystemAllocPolicy>
   5010      usedAssertionKeys;
   5011 
   5012  for (;;) {
   5013    TaggedParserAtomIndex keyName;
   5014    if (TokenKindIsPossibleIdentifierName(token)) {
   5015      keyName = anyChars.currentName();
   5016    } else if (token == TokenKind::String) {
   5017      keyName = anyChars.currentToken().atom();
   5018    } else {
   5019      error(JSMSG_ATTRIBUTE_KEY_EXPECTED);
   5020      return false;
   5021    }
   5022 
   5023    auto p = usedAssertionKeys.lookupForAdd(keyName);
   5024    if (p) {
   5025      UniqueChars str = this->parserAtoms().toPrintableString(keyName);
   5026      if (!str) {
   5027        ReportOutOfMemory(this->fc_);
   5028        return false;
   5029      }
   5030      error(JSMSG_DUPLICATE_ATTRIBUTE_KEY, str.get());
   5031      return false;
   5032    }
   5033    if (!usedAssertionKeys.add(p, keyName)) {
   5034      ReportOutOfMemory(this->fc_);
   5035      return false;
   5036    }
   5037 
   5038    NameNodeType keyNode;
   5039    MOZ_TRY_VAR_OR_RETURN(keyNode, newName(keyName), false);
   5040 
   5041    if (!mustMatchToken(TokenKind::Colon, JSMSG_COLON_AFTER_ATTRIBUTE_KEY)) {
   5042      return false;
   5043    }
   5044    if (!mustMatchToken(TokenKind::String, JSMSG_WITH_CLAUSE_STRING_LITERAL)) {
   5045      return false;
   5046    }
   5047 
   5048    NameNodeType valueNode;
   5049    MOZ_TRY_VAR_OR_RETURN(valueNode, stringLiteral(), false);
   5050 
   5051    BinaryNodeType importAttributeNode;
   5052    MOZ_TRY_VAR_OR_RETURN(importAttributeNode,
   5053                          handler_.newImportAttribute(keyNode, valueNode),
   5054                          false);
   5055 
   5056    handler_.addList(attributesSet, importAttributeNode);
   5057 
   5058    if (!tokenStream.getToken(&token)) {
   5059      return false;
   5060    }
   5061    if (token == TokenKind::Comma) {
   5062      if (!tokenStream.getToken(&token)) {
   5063        return false;
   5064      }
   5065    }
   5066    if (token == TokenKind::RightCurly) {
   5067      break;
   5068    }
   5069  }
   5070 
   5071  return true;
   5072 }
   5073 
   5074 template <class ParseHandler, typename Unit>
   5075 bool GeneralParser<ParseHandler, Unit>::namedImports(
   5076    ListNodeType importSpecSet) {
   5077  if (!abortIfSyntaxParser()) {
   5078    return false;
   5079  }
   5080 
   5081  while (true) {
   5082    // Handle the forms |import {} from 'a'| and
   5083    // |import { ..., } from 'a'| (where ... is non empty), by
   5084    // escaping the loop early if the next token is }.
   5085    TokenKind tt;
   5086    if (!tokenStream.getToken(&tt)) {
   5087      return false;
   5088    }
   5089 
   5090    if (tt == TokenKind::RightCurly) {
   5091      break;
   5092    }
   5093 
   5094    TaggedParserAtomIndex importName;
   5095    NameNodeType importNameNode = null();
   5096    if (TokenKindIsPossibleIdentifierName(tt)) {
   5097      importName = anyChars.currentName();
   5098      MOZ_TRY_VAR_OR_RETURN(importNameNode, newName(importName), false);
   5099    } else if (tt == TokenKind::String) {
   5100      MOZ_TRY_VAR_OR_RETURN(importNameNode, moduleExportName(), false);
   5101    } else {
   5102      error(JSMSG_NO_IMPORT_NAME);
   5103      return false;
   5104    }
   5105 
   5106    bool matched;
   5107    if (!tokenStream.matchToken(&matched, TokenKind::As)) {
   5108      return false;
   5109    }
   5110 
   5111    if (matched) {
   5112      TokenKind afterAs;
   5113      if (!tokenStream.getToken(&afterAs)) {
   5114        return false;
   5115      }
   5116 
   5117      if (!TokenKindIsPossibleIdentifierName(afterAs)) {
   5118        error(JSMSG_NO_BINDING_NAME);
   5119        return false;
   5120      }
   5121    } else {
   5122      // String export names can't refer to local bindings.
   5123      if (tt == TokenKind::String) {
   5124        error(JSMSG_AS_AFTER_STRING);
   5125        return false;
   5126      }
   5127 
   5128      // Keywords cannot be bound to themselves, so an import name
   5129      // that is a keyword is a syntax error if it is not followed
   5130      // by the keyword 'as'.
   5131      // See the ImportSpecifier production in ES6 section 15.2.2.
   5132      MOZ_ASSERT(importName);
   5133      if (IsKeyword(importName)) {
   5134        error(JSMSG_AS_AFTER_RESERVED_WORD, ReservedWordToCharZ(importName));
   5135        return false;
   5136      }
   5137    }
   5138 
   5139    TaggedParserAtomIndex bindingAtom = importedBinding();
   5140    if (!bindingAtom) {
   5141      return false;
   5142    }
   5143 
   5144    NameNodeType bindingName;
   5145    MOZ_TRY_VAR_OR_RETURN(bindingName, newName(bindingAtom), false);
   5146    if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos())) {
   5147      return false;
   5148    }
   5149 
   5150    BinaryNodeType importSpec;
   5151    MOZ_TRY_VAR_OR_RETURN(
   5152        importSpec, handler_.newImportSpec(importNameNode, bindingName), false);
   5153 
   5154    handler_.addList(importSpecSet, importSpec);
   5155 
   5156    TokenKind next;
   5157    if (!tokenStream.getToken(&next)) {
   5158      return false;
   5159    }
   5160 
   5161    if (next == TokenKind::RightCurly) {
   5162      break;
   5163    }
   5164 
   5165    if (next != TokenKind::Comma) {
   5166      error(JSMSG_RC_AFTER_IMPORT_SPEC_LIST);
   5167      return false;
   5168    }
   5169  }
   5170 
   5171  return true;
   5172 }
   5173 
   5174 template <class ParseHandler, typename Unit>
   5175 bool GeneralParser<ParseHandler, Unit>::namespaceImport(
   5176    ListNodeType importSpecSet) {
   5177  if (!abortIfSyntaxParser()) {
   5178    return false;
   5179  }
   5180 
   5181  if (!mustMatchToken(TokenKind::As, JSMSG_AS_AFTER_IMPORT_STAR)) {
   5182    return false;
   5183  }
   5184  uint32_t begin = pos().begin;
   5185 
   5186  if (!mustMatchToken(TokenKindIsPossibleIdentifierName,
   5187                      JSMSG_NO_BINDING_NAME)) {
   5188    return false;
   5189  }
   5190 
   5191  // Namespace imports are not indirect bindings but lexical
   5192  // definitions that hold a module namespace object. They are treated
   5193  // as const variables which are initialized during the
   5194  // ModuleInstantiate step.
   5195  TaggedParserAtomIndex bindingName = importedBinding();
   5196  if (!bindingName) {
   5197    return false;
   5198  }
   5199  NameNodeType bindingNameNode;
   5200  MOZ_TRY_VAR_OR_RETURN(bindingNameNode, newName(bindingName), false);
   5201  if (!noteDeclaredName(bindingName, DeclarationKind::Const, pos())) {
   5202    return false;
   5203  }
   5204 
   5205  // The namespace import name is currently required to live on the
   5206  // environment.
   5207  pc_->varScope().lookupDeclaredName(bindingName)->value()->setClosedOver();
   5208 
   5209  UnaryNodeType importSpec;
   5210  MOZ_TRY_VAR_OR_RETURN(importSpec,
   5211                        handler_.newImportNamespaceSpec(begin, bindingNameNode),
   5212                        false);
   5213 
   5214  handler_.addList(importSpecSet, importSpec);
   5215 
   5216  return true;
   5217 }
   5218 
   5219 template <class ParseHandler, typename Unit>
   5220 typename ParseHandler::BinaryNodeResult
   5221 GeneralParser<ParseHandler, Unit>::importDeclaration() {
   5222  if (!abortIfSyntaxParser()) {
   5223    return errorResult();
   5224  }
   5225 
   5226  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import));
   5227 
   5228  if (!pc_->atModuleLevel()) {
   5229    error(JSMSG_IMPORT_DECL_AT_TOP_LEVEL);
   5230    return errorResult();
   5231  }
   5232 
   5233  uint32_t begin = pos().begin;
   5234  TokenKind tt;
   5235  if (!tokenStream.getToken(&tt)) {
   5236    return errorResult();
   5237  }
   5238 
   5239  ListNodeType importSpecSet =
   5240      MOZ_TRY(handler_.newList(ParseNodeKind::ImportSpecList, pos()));
   5241 
   5242  if (tt == TokenKind::String) {
   5243    // Handle the form |import 'a'| by leaving the list empty. This is
   5244    // equivalent to |import {} from 'a'|.
   5245    handler_.setEndPosition(importSpecSet, pos().begin);
   5246  } else {
   5247    if (tt == TokenKind::LeftCurly) {
   5248      if (!namedImports(importSpecSet)) {
   5249        return errorResult();
   5250      }
   5251    } else if (tt == TokenKind::Mul) {
   5252      if (!namespaceImport(importSpecSet)) {
   5253        return errorResult();
   5254      }
   5255    } else if (TokenKindIsPossibleIdentifierName(tt)) {
   5256      // Handle the form |import a from 'b'|, by adding a single import
   5257      // specifier to the list, with 'default' as the import name and
   5258      // 'a' as the binding name. This is equivalent to
   5259      // |import { default as a } from 'b'|.
   5260      NameNodeType importName =
   5261          MOZ_TRY(newName(TaggedParserAtomIndex::WellKnown::default_()));
   5262 
   5263      TaggedParserAtomIndex bindingAtom = importedBinding();
   5264      if (!bindingAtom) {
   5265        return errorResult();
   5266      }
   5267 
   5268      NameNodeType bindingName = MOZ_TRY(newName(bindingAtom));
   5269 
   5270      if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos())) {
   5271        return errorResult();
   5272      }
   5273 
   5274      BinaryNodeType importSpec =
   5275          MOZ_TRY(handler_.newImportSpec(importName, bindingName));
   5276 
   5277      handler_.addList(importSpecSet, importSpec);
   5278 
   5279      if (!tokenStream.peekToken(&tt)) {
   5280        return errorResult();
   5281      }
   5282 
   5283      if (tt == TokenKind::Comma) {
   5284        tokenStream.consumeKnownToken(tt);
   5285        if (!tokenStream.getToken(&tt)) {
   5286          return errorResult();
   5287        }
   5288 
   5289        if (tt == TokenKind::LeftCurly) {
   5290          if (!namedImports(importSpecSet)) {
   5291            return errorResult();
   5292          }
   5293        } else if (tt == TokenKind::Mul) {
   5294          if (!namespaceImport(importSpecSet)) {
   5295            return errorResult();
   5296          }
   5297        } else {
   5298          error(JSMSG_NAMED_IMPORTS_OR_NAMESPACE_IMPORT);
   5299          return errorResult();
   5300        }
   5301      }
   5302    } else {
   5303      error(JSMSG_DECLARATION_AFTER_IMPORT);
   5304      return errorResult();
   5305    }
   5306 
   5307    if (!mustMatchToken(TokenKind::From, JSMSG_FROM_AFTER_IMPORT_CLAUSE)) {
   5308      return errorResult();
   5309    }
   5310 
   5311    if (!mustMatchToken(TokenKind::String, JSMSG_MODULE_SPEC_AFTER_FROM)) {
   5312      return errorResult();
   5313    }
   5314  }
   5315 
   5316  NameNodeType moduleSpec = MOZ_TRY(stringLiteral());
   5317 
   5318  if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
   5319    return errorResult();
   5320  }
   5321 
   5322  ListNodeType importAttributeList =
   5323      MOZ_TRY(handler_.newList(ParseNodeKind::ImportAttributeList, pos()));
   5324 
   5325  if (tt == TokenKind::With) {
   5326    tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
   5327 
   5328    if (!withClause(importAttributeList)) {
   5329      return errorResult();
   5330    }
   5331  }
   5332 
   5333  if (!matchOrInsertSemicolon(TokenStream::SlashIsRegExp)) {
   5334    return errorResult();
   5335  }
   5336 
   5337  BinaryNodeType moduleRequest = MOZ_TRY(handler_.newModuleRequest(
   5338      moduleSpec, importAttributeList, TokenPos(begin, pos().end)));
   5339 
   5340  BinaryNodeType node = MOZ_TRY(handler_.newImportDeclaration(
   5341      importSpecSet, moduleRequest, TokenPos(begin, pos().end)));
   5342  if (!processImport(node)) {
   5343    return errorResult();
   5344  }
   5345 
   5346  return node;
   5347 }
   5348 
   5349 template <class ParseHandler, typename Unit>
   5350 inline typename ParseHandler::NodeResult
   5351 GeneralParser<ParseHandler, Unit>::importDeclarationOrImportExpr(
   5352    YieldHandling yieldHandling) {
   5353  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import));
   5354 
   5355  TokenKind tt;
   5356  if (!tokenStream.peekToken(&tt)) {
   5357    return errorResult();
   5358  }
   5359 
   5360  if (tt == TokenKind::Dot || tt == TokenKind::LeftParen) {
   5361    return expressionStatement(yieldHandling);
   5362  }
   5363 
   5364  return importDeclaration();
   5365 }
   5366 
   5367 template <typename Unit>
   5368 bool Parser<FullParseHandler, Unit>::checkExportedName(
   5369    TaggedParserAtomIndex exportName) {
   5370  switch (pc_->sc()->asModuleContext()->builder.noteExportedName(exportName)) {
   5371    case ModuleBuilder::NoteExportedNameResult::Success:
   5372      return true;
   5373    case ModuleBuilder::NoteExportedNameResult::OutOfMemory:
   5374      return false;
   5375    case ModuleBuilder::NoteExportedNameResult::AlreadyDeclared:
   5376      break;
   5377  }
   5378 
   5379  UniqueChars str = this->parserAtoms().toPrintableString(exportName);
   5380  if (!str) {
   5381    ReportOutOfMemory(this->fc_);
   5382    return false;
   5383  }
   5384 
   5385  error(JSMSG_DUPLICATE_EXPORT_NAME, str.get());
   5386  return false;
   5387 }
   5388 
   5389 template <typename Unit>
   5390 inline bool Parser<SyntaxParseHandler, Unit>::checkExportedName(
   5391    TaggedParserAtomIndex exportName) {
   5392  MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
   5393  return false;
   5394 }
   5395 
   5396 template <class ParseHandler, typename Unit>
   5397 inline bool GeneralParser<ParseHandler, Unit>::checkExportedName(
   5398    TaggedParserAtomIndex exportName) {
   5399  return asFinalParser()->checkExportedName(exportName);
   5400 }
   5401 
   5402 template <typename Unit>
   5403 bool Parser<FullParseHandler, Unit>::checkExportedNamesForArrayBinding(
   5404    ListNode* array) {
   5405  MOZ_ASSERT(array->isKind(ParseNodeKind::ArrayExpr));
   5406 
   5407  for (ParseNode* node : array->contents()) {
   5408    if (node->isKind(ParseNodeKind::Elision)) {
   5409      continue;
   5410    }
   5411 
   5412    ParseNode* binding;
   5413    if (node->isKind(ParseNodeKind::Spread)) {
   5414      binding = node->as<UnaryNode>().kid();
   5415    } else if (node->isKind(ParseNodeKind::AssignExpr)) {
   5416      binding = node->as<AssignmentNode>().left();
   5417    } else {
   5418      binding = node;
   5419    }
   5420 
   5421    if (!checkExportedNamesForDeclaration(binding)) {
   5422      return false;
   5423    }
   5424  }
   5425 
   5426  return true;
   5427 }
   5428 
   5429 template <typename Unit>
   5430 inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNamesForArrayBinding(
   5431    ListNodeType array) {
   5432  MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
   5433  return false;
   5434 }
   5435 
   5436 template <class ParseHandler, typename Unit>
   5437 inline bool
   5438 GeneralParser<ParseHandler, Unit>::checkExportedNamesForArrayBinding(
   5439    ListNodeType array) {
   5440  return asFinalParser()->checkExportedNamesForArrayBinding(array);
   5441 }
   5442 
   5443 template <typename Unit>
   5444 bool Parser<FullParseHandler, Unit>::checkExportedNamesForObjectBinding(
   5445    ListNode* obj) {
   5446  MOZ_ASSERT(obj->isKind(ParseNodeKind::ObjectExpr));
   5447 
   5448  for (ParseNode* node : obj->contents()) {
   5449    MOZ_ASSERT(node->isKind(ParseNodeKind::MutateProto) ||
   5450               node->isKind(ParseNodeKind::PropertyDefinition) ||
   5451               node->isKind(ParseNodeKind::Shorthand) ||
   5452               node->isKind(ParseNodeKind::Spread));
   5453 
   5454    ParseNode* target;
   5455    if (node->isKind(ParseNodeKind::Spread)) {
   5456      target = node->as<UnaryNode>().kid();
   5457    } else {
   5458      if (node->isKind(ParseNodeKind::MutateProto)) {
   5459        target = node->as<UnaryNode>().kid();
   5460      } else {
   5461        target = node->as<BinaryNode>().right();
   5462      }
   5463 
   5464      if (target->isKind(ParseNodeKind::AssignExpr)) {
   5465        target = target->as<AssignmentNode>().left();
   5466      }
   5467    }
   5468 
   5469    if (!checkExportedNamesForDeclaration(target)) {
   5470      return false;
   5471    }
   5472  }
   5473 
   5474  return true;
   5475 }
   5476 
   5477 template <typename Unit>
   5478 inline bool Parser<SyntaxParseHandler,
   5479                   Unit>::checkExportedNamesForObjectBinding(ListNodeType obj) {
   5480  MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
   5481  return false;
   5482 }
   5483 
   5484 template <class ParseHandler, typename Unit>
   5485 inline bool
   5486 GeneralParser<ParseHandler, Unit>::checkExportedNamesForObjectBinding(
   5487    ListNodeType obj) {
   5488  return asFinalParser()->checkExportedNamesForObjectBinding(obj);
   5489 }
   5490 
   5491 template <typename Unit>
   5492 bool Parser<FullParseHandler, Unit>::checkExportedNamesForDeclaration(
   5493    ParseNode* node) {
   5494  if (node->isKind(ParseNodeKind::Name)) {
   5495    if (!checkExportedName(node->as<NameNode>().atom())) {
   5496      return false;
   5497    }
   5498  } else if (node->isKind(ParseNodeKind::ArrayExpr)) {
   5499    if (!checkExportedNamesForArrayBinding(&node->as<ListNode>())) {
   5500      return false;
   5501    }
   5502  } else {
   5503    MOZ_ASSERT(node->isKind(ParseNodeKind::ObjectExpr));
   5504    if (!checkExportedNamesForObjectBinding(&node->as<ListNode>())) {
   5505      return false;
   5506    }
   5507  }
   5508 
   5509  return true;
   5510 }
   5511 
   5512 template <typename Unit>
   5513 inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNamesForDeclaration(
   5514    Node node) {
   5515  MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
   5516  return false;
   5517 }
   5518 
   5519 template <class ParseHandler, typename Unit>
   5520 inline bool GeneralParser<ParseHandler, Unit>::checkExportedNamesForDeclaration(
   5521    Node node) {
   5522  return asFinalParser()->checkExportedNamesForDeclaration(node);
   5523 }
   5524 
   5525 template <typename Unit>
   5526 bool Parser<FullParseHandler, Unit>::checkExportedNamesForDeclarationList(
   5527    DeclarationListNodeType node) {
   5528  for (ParseNode* binding : node->contents()) {
   5529    if (binding->isKind(ParseNodeKind::AssignExpr)) {
   5530      binding = binding->as<AssignmentNode>().left();
   5531    } else {
   5532      MOZ_ASSERT(binding->isKind(ParseNodeKind::Name));
   5533    }
   5534 
   5535    if (!checkExportedNamesForDeclaration(binding)) {
   5536      return false;
   5537    }
   5538  }
   5539 
   5540  return true;
   5541 }
   5542 
   5543 template <typename Unit>
   5544 inline bool
   5545 Parser<SyntaxParseHandler, Unit>::checkExportedNamesForDeclarationList(
   5546    DeclarationListNodeType node) {
   5547  MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
   5548  return false;
   5549 }
   5550 
   5551 template <class ParseHandler, typename Unit>
   5552 inline bool
   5553 GeneralParser<ParseHandler, Unit>::checkExportedNamesForDeclarationList(
   5554    DeclarationListNodeType node) {
   5555  return asFinalParser()->checkExportedNamesForDeclarationList(node);
   5556 }
   5557 
   5558 template <typename Unit>
   5559 inline bool Parser<FullParseHandler, Unit>::checkExportedNameForClause(
   5560    NameNode* nameNode) {
   5561  return checkExportedName(nameNode->atom());
   5562 }
   5563 
   5564 template <typename Unit>
   5565 inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNameForClause(
   5566    NameNodeType nameNode) {
   5567  MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
   5568  return false;
   5569 }
   5570 
   5571 template <class ParseHandler, typename Unit>
   5572 inline bool GeneralParser<ParseHandler, Unit>::checkExportedNameForClause(
   5573    NameNodeType nameNode) {
   5574  return asFinalParser()->checkExportedNameForClause(nameNode);
   5575 }
   5576 
   5577 template <typename Unit>
   5578 bool Parser<FullParseHandler, Unit>::checkExportedNameForFunction(
   5579    FunctionNode* funNode) {
   5580  return checkExportedName(funNode->funbox()->explicitName());
   5581 }
   5582 
   5583 template <typename Unit>
   5584 inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNameForFunction(
   5585    FunctionNodeType funNode) {
   5586  MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
   5587  return false;
   5588 }
   5589 
   5590 template <class ParseHandler, typename Unit>
   5591 inline bool GeneralParser<ParseHandler, Unit>::checkExportedNameForFunction(
   5592    FunctionNodeType funNode) {
   5593  return asFinalParser()->checkExportedNameForFunction(funNode);
   5594 }
   5595 
   5596 template <typename Unit>
   5597 bool Parser<FullParseHandler, Unit>::checkExportedNameForClass(
   5598    ClassNode* classNode) {
   5599  MOZ_ASSERT(classNode->names());
   5600  return checkExportedName(classNode->names()->innerBinding()->atom());
   5601 }
   5602 
   5603 template <typename Unit>
   5604 inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNameForClass(
   5605    ClassNodeType classNode) {
   5606  MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
   5607  return false;
   5608 }
   5609 
   5610 template <class ParseHandler, typename Unit>
   5611 inline bool GeneralParser<ParseHandler, Unit>::checkExportedNameForClass(
   5612    ClassNodeType classNode) {
   5613  return asFinalParser()->checkExportedNameForClass(classNode);
   5614 }
   5615 
   5616 template <>
   5617 inline bool PerHandlerParser<FullParseHandler>::processExport(ParseNode* node) {
   5618  return pc_->sc()->asModuleContext()->builder.processExport(node);
   5619 }
   5620 
   5621 template <>
   5622 inline bool PerHandlerParser<SyntaxParseHandler>::processExport(Node node) {
   5623  MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
   5624  return false;
   5625 }
   5626 
   5627 template <>
   5628 inline bool PerHandlerParser<FullParseHandler>::processExportFrom(
   5629    BinaryNodeType node) {
   5630  return pc_->sc()->asModuleContext()->builder.processExportFrom(node);
   5631 }
   5632 
   5633 template <>
   5634 inline bool PerHandlerParser<SyntaxParseHandler>::processExportFrom(
   5635    BinaryNodeType node) {
   5636  MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
   5637  return false;
   5638 }
   5639 
   5640 template <>
   5641 inline bool PerHandlerParser<FullParseHandler>::processImport(
   5642    BinaryNodeType node) {
   5643  return pc_->sc()->asModuleContext()->builder.processImport(node);
   5644 }
   5645 
   5646 template <>
   5647 inline bool PerHandlerParser<SyntaxParseHandler>::processImport(
   5648    BinaryNodeType node) {
   5649  MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
   5650  return false;
   5651 }
   5652 
   5653 template <class ParseHandler, typename Unit>
   5654 typename ParseHandler::BinaryNodeResult
   5655 GeneralParser<ParseHandler, Unit>::exportFrom(uint32_t begin, Node specList) {
   5656  if (!abortIfSyntaxParser()) {
   5657    return errorResult();
   5658  }
   5659 
   5660  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::From));
   5661 
   5662  if (!mustMatchToken(TokenKind::String, JSMSG_MODULE_SPEC_AFTER_FROM)) {
   5663    return errorResult();
   5664  }
   5665 
   5666  NameNodeType moduleSpec = MOZ_TRY(stringLiteral());
   5667 
   5668  TokenKind tt;
   5669  if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
   5670    return errorResult();
   5671  }
   5672 
   5673  uint32_t moduleSpecPos = pos().begin;
   5674 
   5675  ListNodeType importAttributeList =
   5676      MOZ_TRY(handler_.newList(ParseNodeKind::ImportAttributeList, pos()));
   5677  if (tt == TokenKind::With) {
   5678    tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
   5679 
   5680    if (!withClause(importAttributeList)) {
   5681      return errorResult();
   5682    }
   5683  }
   5684 
   5685  if (!matchOrInsertSemicolon(TokenStream::SlashIsRegExp)) {
   5686    return errorResult();
   5687  }
   5688 
   5689  BinaryNodeType moduleRequest = MOZ_TRY(handler_.newModuleRequest(
   5690      moduleSpec, importAttributeList, TokenPos(moduleSpecPos, pos().end)));
   5691 
   5692  BinaryNodeType node = MOZ_TRY(
   5693      handler_.newExportFromDeclaration(begin, specList, moduleRequest));
   5694 
   5695  if (!processExportFrom(node)) {
   5696    return errorResult();
   5697  }
   5698 
   5699  return node;
   5700 }
   5701 
   5702 template <class ParseHandler, typename Unit>
   5703 typename ParseHandler::BinaryNodeResult
   5704 GeneralParser<ParseHandler, Unit>::exportBatch(uint32_t begin) {
   5705  if (!abortIfSyntaxParser()) {
   5706    return errorResult();
   5707  }
   5708 
   5709  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Mul));
   5710  uint32_t beginExportSpec = pos().begin;
   5711 
   5712  ListNodeType kid =
   5713      MOZ_TRY(handler_.newList(ParseNodeKind::ExportSpecList, pos()));
   5714 
   5715  bool foundAs;
   5716  if (!tokenStream.matchToken(&foundAs, TokenKind::As)) {
   5717    return errorResult();
   5718  }
   5719 
   5720  if (foundAs) {
   5721    TokenKind tt;
   5722    if (!tokenStream.getToken(&tt)) {
   5723      return errorResult();
   5724    }
   5725 
   5726    NameNodeType exportName = null();
   5727    if (TokenKindIsPossibleIdentifierName(tt)) {
   5728      exportName = MOZ_TRY(newName(anyChars.currentName()));
   5729    } else if (tt == TokenKind::String) {
   5730      exportName = MOZ_TRY(moduleExportName());
   5731    } else {
   5732      error(JSMSG_NO_EXPORT_NAME);
   5733      return errorResult();
   5734    }
   5735 
   5736    if (!checkExportedNameForClause(exportName)) {
   5737      return errorResult();
   5738    }
   5739 
   5740    UnaryNodeType exportSpec =
   5741        MOZ_TRY(handler_.newExportNamespaceSpec(beginExportSpec, exportName));
   5742 
   5743    handler_.addList(kid, exportSpec);
   5744  } else {
   5745    // Handle the form |export *| by adding a special export batch
   5746    // specifier to the list.
   5747    NullaryNodeType exportSpec = MOZ_TRY(handler_.newExportBatchSpec(pos()));
   5748 
   5749    handler_.addList(kid, exportSpec);
   5750  }
   5751 
   5752  if (!mustMatchToken(TokenKind::From, JSMSG_FROM_AFTER_EXPORT_STAR)) {
   5753    return errorResult();
   5754  }
   5755 
   5756  return exportFrom(begin, kid);
   5757 }
   5758 
   5759 template <typename Unit>
   5760 bool Parser<FullParseHandler, Unit>::checkLocalExportNames(ListNode* node) {
   5761  // ES 2017 draft 15.2.3.1.
   5762  for (ParseNode* next : node->contents()) {
   5763    ParseNode* name = next->as<BinaryNode>().left();
   5764 
   5765    if (name->isKind(ParseNodeKind::StringExpr)) {
   5766      errorAt(name->pn_pos.begin, JSMSG_BAD_LOCAL_STRING_EXPORT);
   5767      return false;
   5768    }
   5769 
   5770    MOZ_ASSERT(name->isKind(ParseNodeKind::Name));
   5771 
   5772    TaggedParserAtomIndex ident = name->as<NameNode>().atom();
   5773    if (!checkLocalExportName(ident, name->pn_pos.begin)) {
   5774      return false;
   5775    }
   5776  }
   5777 
   5778  return true;
   5779 }
   5780 
   5781 template <typename Unit>
   5782 bool Parser<SyntaxParseHandler, Unit>::checkLocalExportNames(
   5783    ListNodeType node) {
   5784  MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
   5785  return false;
   5786 }
   5787 
   5788 template <class ParseHandler, typename Unit>
   5789 inline bool GeneralParser<ParseHandler, Unit>::checkLocalExportNames(
   5790    ListNodeType node) {
   5791  return asFinalParser()->checkLocalExportNames(node);
   5792 }
   5793 
   5794 template <class ParseHandler, typename Unit>
   5795 typename ParseHandler::NodeResult
   5796 GeneralParser<ParseHandler, Unit>::exportClause(uint32_t begin) {
   5797  if (!abortIfSyntaxParser()) {
   5798    return errorResult();
   5799  }
   5800 
   5801  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftCurly));
   5802 
   5803  ListNodeType kid =
   5804      MOZ_TRY(handler_.newList(ParseNodeKind::ExportSpecList, pos()));
   5805 
   5806  TokenKind tt;
   5807  while (true) {
   5808    // Handle the forms |export {}| and |export { ..., }| (where ... is non
   5809    // empty), by escaping the loop early if the next token is }.
   5810    if (!tokenStream.getToken(&tt)) {
   5811      return errorResult();
   5812    }
   5813 
   5814    if (tt == TokenKind::RightCurly) {
   5815      break;
   5816    }
   5817 
   5818    NameNodeType bindingName = null();
   5819    if (TokenKindIsPossibleIdentifierName(tt)) {
   5820      bindingName = MOZ_TRY(newName(anyChars.currentName()));
   5821    } else if (tt == TokenKind::String) {
   5822      bindingName = MOZ_TRY(moduleExportName());
   5823    } else {
   5824      error(JSMSG_NO_BINDING_NAME);
   5825      return errorResult();
   5826    }
   5827 
   5828    bool foundAs;
   5829    if (!tokenStream.matchToken(&foundAs, TokenKind::As)) {
   5830      return errorResult();
   5831    }
   5832 
   5833    NameNodeType exportName = null();
   5834    if (foundAs) {
   5835      TokenKind tt;
   5836      if (!tokenStream.getToken(&tt)) {
   5837        return errorResult();
   5838      }
   5839 
   5840      if (TokenKindIsPossibleIdentifierName(tt)) {
   5841        exportName = MOZ_TRY(newName(anyChars.currentName()));
   5842      } else if (tt == TokenKind::String) {
   5843        exportName = MOZ_TRY(moduleExportName());
   5844      } else {
   5845        error(JSMSG_NO_EXPORT_NAME);
   5846        return errorResult();
   5847      }
   5848    } else {
   5849      if (tt != TokenKind::String) {
   5850        exportName = MOZ_TRY(newName(anyChars.currentName()));
   5851      } else {
   5852        exportName = MOZ_TRY(moduleExportName());
   5853      }
   5854    }
   5855 
   5856    if (!checkExportedNameForClause(exportName)) {
   5857      return errorResult();
   5858    }
   5859 
   5860    BinaryNodeType exportSpec =
   5861        MOZ_TRY(handler_.newExportSpec(bindingName, exportName));
   5862 
   5863    handler_.addList(kid, exportSpec);
   5864 
   5865    TokenKind next;
   5866    if (!tokenStream.getToken(&next)) {
   5867      return errorResult();
   5868    }
   5869 
   5870    if (next == TokenKind::RightCurly) {
   5871      break;
   5872    }
   5873 
   5874    if (next != TokenKind::Comma) {
   5875      error(JSMSG_RC_AFTER_EXPORT_SPEC_LIST);
   5876      return errorResult();
   5877    }
   5878  }
   5879 
   5880  // Careful!  If |from| follows, even on a new line, it must start a
   5881  // FromClause:
   5882  //
   5883  //   export { x }
   5884  //   from "foo"; // a single ExportDeclaration
   5885  //
   5886  // But if it doesn't, we might have an ASI opportunity in SlashIsRegExp
   5887  // context:
   5888  //
   5889  //   export { x }   // ExportDeclaration, terminated by ASI
   5890  //   fro\u006D      // ExpressionStatement, the name "from"
   5891  //
   5892  // In that case let matchOrInsertSemicolon sort out ASI or any necessary
   5893  // error.
   5894  bool matched;
   5895  if (!tokenStream.matchToken(&matched, TokenKind::From,
   5896                              TokenStream::SlashIsRegExp)) {
   5897    return errorResult();
   5898  }
   5899 
   5900  if (matched) {
   5901    return exportFrom(begin, kid);
   5902  }
   5903 
   5904  if (!matchOrInsertSemicolon()) {
   5905    return errorResult();
   5906  }
   5907 
   5908  if (!checkLocalExportNames(kid)) {
   5909    return errorResult();
   5910  }
   5911 
   5912  UnaryNodeType node =
   5913      MOZ_TRY(handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)));
   5914 
   5915  if (!processExport(node)) {
   5916    return errorResult();
   5917  }
   5918 
   5919  return node;
   5920 }
   5921 
   5922 template <class ParseHandler, typename Unit>
   5923 typename ParseHandler::UnaryNodeResult
   5924 GeneralParser<ParseHandler, Unit>::exportVariableStatement(uint32_t begin) {
   5925  if (!abortIfSyntaxParser()) {
   5926    return errorResult();
   5927  }
   5928 
   5929  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Var));
   5930 
   5931  DeclarationListNodeType kid =
   5932      MOZ_TRY(declarationList(YieldIsName, ParseNodeKind::VarStmt));
   5933  if (!matchOrInsertSemicolon()) {
   5934    return errorResult();
   5935  }
   5936  if (!checkExportedNamesForDeclarationList(kid)) {
   5937    return errorResult();
   5938  }
   5939 
   5940  UnaryNodeType node =
   5941      MOZ_TRY(handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)));
   5942 
   5943  if (!processExport(node)) {
   5944    return errorResult();
   5945  }
   5946 
   5947  return node;
   5948 }
   5949 
   5950 template <class ParseHandler, typename Unit>
   5951 typename ParseHandler::UnaryNodeResult
   5952 GeneralParser<ParseHandler, Unit>::exportFunctionDeclaration(
   5953    uint32_t begin, uint32_t toStringStart,
   5954    FunctionAsyncKind asyncKind /* = SyncFunction */) {
   5955  if (!abortIfSyntaxParser()) {
   5956    return errorResult();
   5957  }
   5958 
   5959  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function));
   5960 
   5961  Node kid = MOZ_TRY(
   5962      functionStmt(toStringStart, YieldIsName, NameRequired, asyncKind));
   5963 
   5964  if (!checkExportedNameForFunction(handler_.asFunctionNode(kid))) {
   5965    return errorResult();
   5966  }
   5967 
   5968  UnaryNodeType node =
   5969      MOZ_TRY(handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)));
   5970 
   5971  if (!processExport(node)) {
   5972    return errorResult();
   5973  }
   5974 
   5975  return node;
   5976 }
   5977 
   5978 template <class ParseHandler, typename Unit>
   5979 typename ParseHandler::UnaryNodeResult
   5980 GeneralParser<ParseHandler, Unit>::exportClassDeclaration(uint32_t begin) {
   5981  if (!abortIfSyntaxParser()) {
   5982    return errorResult();
   5983  }
   5984 
   5985  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Class));
   5986 
   5987  ClassNodeType kid =
   5988      MOZ_TRY(classDefinition(YieldIsName, ClassStatement, NameRequired));
   5989 
   5990  if (!checkExportedNameForClass(kid)) {
   5991    return errorResult();
   5992  }
   5993 
   5994  UnaryNodeType node =
   5995      MOZ_TRY(handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)));
   5996 
   5997  if (!processExport(node)) {
   5998    return errorResult();
   5999  }
   6000 
   6001  return node;
   6002 }
   6003 
   6004 template <class ParseHandler, typename Unit>
   6005 typename ParseHandler::UnaryNodeResult
   6006 GeneralParser<ParseHandler, Unit>::exportLexicalDeclaration(
   6007    uint32_t begin, DeclarationKind kind) {
   6008  if (!abortIfSyntaxParser()) {
   6009    return errorResult();
   6010  }
   6011 
   6012  MOZ_ASSERT(kind == DeclarationKind::Const || kind == DeclarationKind::Let);
   6013  MOZ_ASSERT_IF(kind == DeclarationKind::Const,
   6014                anyChars.isCurrentTokenType(TokenKind::Const));
   6015  MOZ_ASSERT_IF(kind == DeclarationKind::Let,
   6016                anyChars.isCurrentTokenType(TokenKind::Let));
   6017 
   6018  DeclarationListNodeType kid = MOZ_TRY(lexicalDeclaration(YieldIsName, kind));
   6019  if (!checkExportedNamesForDeclarationList(kid)) {
   6020    return errorResult();
   6021  }
   6022 
   6023  UnaryNodeType node =
   6024      MOZ_TRY(handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)));
   6025 
   6026  if (!processExport(node)) {
   6027    return errorResult();
   6028  }
   6029 
   6030  return node;
   6031 }
   6032 
   6033 template <class ParseHandler, typename Unit>
   6034 typename ParseHandler::BinaryNodeResult
   6035 GeneralParser<ParseHandler, Unit>::exportDefaultFunctionDeclaration(
   6036    uint32_t begin, uint32_t toStringStart,
   6037    FunctionAsyncKind asyncKind /* = SyncFunction */) {
   6038  if (!abortIfSyntaxParser()) {
   6039    return errorResult();
   6040  }
   6041 
   6042  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function));
   6043 
   6044  Node kid = MOZ_TRY(
   6045      functionStmt(toStringStart, YieldIsName, AllowDefaultName, asyncKind));
   6046 
   6047  BinaryNodeType node = MOZ_TRY(handler_.newExportDefaultDeclaration(
   6048      kid, null(), TokenPos(begin, pos().end)));
   6049 
   6050  if (!processExport(node)) {
   6051    return errorResult();
   6052  }
   6053 
   6054  return node;
   6055 }
   6056 
   6057 template <class ParseHandler, typename Unit>
   6058 typename ParseHandler::BinaryNodeResult
   6059 GeneralParser<ParseHandler, Unit>::exportDefaultClassDeclaration(
   6060    uint32_t begin) {
   6061  if (!abortIfSyntaxParser()) {
   6062    return errorResult();
   6063  }
   6064 
   6065  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Class));
   6066 
   6067  ClassNodeType kid =
   6068      MOZ_TRY(classDefinition(YieldIsName, ClassStatement, AllowDefaultName));
   6069 
   6070  BinaryNodeType node = MOZ_TRY(handler_.newExportDefaultDeclaration(
   6071      kid, null(), TokenPos(begin, pos().end)));
   6072 
   6073  if (!processExport(node)) {
   6074    return errorResult();
   6075  }
   6076 
   6077  return node;
   6078 }
   6079 
   6080 template <class ParseHandler, typename Unit>
   6081 typename ParseHandler::BinaryNodeResult
   6082 GeneralParser<ParseHandler, Unit>::exportDefaultAssignExpr(uint32_t begin) {
   6083  if (!abortIfSyntaxParser()) {
   6084    return errorResult();
   6085  }
   6086 
   6087  TaggedParserAtomIndex name = TaggedParserAtomIndex::WellKnown::default_();
   6088  NameNodeType nameNode = MOZ_TRY(newName(name));
   6089  if (!noteDeclaredName(name, DeclarationKind::Const, pos())) {
   6090    return errorResult();
   6091  }
   6092 
   6093  Node kid = MOZ_TRY(assignExpr(InAllowed, YieldIsName, TripledotProhibited));
   6094 
   6095  if (!matchOrInsertSemicolon()) {
   6096    return errorResult();
   6097  }
   6098 
   6099  BinaryNodeType node = MOZ_TRY(handler_.newExportDefaultDeclaration(
   6100      kid, nameNode, TokenPos(begin, pos().end)));
   6101 
   6102  if (!processExport(node)) {
   6103    return errorResult();
   6104  }
   6105 
   6106  return node;
   6107 }
   6108 
   6109 template <class ParseHandler, typename Unit>
   6110 typename ParseHandler::BinaryNodeResult
   6111 GeneralParser<ParseHandler, Unit>::exportDefault(uint32_t begin) {
   6112  if (!abortIfSyntaxParser()) {
   6113    return errorResult();
   6114  }
   6115 
   6116  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Default));
   6117 
   6118  TokenKind tt;
   6119  if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
   6120    return errorResult();
   6121  }
   6122 
   6123  if (!checkExportedName(TaggedParserAtomIndex::WellKnown::default_())) {
   6124    return errorResult();
   6125  }
   6126 
   6127  switch (tt) {
   6128    case TokenKind::Function:
   6129      return exportDefaultFunctionDeclaration(begin, pos().begin);
   6130 
   6131    case TokenKind::Async: {
   6132      TokenKind nextSameLine = TokenKind::Eof;
   6133      if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
   6134        return errorResult();
   6135      }
   6136 
   6137      if (nextSameLine == TokenKind::Function) {
   6138        uint32_t toStringStart = pos().begin;
   6139        tokenStream.consumeKnownToken(TokenKind::Function);
   6140        return exportDefaultFunctionDeclaration(
   6141            begin, toStringStart, FunctionAsyncKind::AsyncFunction);
   6142      }
   6143 
   6144      anyChars.ungetToken();
   6145      return exportDefaultAssignExpr(begin);
   6146    }
   6147 
   6148    case TokenKind::Class:
   6149      return exportDefaultClassDeclaration(begin);
   6150 
   6151    default:
   6152      anyChars.ungetToken();
   6153      return exportDefaultAssignExpr(begin);
   6154  }
   6155 }
   6156 
   6157 template <class ParseHandler, typename Unit>
   6158 typename ParseHandler::NodeResult
   6159 GeneralParser<ParseHandler, Unit>::exportDeclaration() {
   6160  if (!abortIfSyntaxParser()) {
   6161    return errorResult();
   6162  }
   6163 
   6164  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Export));
   6165 
   6166  if (!pc_->atModuleLevel()) {
   6167    error(JSMSG_EXPORT_DECL_AT_TOP_LEVEL);
   6168    return errorResult();
   6169  }
   6170 
   6171  uint32_t begin = pos().begin;
   6172 
   6173  TokenKind tt;
   6174  if (!tokenStream.getToken(&tt)) {
   6175    return errorResult();
   6176  }
   6177  switch (tt) {
   6178    case TokenKind::Mul:
   6179      return exportBatch(begin);
   6180 
   6181    case TokenKind::LeftCurly:
   6182      return exportClause(begin);
   6183 
   6184    case TokenKind::Var:
   6185      return exportVariableStatement(begin);
   6186 
   6187    case TokenKind::Function:
   6188      return exportFunctionDeclaration(begin, pos().begin);
   6189 
   6190    case TokenKind::Async: {
   6191      TokenKind nextSameLine = TokenKind::Eof;
   6192      if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
   6193        return errorResult();
   6194      }
   6195 
   6196      if (nextSameLine == TokenKind::Function) {
   6197        uint32_t toStringStart = pos().begin;
   6198        tokenStream.consumeKnownToken(TokenKind::Function);
   6199        return exportFunctionDeclaration(begin, toStringStart,
   6200                                         FunctionAsyncKind::AsyncFunction);
   6201      }
   6202 
   6203      error(JSMSG_DECLARATION_AFTER_EXPORT);
   6204      return errorResult();
   6205    }
   6206 
   6207    case TokenKind::Class:
   6208      return exportClassDeclaration(begin);
   6209 
   6210    case TokenKind::Const:
   6211      return exportLexicalDeclaration(begin, DeclarationKind::Const);
   6212 
   6213    case TokenKind::Let:
   6214      return exportLexicalDeclaration(begin, DeclarationKind::Let);
   6215 
   6216    case TokenKind::Default:
   6217      return exportDefault(begin);
   6218 
   6219    default:
   6220      error(JSMSG_DECLARATION_AFTER_EXPORT);
   6221      return errorResult();
   6222  }
   6223 }
   6224 
   6225 template <class ParseHandler, typename Unit>
   6226 typename ParseHandler::UnaryNodeResult
   6227 GeneralParser<ParseHandler, Unit>::expressionStatement(
   6228    YieldHandling yieldHandling, InvokedPrediction invoked) {
   6229  anyChars.ungetToken();
   6230  Node pnexpr = MOZ_TRY(expr(InAllowed, yieldHandling, TripledotProhibited,
   6231                             /* possibleError = */ nullptr, invoked));
   6232  if (!matchOrInsertSemicolon()) {
   6233    return errorResult();
   6234  }
   6235  return handler_.newExprStatement(pnexpr, pos().end);
   6236 }
   6237 
   6238 template <class ParseHandler, typename Unit>
   6239 typename ParseHandler::NodeResult
   6240 GeneralParser<ParseHandler, Unit>::consequentOrAlternative(
   6241    YieldHandling yieldHandling) {
   6242  TokenKind next;
   6243  if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
   6244    return errorResult();
   6245  }
   6246 
   6247  // Annex B.3.4 says that unbraced FunctionDeclarations under if/else in
   6248  // non-strict code act as if they were braced: |if (x) function f() {}|
   6249  // parses as |if (x) { function f() {} }|.
   6250  //
   6251  // Careful!  FunctionDeclaration doesn't include generators or async
   6252  // functions.
   6253  if (next == TokenKind::Function) {
   6254    tokenStream.consumeKnownToken(next, TokenStream::SlashIsRegExp);
   6255 
   6256    // Parser::statement would handle this, but as this function handles
   6257    // every other error case, it seems best to handle this.
   6258    if (pc_->sc()->strict()) {
   6259      error(JSMSG_FORBIDDEN_AS_STATEMENT, "function declarations");
   6260      return errorResult();
   6261    }
   6262 
   6263    TokenKind maybeStar;
   6264    if (!tokenStream.peekToken(&maybeStar)) {
   6265      return errorResult();
   6266    }
   6267 
   6268    if (maybeStar == TokenKind::Mul) {
   6269      error(JSMSG_FORBIDDEN_AS_STATEMENT, "generator declarations");
   6270      return errorResult();
   6271    }
   6272 
   6273    ParseContext::Statement stmt(pc_, StatementKind::Block);
   6274    ParseContext::Scope scope(this);
   6275    if (!scope.init(pc_)) {
   6276      return errorResult();
   6277    }
   6278 
   6279    TokenPos funcPos = pos();
   6280    Node fun = MOZ_TRY(functionStmt(pos().begin, yieldHandling, NameRequired));
   6281 
   6282    ListNodeType block = MOZ_TRY(handler_.newStatementList(funcPos));
   6283 
   6284    handler_.addStatementToList(block, fun);
   6285    return finishLexicalScope(scope, block);
   6286  }
   6287 
   6288  return statement(yieldHandling);
   6289 }
   6290 
   6291 template <class ParseHandler, typename Unit>
   6292 typename ParseHandler::TernaryNodeResult
   6293 GeneralParser<ParseHandler, Unit>::ifStatement(YieldHandling yieldHandling) {
   6294  Vector<Node, 4> condList(fc_), thenList(fc_);
   6295  Vector<uint32_t, 4> posList(fc_);
   6296  Node elseBranch;
   6297 
   6298  ParseContext::Statement stmt(pc_, StatementKind::If);
   6299 
   6300  while (true) {
   6301    uint32_t begin = pos().begin;
   6302 
   6303    /* An IF node has three kids: condition, then, and optional else. */
   6304    Node cond = MOZ_TRY(condition(InAllowed, yieldHandling));
   6305 
   6306    TokenKind tt;
   6307    if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
   6308      return errorResult();
   6309    }
   6310 
   6311    Node thenBranch = MOZ_TRY(consequentOrAlternative(yieldHandling));
   6312 
   6313    if (!condList.append(cond) || !thenList.append(thenBranch) ||
   6314        !posList.append(begin)) {
   6315      return errorResult();
   6316    }
   6317 
   6318    bool matched;
   6319    if (!tokenStream.matchToken(&matched, TokenKind::Else,
   6320                                TokenStream::SlashIsRegExp)) {
   6321      return errorResult();
   6322    }
   6323    if (matched) {
   6324      if (!tokenStream.matchToken(&matched, TokenKind::If,
   6325                                  TokenStream::SlashIsRegExp)) {
   6326        return errorResult();
   6327      }
   6328      if (matched) {
   6329        continue;
   6330      }
   6331      elseBranch = MOZ_TRY(consequentOrAlternative(yieldHandling));
   6332    } else {
   6333      elseBranch = null();
   6334    }
   6335    break;
   6336  }
   6337 
   6338  TernaryNodeType ifNode;
   6339  for (int i = condList.length() - 1; i >= 0; i--) {
   6340    ifNode = MOZ_TRY(handler_.newIfStatement(posList[i], condList[i],
   6341                                             thenList[i], elseBranch));
   6342    elseBranch = ifNode;
   6343  }
   6344 
   6345  return ifNode;
   6346 }
   6347 
   6348 template <class ParseHandler, typename Unit>
   6349 typename ParseHandler::BinaryNodeResult
   6350 GeneralParser<ParseHandler, Unit>::doWhileStatement(
   6351    YieldHandling yieldHandling) {
   6352  uint32_t begin = pos().begin;
   6353  ParseContext::Statement stmt(pc_, StatementKind::DoLoop);
   6354  Node body = MOZ_TRY(statement(yieldHandling));
   6355  if (!mustMatchToken(TokenKind::While, JSMSG_WHILE_AFTER_DO)) {
   6356    return errorResult();
   6357  }
   6358  Node cond = MOZ_TRY(condition(InAllowed, yieldHandling));
   6359 
   6360  // The semicolon after do-while is even more optional than most
   6361  // semicolons in JS.  Web compat required this by 2004:
   6362  //   http://bugzilla.mozilla.org/show_bug.cgi?id=238945
   6363  // ES3 and ES5 disagreed, but ES6 conforms to Web reality:
   6364  //   https://bugs.ecmascript.org/show_bug.cgi?id=157
   6365  // To parse |do {} while (true) false| correctly, use SlashIsRegExp.
   6366  bool ignored;
   6367  if (!tokenStream.matchToken(&ignored, TokenKind::Semi,
   6368                              TokenStream::SlashIsRegExp)) {
   6369    return errorResult();
   6370  }
   6371  return handler_.newDoWhileStatement(body, cond, TokenPos(begin, pos().end));
   6372 }
   6373 
   6374 template <class ParseHandler, typename Unit>
   6375 typename ParseHandler::BinaryNodeResult
   6376 GeneralParser<ParseHandler, Unit>::whileStatement(YieldHandling yieldHandling) {
   6377  uint32_t begin = pos().begin;
   6378  ParseContext::Statement stmt(pc_, StatementKind::WhileLoop);
   6379  Node cond = MOZ_TRY(condition(InAllowed, yieldHandling));
   6380  Node body = MOZ_TRY(statement(yieldHandling));
   6381  return handler_.newWhileStatement(begin, cond, body);
   6382 }
   6383 
   6384 template <class ParseHandler, typename Unit>
   6385 bool GeneralParser<ParseHandler, Unit>::matchInOrOf(bool* isForInp,
   6386                                                    bool* isForOfp) {
   6387  TokenKind tt;
   6388  if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
   6389    return false;
   6390  }
   6391 
   6392  *isForInp = tt == TokenKind::In;
   6393  *isForOfp = tt == TokenKind::Of;
   6394  if (!*isForInp && !*isForOfp) {
   6395    anyChars.ungetToken();
   6396  }
   6397 
   6398  MOZ_ASSERT_IF(*isForInp || *isForOfp, *isForInp != *isForOfp);
   6399  return true;
   6400 }
   6401 
   6402 template <class ParseHandler, typename Unit>
   6403 bool GeneralParser<ParseHandler, Unit>::forHeadStart(
   6404    YieldHandling yieldHandling, IteratorKind iterKind,
   6405    ParseNodeKind* forHeadKind, Node* forInitialPart,
   6406    Maybe<ParseContext::Scope>& forLoopLexicalScope,
   6407    Node* forInOrOfExpression) {
   6408  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftParen));
   6409 
   6410  TokenKind tt;
   6411  if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
   6412    return false;
   6413  }
   6414 
   6415  // Super-duper easy case: |for (;| is a C-style for-loop with no init
   6416  // component.
   6417  if (tt == TokenKind::Semi) {
   6418    *forInitialPart = null();
   6419    *forHeadKind = ParseNodeKind::ForHead;
   6420    return true;
   6421  }
   6422 
   6423  // Parsing after |for (var| is also relatively simple (from this method's
   6424  // point of view).  No block-related work complicates matters, so delegate
   6425  // to Parser::declaration.
   6426  if (tt == TokenKind::Var) {
   6427    tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
   6428 
   6429    // Pass null for block object because |var| declarations don't use one.
   6430    MOZ_TRY_VAR_OR_RETURN(*forInitialPart,
   6431                          declarationList(yieldHandling, ParseNodeKind::VarStmt,
   6432                                          forHeadKind, forInOrOfExpression),
   6433                          false);
   6434    return true;
   6435  }
   6436 
   6437  // Otherwise we have a lexical declaration or an expression.
   6438 
   6439  // For-in loop backwards compatibility requires that |let| starting a
   6440  // for-loop that's not a (new to ES6) for-of loop, in non-strict mode code,
   6441  // parse as an identifier.  (|let| in for-of is always a declaration.)
   6442  //
   6443  // For-of loops can't start with the token sequence "async of", because that
   6444  // leads to a shift-reduce conflict when parsing |for (async of => {};;)| or
   6445  // |for (async of [])|.
   6446  bool parsingLexicalDeclaration = false;
   6447  bool letIsIdentifier = false;
   6448  bool startsWithForOf = false;
   6449 
   6450  if (tt == TokenKind::Const) {
   6451    parsingLexicalDeclaration = true;
   6452    tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
   6453  }
   6454 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   6455  else if (tt == TokenKind::Await && options().explicitResourceManagement()) {
   6456    if (!pc_->isAsync()) {
   6457      if (pc_->atModuleTopLevel()) {
   6458        if (!options().topLevelAwait) {
   6459          error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
   6460          return false;
   6461        }
   6462        pc_->sc()->asModuleContext()->setIsAsync();
   6463        MOZ_ASSERT(pc_->isAsync());
   6464      }
   6465    }
   6466    if (pc_->isAsync()) {
   6467      // Try finding evidence of a AwaitUsingDeclaration the syntax for which
   6468      // would be:
   6469      //   await [no LineTerminator here] using [no LineTerminator here]
   6470      //     identifier
   6471      tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
   6472 
   6473      TokenKind nextTok = TokenKind::Eof;
   6474      if (!tokenStream.peekTokenSameLine(&nextTok,
   6475                                         TokenStream::SlashIsRegExp)) {
   6476        return false;
   6477      }
   6478 
   6479      if (nextTok == TokenKind::Using) {
   6480        tokenStream.consumeKnownToken(nextTok, TokenStream::SlashIsRegExp);
   6481 
   6482        TokenKind nextTokIdent = TokenKind::Eof;
   6483        if (!tokenStream.peekTokenSameLine(&nextTokIdent)) {
   6484          return false;
   6485        }
   6486 
   6487        if (TokenKindIsPossibleIdentifier(nextTokIdent)) {
   6488          parsingLexicalDeclaration = true;
   6489        } else {
   6490          anyChars.ungetToken();  // put back using token
   6491          anyChars.ungetToken();  // put back await token
   6492        }
   6493      } else {
   6494        anyChars.ungetToken();  // put back await token
   6495      }
   6496    }
   6497  } else if (tt == TokenKind::Using && options().explicitResourceManagement()) {
   6498    tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
   6499 
   6500    // Look ahead to find either a 'of' token or if not identifier
   6501    TokenKind nextTok = TokenKind::Eof;
   6502    if (!tokenStream.peekTokenSameLine(&nextTok)) {
   6503      return false;
   6504    }
   6505 
   6506    if (!TokenKindIsPossibleIdentifier(nextTok)) {
   6507      anyChars.ungetToken();  // we didnt find a valid case of using decl put
   6508                              // back the token
   6509    } else if (nextTok == TokenKind::Of) {
   6510      // "for (using of" can be a prefix of the following:
   6511      //   * "for (using of = 0;;) { ... }"
   6512      //   * "for (using of [1, 2, 3]) { ... }"
   6513      //
   6514      // If the "of" token is followed by the assignment token, the loop is
   6515      // considered a C-style for-statement with a using declaration where
   6516      // "of" is an identifier.
   6517      // https://arai-a.github.io/ecma262-compare/?pr=3000&id=sec-for-statement&secAll=true
   6518      //
   6519      // If the "of" token is followed by anything else, this is a for-of
   6520      // statement with the "using" being an identifier", and the token after
   6521      // the "of" token being the first token of the iterated expression (thus
   6522      // SlashIsRegExp is used as the modifier).
   6523      // https://arai-a.github.io/ecma262-compare/?pr=3000&id=sec-for-in-and-for-of-statements&secAll=true
   6524      tokenStream.consumeKnownToken(nextTok);
   6525      TokenKind nextTokAssign;
   6526      if (!tokenStream.peekToken(&nextTokAssign, TokenStream::SlashIsRegExp)) {
   6527        return false;
   6528      }
   6529      if (nextTokAssign == TokenKind::Assign) {
   6530        parsingLexicalDeclaration = true;
   6531        anyChars.ungetToken();  // put back the assignment token
   6532      } else {
   6533        anyChars.ungetToken();  // put back the token after the "of" token
   6534        anyChars.ungetToken();  // put back the of token
   6535      }
   6536    } else {
   6537      parsingLexicalDeclaration = true;
   6538    }
   6539  }
   6540 #endif
   6541  else if (tt == TokenKind::Let) {
   6542    // We could have a {For,Lexical}Declaration, or we could have a
   6543    // LeftHandSideExpression with lookahead restrictions so it's not
   6544    // ambiguous with the former.  Check for a continuation of the former
   6545    // to decide which we have.
   6546    tokenStream.consumeKnownToken(TokenKind::Let, TokenStream::SlashIsRegExp);
   6547 
   6548    TokenKind next;
   6549    if (!tokenStream.peekToken(&next)) {
   6550      return false;
   6551    }
   6552 
   6553    parsingLexicalDeclaration = nextTokenContinuesLetDeclaration(next);
   6554    if (!parsingLexicalDeclaration) {
   6555      // If we end up here, we may have `for (let <reserved word> of/in ...`,
   6556      // which is not valid.
   6557      if (next != TokenKind::In && next != TokenKind::Of &&
   6558          TokenKindIsReservedWord(next)) {
   6559        tokenStream.consumeKnownToken(next);
   6560        error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(next));
   6561        return false;
   6562      }
   6563 
   6564      anyChars.ungetToken();
   6565      letIsIdentifier = true;
   6566    }
   6567  } else if (tt == TokenKind::Async && iterKind == IteratorKind::Sync) {
   6568    tokenStream.consumeKnownToken(TokenKind::Async, TokenStream::SlashIsRegExp);
   6569 
   6570    TokenKind next;
   6571    if (!tokenStream.peekToken(&next)) {
   6572      return false;
   6573    }
   6574 
   6575    if (next == TokenKind::Of) {
   6576      startsWithForOf = true;
   6577    }
   6578    anyChars.ungetToken();
   6579  }
   6580 
   6581  if (parsingLexicalDeclaration) {
   6582    if (options().selfHostingMode) {
   6583      error(JSMSG_SELFHOSTED_LEXICAL);
   6584      return false;
   6585    }
   6586 
   6587    forLoopLexicalScope.emplace(this);
   6588    if (!forLoopLexicalScope->init(pc_)) {
   6589      return false;
   6590    }
   6591 
   6592    // Push a temporary ForLoopLexicalHead Statement that allows for
   6593    // lexical declarations, as they are usually allowed only in braced
   6594    // statements.
   6595    ParseContext::Statement forHeadStmt(pc_, StatementKind::ForLoopLexicalHead);
   6596 
   6597    ParseNodeKind declKind;
   6598    switch (tt) {
   6599      case TokenKind::Const:
   6600        declKind = ParseNodeKind::ConstDecl;
   6601        break;
   6602 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   6603      case TokenKind::Using:
   6604        declKind = ParseNodeKind::UsingDecl;
   6605        break;
   6606      case TokenKind::Await:
   6607        declKind = ParseNodeKind::AwaitUsingDecl;
   6608        break;
   6609 #endif
   6610      case TokenKind::Let:
   6611        declKind = ParseNodeKind::LetDecl;
   6612        break;
   6613      default:
   6614        MOZ_CRASH("unexpected node kind");
   6615    }
   6616 
   6617    MOZ_TRY_VAR_OR_RETURN(*forInitialPart,
   6618                          declarationList(yieldHandling, declKind, forHeadKind,
   6619                                          forInOrOfExpression),
   6620                          false);
   6621    return true;
   6622  }
   6623 
   6624  uint32_t exprOffset;
   6625  if (!tokenStream.peekOffset(&exprOffset, TokenStream::SlashIsRegExp)) {
   6626    return false;
   6627  }
   6628 
   6629  // Finally, handle for-loops that start with expressions.  Pass
   6630  // |InProhibited| so that |in| isn't parsed in a RelationalExpression as a
   6631  // binary operator.  |in| makes it a for-in loop, *not* an |in| expression.
   6632  PossibleError possibleError(*this);
   6633  MOZ_TRY_VAR_OR_RETURN(
   6634      *forInitialPart,
   6635      expr(InProhibited, yieldHandling, TripledotProhibited, &possibleError),
   6636      false);
   6637 
   6638  bool isForIn, isForOf;
   6639  if (!matchInOrOf(&isForIn, &isForOf)) {
   6640    return false;
   6641  }
   6642 
   6643  // If we don't encounter 'in'/'of', we have a for(;;) loop.  We've handled
   6644  // the init expression; the caller handles the rest.
   6645  if (!isForIn && !isForOf) {
   6646    if (!possibleError.checkForExpressionError()) {
   6647      return false;
   6648    }
   6649 
   6650    *forHeadKind = ParseNodeKind::ForHead;
   6651    return true;
   6652  }
   6653 
   6654  MOZ_ASSERT(isForIn != isForOf);
   6655 
   6656  // In a for-of loop, 'let' that starts the loop head is a |let| keyword,
   6657  // per the [lookahead ≠ let] restriction on the LeftHandSideExpression
   6658  // variant of such loops.  Expressions that start with |let| can't be used
   6659  // here.
   6660  //
   6661  //   var let = {};
   6662  //   for (let.prop of [1]) // BAD
   6663  //     break;
   6664  //
   6665  // See ES6 13.7.
   6666  if (isForOf && letIsIdentifier) {
   6667    errorAt(exprOffset, JSMSG_BAD_STARTING_FOROF_LHS, "let");
   6668    return false;
   6669  }
   6670 
   6671  // In a for-of loop, the LeftHandSideExpression isn't allowed to be an
   6672  // identifier named "async" per the [lookahead ≠ async of] restriction.
   6673  if (isForOf && startsWithForOf) {
   6674    errorAt(exprOffset, JSMSG_BAD_STARTING_FOROF_LHS, "async of");
   6675    return false;
   6676  }
   6677 
   6678  *forHeadKind = isForIn ? ParseNodeKind::ForIn : ParseNodeKind::ForOf;
   6679 
   6680  // Verify the left-hand side expression doesn't have a forbidden form.
   6681  if (handler_.isUnparenthesizedDestructuringPattern(*forInitialPart)) {
   6682    if (!possibleError.checkForDestructuringErrorOrWarning()) {
   6683      return false;
   6684    }
   6685  } else if (handler_.isName(*forInitialPart)) {
   6686    if (const char* chars = nameIsArgumentsOrEval(*forInitialPart)) {
   6687      // |chars| is "arguments" or "eval" here.
   6688      if (!strictModeErrorAt(exprOffset, JSMSG_BAD_STRICT_ASSIGN, chars)) {
   6689        return false;
   6690      }
   6691    }
   6692  } else if (handler_.isArgumentsLength(*forInitialPart)) {
   6693    pc_->sc()->setIneligibleForArgumentsLength();
   6694  } else if (handler_.isPropertyOrPrivateMemberAccess(*forInitialPart)) {
   6695    // Permitted: no additional testing/fixup needed.
   6696  } else if (handler_.isFunctionCall(*forInitialPart)) {
   6697    if (!strictModeErrorAt(exprOffset, JSMSG_BAD_FOR_LEFTSIDE)) {
   6698      return false;
   6699    }
   6700  } else {
   6701    errorAt(exprOffset, JSMSG_BAD_FOR_LEFTSIDE);
   6702    return false;
   6703  }
   6704 
   6705  if (!possibleError.checkForExpressionError()) {
   6706    return false;
   6707  }
   6708 
   6709  // Finally, parse the iterated expression, making the for-loop's closing
   6710  // ')' the next token.
   6711  MOZ_TRY_VAR_OR_RETURN(*forInOrOfExpression,
   6712                        expressionAfterForInOrOf(*forHeadKind, yieldHandling),
   6713                        false);
   6714  return true;
   6715 }
   6716 
   6717 template <class ParseHandler, typename Unit>
   6718 typename ParseHandler::NodeResult
   6719 GeneralParser<ParseHandler, Unit>::forStatement(YieldHandling yieldHandling) {
   6720  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::For));
   6721 
   6722  uint32_t begin = pos().begin;
   6723 
   6724  ParseContext::Statement stmt(pc_, StatementKind::ForLoop);
   6725 
   6726  IteratorKind iterKind = IteratorKind::Sync;
   6727  unsigned iflags = 0;
   6728 
   6729  if (pc_->isAsync() || pc_->sc()->isModuleContext()) {
   6730    bool matched;
   6731    if (!tokenStream.matchToken(&matched, TokenKind::Await)) {
   6732      return errorResult();
   6733    }
   6734 
   6735    // If we come across a top level await here, mark the module as async.
   6736    if (matched && pc_->sc()->isModuleContext() && !pc_->isAsync()) {
   6737      if (!options().topLevelAwait) {
   6738        error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
   6739        return errorResult();
   6740      }
   6741      pc_->sc()->asModuleContext()->setIsAsync();
   6742      MOZ_ASSERT(pc_->isAsync());
   6743    }
   6744 
   6745    if (matched) {
   6746      iflags |= JSITER_FORAWAITOF;
   6747      iterKind = IteratorKind::Async;
   6748    }
   6749  }
   6750 
   6751  if (!mustMatchToken(TokenKind::LeftParen, [this](TokenKind actual) {
   6752        this->error((actual == TokenKind::Await && !this->pc_->isAsync())
   6753                        ? JSMSG_FOR_AWAIT_OUTSIDE_ASYNC
   6754                        : JSMSG_PAREN_AFTER_FOR);
   6755      })) {
   6756    return errorResult();
   6757  }
   6758 
   6759  // ParseNodeKind::ForHead, ParseNodeKind::ForIn, or
   6760  // ParseNodeKind::ForOf depending on the loop type.
   6761  ParseNodeKind headKind;
   6762 
   6763  // |x| in either |for (x; ...; ...)| or |for (x in/of ...)|.
   6764  Node startNode;
   6765 
   6766  // The next two variables are used to implement `for (let/const ...)`.
   6767  //
   6768  // We generate an implicit block, wrapping the whole loop, to store loop
   6769  // variables declared this way. Note that if the loop uses `for (var...)`
   6770  // instead, those variables go on some existing enclosing scope, so no
   6771  // implicit block scope is created.
   6772  //
   6773  // Both variables remain null/none if the loop is any other form.
   6774 
   6775  // The static block scope for the implicit block scope.
   6776  Maybe<ParseContext::Scope> forLoopLexicalScope;
   6777 
   6778  // The expression being iterated over, for for-in/of loops only.  Unused
   6779  // for for(;;) loops.
   6780  Node iteratedExpr;
   6781 
   6782  // Parse the entirety of the loop-head for a for-in/of loop (so the next
   6783  // token is the closing ')'):
   6784  //
   6785  //   for (... in/of ...) ...
   6786  //                     ^next token
   6787  //
   6788  // ...OR, parse up to the first ';' in a C-style for-loop:
   6789  //
   6790  //   for (...; ...; ...) ...
   6791  //           ^next token
   6792  //
   6793  // In either case the subsequent token can be consistently accessed using
   6794  // TokenStream::SlashIsDiv semantics.
   6795  if (!forHeadStart(yieldHandling, iterKind, &headKind, &startNode,
   6796                    forLoopLexicalScope, &iteratedExpr)) {
   6797    return errorResult();
   6798  }
   6799 
   6800  MOZ_ASSERT(headKind == ParseNodeKind::ForIn ||
   6801             headKind == ParseNodeKind::ForOf ||
   6802             headKind == ParseNodeKind::ForHead);
   6803 
   6804  if (iterKind == IteratorKind::Async && headKind != ParseNodeKind::ForOf) {
   6805    errorAt(begin, JSMSG_FOR_AWAIT_NOT_OF);
   6806    return errorResult();
   6807  }
   6808 
   6809  TernaryNodeType forHead;
   6810  if (headKind == ParseNodeKind::ForHead) {
   6811    Node init = startNode;
   6812 
   6813    // Look for an operand: |for (;| means we might have already examined
   6814    // this semicolon with that modifier.
   6815    if (!mustMatchToken(TokenKind::Semi, JSMSG_SEMI_AFTER_FOR_INIT)) {
   6816      return errorResult();
   6817    }
   6818 
   6819    TokenKind tt;
   6820    if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
   6821      return errorResult();
   6822    }
   6823 
   6824    Node test;
   6825    if (tt == TokenKind::Semi) {
   6826      test = null();
   6827    } else {
   6828      test = MOZ_TRY(expr(InAllowed, yieldHandling, TripledotProhibited));
   6829    }
   6830 
   6831    if (!mustMatchToken(TokenKind::Semi, JSMSG_SEMI_AFTER_FOR_COND)) {
   6832      return errorResult();
   6833    }
   6834 
   6835    if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
   6836      return errorResult();
   6837    }
   6838 
   6839    Node update;
   6840    if (tt == TokenKind::RightParen) {
   6841      update = null();
   6842    } else {
   6843      update = MOZ_TRY(expr(InAllowed, yieldHandling, TripledotProhibited));
   6844    }
   6845 
   6846    if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_FOR_CTRL)) {
   6847      return errorResult();
   6848    }
   6849 
   6850    TokenPos headPos(begin, pos().end);
   6851    forHead = MOZ_TRY(handler_.newForHead(init, test, update, headPos));
   6852  } else {
   6853    MOZ_ASSERT(headKind == ParseNodeKind::ForIn ||
   6854               headKind == ParseNodeKind::ForOf);
   6855 
   6856    // |target| is the LeftHandSideExpression or declaration to which the
   6857    // per-iteration value (an arbitrary value exposed by the iteration
   6858    // protocol, or a string naming a property) is assigned.
   6859    Node target = startNode;
   6860 
   6861    // Parse the rest of the for-in/of head.
   6862    if (headKind == ParseNodeKind::ForIn) {
   6863      stmt.refineForKind(StatementKind::ForInLoop);
   6864    } else {
   6865      stmt.refineForKind(StatementKind::ForOfLoop);
   6866    }
   6867 
   6868    // Parser::declaration consumed everything up to the closing ')'.  That
   6869    // token follows an {Assignment,}Expression and so must be interpreted
   6870    // as an operand to be consistent with normal expression tokenizing.
   6871    if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_FOR_CTRL)) {
   6872      return errorResult();
   6873    }
   6874 
   6875    TokenPos headPos(begin, pos().end);
   6876    forHead = MOZ_TRY(
   6877        handler_.newForInOrOfHead(headKind, target, iteratedExpr, headPos));
   6878  }
   6879 
   6880  Node body = MOZ_TRY(statement(yieldHandling));
   6881 
   6882  ForNodeType forLoop =
   6883      MOZ_TRY(handler_.newForStatement(begin, forHead, body, iflags));
   6884 
   6885  if (forLoopLexicalScope) {
   6886    return finishLexicalScope(*forLoopLexicalScope, forLoop);
   6887  }
   6888 
   6889  return forLoop;
   6890 }
   6891 
   6892 template <class ParseHandler, typename Unit>
   6893 typename ParseHandler::SwitchStatementResult
   6894 GeneralParser<ParseHandler, Unit>::switchStatement(
   6895    YieldHandling yieldHandling) {
   6896  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Switch));
   6897  uint32_t begin = pos().begin;
   6898 
   6899  if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_SWITCH)) {
   6900    return errorResult();
   6901  }
   6902 
   6903  Node discriminant =
   6904      MOZ_TRY(exprInParens(InAllowed, yieldHandling, TripledotProhibited));
   6905 
   6906  if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_SWITCH)) {
   6907    return errorResult();
   6908  }
   6909  if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_SWITCH)) {
   6910    return errorResult();
   6911  }
   6912 
   6913  ParseContext::Statement stmt(pc_, StatementKind::Switch);
   6914  ParseContext::Scope scope(this);
   6915  if (!scope.init(pc_)) {
   6916    return errorResult();
   6917  }
   6918 
   6919  ListNodeType caseList = MOZ_TRY(handler_.newStatementList(pos()));
   6920 
   6921  bool seenDefault = false;
   6922  TokenKind tt;
   6923  while (true) {
   6924    if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
   6925      return errorResult();
   6926    }
   6927    if (tt == TokenKind::RightCurly) {
   6928      break;
   6929    }
   6930    uint32_t caseBegin = pos().begin;
   6931 
   6932    Node caseExpr;
   6933    switch (tt) {
   6934      case TokenKind::Default:
   6935        if (seenDefault) {
   6936          error(JSMSG_TOO_MANY_DEFAULTS);
   6937          return errorResult();
   6938        }
   6939        seenDefault = true;
   6940        caseExpr = null();  // The default case has pn_left == nullptr.
   6941        break;
   6942 
   6943      case TokenKind::Case:
   6944        caseExpr = MOZ_TRY(expr(InAllowed, yieldHandling, TripledotProhibited));
   6945        break;
   6946 
   6947      default:
   6948        error(JSMSG_BAD_SWITCH);
   6949        return errorResult();
   6950    }
   6951 
   6952    if (!mustMatchToken(TokenKind::Colon, JSMSG_COLON_AFTER_CASE)) {
   6953      return errorResult();
   6954    }
   6955 
   6956    ListNodeType body = MOZ_TRY(handler_.newStatementList(pos()));
   6957 
   6958    bool afterReturn = false;
   6959    bool warnedAboutStatementsAfterReturn = false;
   6960    uint32_t statementBegin = 0;
   6961    while (true) {
   6962      if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
   6963        return errorResult();
   6964      }
   6965      if (tt == TokenKind::RightCurly || tt == TokenKind::Case ||
   6966          tt == TokenKind::Default) {
   6967        break;
   6968      }
   6969      if (afterReturn) {
   6970        if (!tokenStream.peekOffset(&statementBegin,
   6971                                    TokenStream::SlashIsRegExp)) {
   6972          return errorResult();
   6973        }
   6974      }
   6975      Node stmt = MOZ_TRY(statementListItem(yieldHandling));
   6976      if (!warnedAboutStatementsAfterReturn) {
   6977        if (afterReturn) {
   6978          if (!handler_.isStatementPermittedAfterReturnStatement(stmt)) {
   6979            if (!warningAt(statementBegin, JSMSG_STMT_AFTER_RETURN)) {
   6980              return errorResult();
   6981            }
   6982 
   6983            warnedAboutStatementsAfterReturn = true;
   6984          }
   6985        } else if (handler_.isReturnStatement(stmt)) {
   6986          afterReturn = true;
   6987        }
   6988      }
   6989      handler_.addStatementToList(body, stmt);
   6990    }
   6991 
   6992    CaseClauseType caseClause =
   6993        MOZ_TRY(handler_.newCaseOrDefault(caseBegin, caseExpr, body));
   6994    handler_.addCaseStatementToList(caseList, caseClause);
   6995  }
   6996 
   6997  LexicalScopeNodeType lexicalForCaseList =
   6998      MOZ_TRY(finishLexicalScope(scope, caseList));
   6999 
   7000  handler_.setEndPosition(lexicalForCaseList, pos().end);
   7001 
   7002  return handler_.newSwitchStatement(begin, discriminant, lexicalForCaseList,
   7003                                     seenDefault);
   7004 }
   7005 
   7006 template <class ParseHandler, typename Unit>
   7007 typename ParseHandler::ContinueStatementResult
   7008 GeneralParser<ParseHandler, Unit>::continueStatement(
   7009    YieldHandling yieldHandling) {
   7010  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Continue));
   7011  uint32_t begin = pos().begin;
   7012 
   7013  TaggedParserAtomIndex label;
   7014  if (!matchLabel(yieldHandling, &label)) {
   7015    return errorResult();
   7016  }
   7017 
   7018  auto validity = pc_->checkContinueStatement(label);
   7019  if (validity.isErr()) {
   7020    switch (validity.unwrapErr()) {
   7021      case ParseContext::ContinueStatementError::NotInALoop:
   7022        errorAt(begin, JSMSG_BAD_CONTINUE);
   7023        break;
   7024      case ParseContext::ContinueStatementError::LabelNotFound:
   7025        error(JSMSG_LABEL_NOT_FOUND);
   7026        break;
   7027    }
   7028    return errorResult();
   7029  }
   7030 
   7031  if (!matchOrInsertSemicolon()) {
   7032    return errorResult();
   7033  }
   7034 
   7035  return handler_.newContinueStatement(label, TokenPos(begin, pos().end));
   7036 }
   7037 
   7038 template <class ParseHandler, typename Unit>
   7039 typename ParseHandler::BreakStatementResult
   7040 GeneralParser<ParseHandler, Unit>::breakStatement(YieldHandling yieldHandling) {
   7041  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Break));
   7042  uint32_t begin = pos().begin;
   7043 
   7044  TaggedParserAtomIndex label;
   7045  if (!matchLabel(yieldHandling, &label)) {
   7046    return errorResult();
   7047  }
   7048 
   7049  auto validity = pc_->checkBreakStatement(label);
   7050  if (validity.isErr()) {
   7051    switch (validity.unwrapErr()) {
   7052      case ParseContext::BreakStatementError::ToughBreak:
   7053        errorAt(begin, JSMSG_TOUGH_BREAK);
   7054        return errorResult();
   7055      case ParseContext::BreakStatementError::LabelNotFound:
   7056        error(JSMSG_LABEL_NOT_FOUND);
   7057        return errorResult();
   7058    }
   7059  }
   7060 
   7061  if (!matchOrInsertSemicolon()) {
   7062    return errorResult();
   7063  }
   7064 
   7065  return handler_.newBreakStatement(label, TokenPos(begin, pos().end));
   7066 }
   7067 
   7068 template <class ParseHandler, typename Unit>
   7069 typename ParseHandler::UnaryNodeResult
   7070 GeneralParser<ParseHandler, Unit>::returnStatement(
   7071    YieldHandling yieldHandling) {
   7072  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Return));
   7073  uint32_t begin = pos().begin;
   7074 
   7075  MOZ_ASSERT(pc_->isFunctionBox());
   7076 
   7077  // Parse an optional operand.
   7078  //
   7079  // This is ugly, but we don't want to require a semicolon.
   7080  TokenKind tt = TokenKind::Eof;
   7081  if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
   7082    return errorResult();
   7083  }
   7084 
   7085  Node exprNode;
   7086  switch (tt) {
   7087    case TokenKind::Eol:
   7088    case TokenKind::Eof:
   7089    case TokenKind::Semi:
   7090    case TokenKind::RightCurly:
   7091      exprNode = null();
   7092      break;
   7093    default: {
   7094      exprNode = MOZ_TRY(expr(InAllowed, yieldHandling, TripledotProhibited));
   7095    }
   7096  }
   7097 
   7098  if (!matchOrInsertSemicolon()) {
   7099    return errorResult();
   7100  }
   7101 
   7102  return handler_.newReturnStatement(exprNode, TokenPos(begin, pos().end));
   7103 }
   7104 
   7105 template <class ParseHandler, typename Unit>
   7106 typename ParseHandler::UnaryNodeResult
   7107 GeneralParser<ParseHandler, Unit>::yieldExpression(InHandling inHandling) {
   7108  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Yield));
   7109  uint32_t begin = pos().begin;
   7110 
   7111  MOZ_ASSERT(pc_->isGenerator());
   7112  MOZ_ASSERT(pc_->isFunctionBox());
   7113 
   7114  pc_->lastYieldOffset = begin;
   7115 
   7116  Node exprNode;
   7117  ParseNodeKind kind = ParseNodeKind::YieldExpr;
   7118  TokenKind tt = TokenKind::Eof;
   7119  if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
   7120    return errorResult();
   7121  }
   7122  switch (tt) {
   7123    // TokenKind::Eol is special; it implements the [no LineTerminator here]
   7124    // quirk in the grammar.
   7125    case TokenKind::Eol:
   7126    // The rest of these make up the complete set of tokens that can
   7127    // appear after any of the places where AssignmentExpression is used
   7128    // throughout the grammar.  Conveniently, none of them can also be the
   7129    // start an expression.
   7130    case TokenKind::Eof:
   7131    case TokenKind::Semi:
   7132    case TokenKind::RightCurly:
   7133    case TokenKind::RightBracket:
   7134    case TokenKind::RightParen:
   7135    case TokenKind::Colon:
   7136    case TokenKind::Comma:
   7137    case TokenKind::In:  // Annex B.3.6 `for (x = yield in y) ;`
   7138      // No value.
   7139      exprNode = null();
   7140      break;
   7141    case TokenKind::Mul:
   7142      kind = ParseNodeKind::YieldStarExpr;
   7143      tokenStream.consumeKnownToken(TokenKind::Mul, TokenStream::SlashIsRegExp);
   7144      [[fallthrough]];
   7145    default:
   7146      exprNode =
   7147          MOZ_TRY(assignExpr(inHandling, YieldIsKeyword, TripledotProhibited));
   7148  }
   7149  if (kind == ParseNodeKind::YieldStarExpr) {
   7150    return handler_.newYieldStarExpression(begin, exprNode);
   7151  }
   7152  return handler_.newYieldExpression(begin, exprNode);
   7153 }
   7154 
   7155 template <class ParseHandler, typename Unit>
   7156 typename ParseHandler::BinaryNodeResult
   7157 GeneralParser<ParseHandler, Unit>::withStatement(YieldHandling yieldHandling) {
   7158  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::With));
   7159  uint32_t begin = pos().begin;
   7160 
   7161  if (pc_->sc()->strict()) {
   7162    if (!strictModeError(JSMSG_STRICT_CODE_WITH)) {
   7163      return errorResult();
   7164    }
   7165  }
   7166 
   7167  if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_WITH)) {
   7168    return errorResult();
   7169  }
   7170 
   7171  Node objectExpr =
   7172      MOZ_TRY(exprInParens(InAllowed, yieldHandling, TripledotProhibited));
   7173 
   7174  if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_WITH)) {
   7175    return errorResult();
   7176  }
   7177 
   7178  Node innerBlock;
   7179  {
   7180    ParseContext::Statement stmt(pc_, StatementKind::With);
   7181    innerBlock = MOZ_TRY(statement(yieldHandling));
   7182  }
   7183 
   7184  pc_->sc()->setBindingsAccessedDynamically();
   7185 
   7186  return handler_.newWithStatement(begin, objectExpr, innerBlock);
   7187 }
   7188 
   7189 template <class ParseHandler, typename Unit>
   7190 typename ParseHandler::NodeResult
   7191 GeneralParser<ParseHandler, Unit>::labeledItem(YieldHandling yieldHandling) {
   7192  TokenKind tt;
   7193  if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
   7194    return errorResult();
   7195  }
   7196 
   7197  if (tt == TokenKind::Function) {
   7198    TokenKind next;
   7199    if (!tokenStream.peekToken(&next)) {
   7200      return errorResult();
   7201    }
   7202 
   7203    // GeneratorDeclaration is only matched by HoistableDeclaration in
   7204    // StatementListItem, so generators can't be inside labels.
   7205    if (next == TokenKind::Mul) {
   7206      error(JSMSG_GENERATOR_LABEL);
   7207      return errorResult();
   7208    }
   7209 
   7210    // Per 13.13.1 it's a syntax error if LabelledItem: FunctionDeclaration
   7211    // is ever matched.  Per Annex B.3.2 that modifies this text, this
   7212    // applies only to strict mode code.
   7213    if (pc_->sc()->strict()) {
   7214      error(JSMSG_FUNCTION_LABEL);
   7215      return errorResult();
   7216    }
   7217 
   7218    return functionStmt(pos().begin, yieldHandling, NameRequired);
   7219  }
   7220 
   7221  anyChars.ungetToken();
   7222  return statement(yieldHandling);
   7223 }
   7224 
   7225 template <class ParseHandler, typename Unit>
   7226 typename ParseHandler::LabeledStatementResult
   7227 GeneralParser<ParseHandler, Unit>::labeledStatement(
   7228    YieldHandling yieldHandling) {
   7229  TaggedParserAtomIndex label = labelIdentifier(yieldHandling);
   7230  if (!label) {
   7231    return errorResult();
   7232  }
   7233 
   7234  auto hasSameLabel = [&label](ParseContext::LabelStatement* stmt) {
   7235    return stmt->label() == label;
   7236  };
   7237 
   7238  uint32_t begin = pos().begin;
   7239 
   7240  if (pc_->template findInnermostStatement<ParseContext::LabelStatement>(
   7241          hasSameLabel)) {
   7242    errorAt(begin, JSMSG_DUPLICATE_LABEL);
   7243    return errorResult();
   7244  }
   7245 
   7246  tokenStream.consumeKnownToken(TokenKind::Colon);
   7247 
   7248  /* Push a label struct and parse the statement. */
   7249  ParseContext::LabelStatement stmt(pc_, label);
   7250  Node pn = MOZ_TRY(labeledItem(yieldHandling));
   7251 
   7252  return handler_.newLabeledStatement(label, pn, begin);
   7253 }
   7254 
   7255 template <class ParseHandler, typename Unit>
   7256 typename ParseHandler::UnaryNodeResult
   7257 GeneralParser<ParseHandler, Unit>::throwStatement(YieldHandling yieldHandling) {
   7258  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Throw));
   7259  uint32_t begin = pos().begin;
   7260 
   7261  /* ECMA-262 Edition 3 says 'throw [no LineTerminator here] Expr'. */
   7262  TokenKind tt = TokenKind::Eof;
   7263  if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
   7264    return errorResult();
   7265  }
   7266  if (tt == TokenKind::Eof || tt == TokenKind::Semi ||
   7267      tt == TokenKind::RightCurly) {
   7268    error(JSMSG_MISSING_EXPR_AFTER_THROW);
   7269    return errorResult();
   7270  }
   7271  if (tt == TokenKind::Eol) {
   7272    error(JSMSG_LINE_BREAK_AFTER_THROW);
   7273    return errorResult();
   7274  }
   7275 
   7276  Node throwExpr = MOZ_TRY(expr(InAllowed, yieldHandling, TripledotProhibited));
   7277 
   7278  if (!matchOrInsertSemicolon()) {
   7279    return errorResult();
   7280  }
   7281 
   7282  return handler_.newThrowStatement(throwExpr, TokenPos(begin, pos().end));
   7283 }
   7284 
   7285 template <class ParseHandler, typename Unit>
   7286 typename ParseHandler::TernaryNodeResult
   7287 GeneralParser<ParseHandler, Unit>::tryStatement(YieldHandling yieldHandling) {
   7288  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Try));
   7289  uint32_t begin = pos().begin;
   7290 
   7291  /*
   7292   * try nodes are ternary.
   7293   * kid1 is the try statement
   7294   * kid2 is the catch node list or null
   7295   * kid3 is the finally statement
   7296   *
   7297   * catch nodes are binary.
   7298   * left is the catch-name/pattern or null
   7299   * right is the catch block
   7300   *
   7301   * catch lvalue nodes are either:
   7302   *   a single identifier
   7303   *   TokenKind::RightBracket for a destructuring left-hand side
   7304   *   TokenKind::RightCurly for a destructuring left-hand side
   7305   *
   7306   * finally nodes are TokenKind::LeftCurly statement lists.
   7307   */
   7308 
   7309  Node innerBlock;
   7310  {
   7311    if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_TRY)) {
   7312      return errorResult();
   7313    }
   7314 
   7315    uint32_t openedPos = pos().begin;
   7316 
   7317    ParseContext::Statement stmt(pc_, StatementKind::Try);
   7318    ParseContext::Scope scope(this);
   7319    if (!scope.init(pc_)) {
   7320      return errorResult();
   7321    }
   7322 
   7323    innerBlock = MOZ_TRY(statementList(yieldHandling));
   7324 
   7325    innerBlock = MOZ_TRY(finishLexicalScope(scope, innerBlock));
   7326 
   7327    if (!mustMatchToken(
   7328            TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
   7329              this->reportMissingClosing(JSMSG_CURLY_AFTER_TRY,
   7330                                         JSMSG_CURLY_OPENED, openedPos);
   7331            })) {
   7332      return errorResult();
   7333    }
   7334  }
   7335 
   7336  LexicalScopeNodeType catchScope = null();
   7337  TokenKind tt;
   7338  if (!tokenStream.getToken(&tt)) {
   7339    return errorResult();
   7340  }
   7341  if (tt == TokenKind::Catch) {
   7342    /*
   7343     * Create a lexical scope node around the whole catch clause,
   7344     * including the head.
   7345     */
   7346    ParseContext::Statement stmt(pc_, StatementKind::Catch);
   7347    ParseContext::Scope scope(this);
   7348    if (!scope.init(pc_)) {
   7349      return errorResult();
   7350    }
   7351 
   7352    /*
   7353     * Legal catch forms are:
   7354     *   catch (lhs) {
   7355     *   catch {
   7356     * where lhs is a name or a destructuring left-hand side.
   7357     */
   7358    bool omittedBinding;
   7359    if (!tokenStream.matchToken(&omittedBinding, TokenKind::LeftCurly)) {
   7360      return errorResult();
   7361    }
   7362 
   7363    Node catchName;
   7364    if (omittedBinding) {
   7365      catchName = null();
   7366    } else {
   7367      if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_CATCH)) {
   7368        return errorResult();
   7369      }
   7370 
   7371      if (!tokenStream.getToken(&tt)) {
   7372        return errorResult();
   7373      }
   7374      switch (tt) {
   7375        case TokenKind::LeftBracket:
   7376        case TokenKind::LeftCurly:
   7377          catchName = MOZ_TRY(destructuringDeclaration(
   7378              DeclarationKind::CatchParameter, yieldHandling, tt));
   7379          break;
   7380 
   7381        default: {
   7382          if (!TokenKindIsPossibleIdentifierName(tt)) {
   7383            error(JSMSG_CATCH_IDENTIFIER);
   7384            return errorResult();
   7385          }
   7386 
   7387          catchName = MOZ_TRY(bindingIdentifier(
   7388              DeclarationKind::SimpleCatchParameter, yieldHandling));
   7389          break;
   7390        }
   7391      }
   7392 
   7393      if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_CATCH)) {
   7394        return errorResult();
   7395      }
   7396 
   7397      if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_CATCH)) {
   7398        return errorResult();
   7399      }
   7400    }
   7401 
   7402    LexicalScopeNodeType catchBody =
   7403        MOZ_TRY(catchBlockStatement(yieldHandling, scope));
   7404 
   7405    catchScope = MOZ_TRY(finishLexicalScope(scope, catchBody));
   7406 
   7407    if (!handler_.setupCatchScope(catchScope, catchName, catchBody)) {
   7408      return errorResult();
   7409    }
   7410    handler_.setEndPosition(catchScope, pos().end);
   7411 
   7412    if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
   7413      return errorResult();
   7414    }
   7415  }
   7416 
   7417  Node finallyBlock = null();
   7418 
   7419  if (tt == TokenKind::Finally) {
   7420    if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_FINALLY)) {
   7421      return errorResult();
   7422    }
   7423 
   7424    uint32_t openedPos = pos().begin;
   7425 
   7426    ParseContext::Statement stmt(pc_, StatementKind::Finally);
   7427    ParseContext::Scope scope(this);
   7428    if (!scope.init(pc_)) {
   7429      return errorResult();
   7430    }
   7431 
   7432    finallyBlock = MOZ_TRY(statementList(yieldHandling));
   7433 
   7434    finallyBlock = MOZ_TRY(finishLexicalScope(scope, finallyBlock));
   7435 
   7436    if (!mustMatchToken(
   7437            TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
   7438              this->reportMissingClosing(JSMSG_CURLY_AFTER_FINALLY,
   7439                                         JSMSG_CURLY_OPENED, openedPos);
   7440            })) {
   7441      return errorResult();
   7442    }
   7443  } else {
   7444    anyChars.ungetToken();
   7445  }
   7446  if (!catchScope && !finallyBlock) {
   7447    error(JSMSG_CATCH_OR_FINALLY);
   7448    return errorResult();
   7449  }
   7450 
   7451  return handler_.newTryStatement(begin, innerBlock, catchScope, finallyBlock);
   7452 }
   7453 
   7454 template <class ParseHandler, typename Unit>
   7455 typename ParseHandler::LexicalScopeNodeResult
   7456 GeneralParser<ParseHandler, Unit>::catchBlockStatement(
   7457    YieldHandling yieldHandling, ParseContext::Scope& catchParamScope) {
   7458  uint32_t openedPos = pos().begin;
   7459 
   7460  ParseContext::Statement stmt(pc_, StatementKind::Block);
   7461 
   7462  // ES 13.15.7 CatchClauseEvaluation
   7463  //
   7464  // Step 8 means that the body of a catch block always has an additional
   7465  // lexical scope.
   7466  ParseContext::Scope scope(this);
   7467  if (!scope.init(pc_)) {
   7468    return errorResult();
   7469  }
   7470 
   7471  // The catch parameter names cannot be redeclared inside the catch
   7472  // block, so declare the name in the inner scope.
   7473  if (!scope.addCatchParameters(pc_, catchParamScope)) {
   7474    return errorResult();
   7475  }
   7476 
   7477  ListNodeType list = MOZ_TRY(statementList(yieldHandling));
   7478 
   7479  if (!mustMatchToken(
   7480          TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
   7481            this->reportMissingClosing(JSMSG_CURLY_AFTER_CATCH,
   7482                                       JSMSG_CURLY_OPENED, openedPos);
   7483          })) {
   7484    return errorResult();
   7485  }
   7486 
   7487  // The catch parameter names are not bound in the body scope, so remove
   7488  // them before generating bindings.
   7489  scope.removeCatchParameters(pc_, catchParamScope);
   7490  return finishLexicalScope(scope, list);
   7491 }
   7492 
   7493 template <class ParseHandler, typename Unit>
   7494 typename ParseHandler::DebuggerStatementResult
   7495 GeneralParser<ParseHandler, Unit>::debuggerStatement() {
   7496  TokenPos p;
   7497  p.begin = pos().begin;
   7498  if (!matchOrInsertSemicolon()) {
   7499    return errorResult();
   7500  }
   7501  p.end = pos().end;
   7502 
   7503  return handler_.newDebuggerStatement(p);
   7504 }
   7505 
   7506 static AccessorType ToAccessorType(PropertyType propType) {
   7507  switch (propType) {
   7508    case PropertyType::Getter:
   7509      return AccessorType::Getter;
   7510    case PropertyType::Setter:
   7511      return AccessorType::Setter;
   7512    case PropertyType::Normal:
   7513    case PropertyType::Method:
   7514    case PropertyType::GeneratorMethod:
   7515    case PropertyType::AsyncMethod:
   7516    case PropertyType::AsyncGeneratorMethod:
   7517    case PropertyType::Constructor:
   7518    case PropertyType::DerivedConstructor:
   7519      return AccessorType::None;
   7520    default:
   7521      MOZ_CRASH("unexpected property type");
   7522  }
   7523 }
   7524 
   7525 #ifdef ENABLE_DECORATORS
   7526 template <class ParseHandler, typename Unit>
   7527 typename ParseHandler::ListNodeResult
   7528 GeneralParser<ParseHandler, Unit>::decoratorList(YieldHandling yieldHandling) {
   7529  ListNodeType decorators =
   7530      MOZ_TRY(handler_.newList(ParseNodeKind::DecoratorList, pos()));
   7531 
   7532  // Build a decorator list element. At each entry point to this loop we have
   7533  // already consumed the |@| token
   7534  TokenKind tt;
   7535  for (;;) {
   7536    if (!tokenStream.getToken(&tt, TokenStream::SlashIsInvalid)) {
   7537      return errorResult();
   7538    }
   7539 
   7540    Node decorator = MOZ_TRY(decoratorExpr(yieldHandling, tt));
   7541 
   7542    handler_.addList(decorators, decorator);
   7543 
   7544    if (!tokenStream.getToken(&tt)) {
   7545      return errorResult();
   7546    }
   7547    if (tt != TokenKind::At) {
   7548      anyChars.ungetToken();
   7549      break;
   7550    }
   7551  }
   7552  return decorators;
   7553 }
   7554 #endif
   7555 
   7556 template <class ParseHandler, typename Unit>
   7557 bool GeneralParser<ParseHandler, Unit>::classMember(
   7558    YieldHandling yieldHandling, const ParseContext::ClassStatement& classStmt,
   7559    TaggedParserAtomIndex className, uint32_t classStartOffset,
   7560    HasHeritage hasHeritage, ClassInitializedMembers& classInitializedMembers,
   7561    ListNodeType& classMembers, bool* done) {
   7562  *done = false;
   7563 
   7564  TokenKind tt;
   7565  if (!tokenStream.getToken(&tt, TokenStream::SlashIsInvalid)) {
   7566    return false;
   7567  }
   7568  if (tt == TokenKind::RightCurly) {
   7569    *done = true;
   7570    return true;
   7571  }
   7572 
   7573  if (tt == TokenKind::Semi) {
   7574    return true;
   7575  }
   7576 
   7577 #ifdef ENABLE_DECORATORS
   7578  ListNodeType decorators = null();
   7579  if (tt == TokenKind::At) {
   7580    MOZ_TRY_VAR_OR_RETURN(decorators, decoratorList(yieldHandling), false);
   7581 
   7582    if (!tokenStream.getToken(&tt, TokenStream::SlashIsInvalid)) {
   7583      return false;
   7584    }
   7585  }
   7586 #endif
   7587 
   7588  bool isStatic = false;
   7589  if (tt == TokenKind::Static) {
   7590    if (!tokenStream.peekToken(&tt)) {
   7591      return false;
   7592    }
   7593 
   7594    if (tt == TokenKind::LeftCurly) {
   7595      /* Parsing static class block: static { ... } */
   7596      FunctionNodeType staticBlockBody;
   7597      MOZ_TRY_VAR_OR_RETURN(staticBlockBody,
   7598                            staticClassBlock(classInitializedMembers), false);
   7599 
   7600      StaticClassBlockType classBlock;
   7601      MOZ_TRY_VAR_OR_RETURN(
   7602          classBlock, handler_.newStaticClassBlock(staticBlockBody), false);
   7603 
   7604      return handler_.addClassMemberDefinition(classMembers, classBlock);
   7605    }
   7606 
   7607    if (tt != TokenKind::LeftParen && tt != TokenKind::Assign &&
   7608        tt != TokenKind::Semi && tt != TokenKind::RightCurly) {
   7609      isStatic = true;
   7610    } else {
   7611      anyChars.ungetToken();
   7612    }
   7613  } else {
   7614    anyChars.ungetToken();
   7615  }
   7616 
   7617  uint32_t propNameOffset;
   7618  if (!tokenStream.peekOffset(&propNameOffset, TokenStream::SlashIsInvalid)) {
   7619    return false;
   7620  }
   7621 
   7622  TaggedParserAtomIndex propAtom;
   7623  PropertyType propType;
   7624  Node propName;
   7625  MOZ_TRY_VAR_OR_RETURN(
   7626      propName,
   7627      propertyOrMethodName(yieldHandling, PropertyNameInClass,
   7628                           /* maybeDecl = */ Nothing(), classMembers, &propType,
   7629                           &propAtom),
   7630      false);
   7631 
   7632  if (propType == PropertyType::Field ||
   7633      propType == PropertyType::FieldWithAccessor) {
   7634    if (isStatic) {
   7635      if (propAtom == TaggedParserAtomIndex::WellKnown::prototype()) {
   7636        errorAt(propNameOffset, JSMSG_CLASS_STATIC_PROTO);
   7637        return false;
   7638      }
   7639    }
   7640 
   7641    if (propAtom == TaggedParserAtomIndex::WellKnown::constructor()) {
   7642      errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
   7643      return false;
   7644    }
   7645 
   7646    if (handler_.isPrivateName(propName)) {
   7647      if (propAtom == TaggedParserAtomIndex::WellKnown::hash_constructor_()) {
   7648        errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
   7649        return false;
   7650      }
   7651 
   7652      auto privateName = propAtom;
   7653      if (!noteDeclaredPrivateName(
   7654              propName, privateName, propType,
   7655              isStatic ? FieldPlacement::Static : FieldPlacement::Instance,
   7656              pos())) {
   7657        return false;
   7658      }
   7659    }
   7660 
   7661 #ifdef ENABLE_DECORATORS
   7662    ClassMethodType accessorGetterNode = null();
   7663    ClassMethodType accessorSetterNode = null();
   7664    if (propType == PropertyType::FieldWithAccessor) {
   7665      // Decorators Proposal
   7666      // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-runtime-semantics-classfielddefinitionevaluation
   7667      //
   7668      // FieldDefinition : accessor ClassElementName Initializeropt
   7669      //
   7670      // Step 1. Let name be the result of evaluating ClassElementName.
   7671      // ...
   7672      // Step 3. Let privateStateDesc be the string-concatenation of name
   7673      // and " accessor storage".
   7674      StringBuilder privateStateDesc(fc_);
   7675      if (!privateStateDesc.append(this->parserAtoms(), propAtom)) {
   7676        return false;
   7677      }
   7678      if (!privateStateDesc.append(" accessor storage")) {
   7679        return false;
   7680      }
   7681      // Step 4. Let privateStateName be a new Private Name whose
   7682      // [[Description]] value is privateStateDesc.
   7683      TokenPos propNamePos(propNameOffset, pos().end);
   7684      auto privateStateName =
   7685          privateStateDesc.finishParserAtom(this->parserAtoms(), fc_);
   7686      if (!noteDeclaredPrivateName(
   7687              propName, privateStateName, propType,
   7688              isStatic ? FieldPlacement::Static : FieldPlacement::Instance,
   7689              propNamePos)) {
   7690        return false;
   7691      }
   7692 
   7693      // Step 5. Let getter be MakeAutoAccessorGetter(homeObject, name,
   7694      // privateStateName).
   7695      MOZ_TRY_VAR_OR_RETURN(
   7696          accessorGetterNode,
   7697          synthesizeAccessor(propName, propNamePos, propAtom, privateStateName,
   7698                             isStatic, FunctionSyntaxKind::Getter,
   7699                             classInitializedMembers),
   7700          false);
   7701 
   7702      // If the accessor is not decorated or is a non-static private field,
   7703      // add it to the class here. Otherwise, we'll handle this when the
   7704      // decorators are called. We don't need to keep a reference to the node
   7705      // after this except for non-static private accessors. Please see the
   7706      // comment in the definition of ClassField for details.
   7707      bool addAccessorImmediately =
   7708          !decorators || (!isStatic && handler_.isPrivateName(propName));
   7709      if (addAccessorImmediately) {
   7710        if (!handler_.addClassMemberDefinition(classMembers,
   7711                                               accessorGetterNode)) {
   7712          return false;
   7713        }
   7714        if (!handler_.isPrivateName(propName)) {
   7715          accessorGetterNode = null();
   7716        }
   7717      }
   7718 
   7719      // Step 6. Let setter be MakeAutoAccessorSetter(homeObject, name,
   7720      // privateStateName).
   7721      MOZ_TRY_VAR_OR_RETURN(
   7722          accessorSetterNode,
   7723          synthesizeAccessor(propName, propNamePos, propAtom, privateStateName,
   7724                             isStatic, FunctionSyntaxKind::Setter,
   7725                             classInitializedMembers),
   7726          false);
   7727 
   7728      if (addAccessorImmediately) {
   7729        if (!handler_.addClassMemberDefinition(classMembers,
   7730                                               accessorSetterNode)) {
   7731          return false;
   7732        }
   7733        if (!handler_.isPrivateName(propName)) {
   7734          accessorSetterNode = null();
   7735        }
   7736      }
   7737 
   7738      // Step 10. Return ClassElementDefinition Record { [[Key]]: name,
   7739      // [[Kind]]: accessor, [[Get]]: getter, [[Set]]: setter,
   7740      // [[BackingStorageKey]]: privateStateName, [[Initializers]]:
   7741      // initializers, [[Decorators]]: empty }.
   7742      MOZ_TRY_VAR_OR_RETURN(
   7743          propName, handler_.newPrivateName(privateStateName, pos()), false);
   7744      propAtom = privateStateName;
   7745      // We maintain `decorators` here to perform this step at the same time:
   7746      // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-static-semantics-classelementevaluation
   7747      // 4. Set fieldDefinition.[[Decorators]] to decorators.
   7748    }
   7749 #endif
   7750    if (isStatic) {
   7751      classInitializedMembers.staticFields++;
   7752    } else {
   7753      classInitializedMembers.instanceFields++;
   7754 #ifdef ENABLE_DECORATORS
   7755      if (decorators) {
   7756        classInitializedMembers.hasInstanceDecorators = true;
   7757      }
   7758 #endif
   7759    }
   7760 
   7761    TokenPos propNamePos(propNameOffset, pos().end);
   7762    FunctionNodeType initializer;
   7763    MOZ_TRY_VAR_OR_RETURN(
   7764        initializer,
   7765        fieldInitializerOpt(propNamePos, propName, propAtom,
   7766                            classInitializedMembers, isStatic, hasHeritage),
   7767        false);
   7768 
   7769    if (!matchOrInsertSemicolon(TokenStream::SlashIsInvalid)) {
   7770      return false;
   7771    }
   7772 
   7773    ClassFieldType field;
   7774    MOZ_TRY_VAR_OR_RETURN(field,
   7775                          handler_.newClassFieldDefinition(
   7776                              propName, initializer, isStatic
   7777 #ifdef ENABLE_DECORATORS
   7778                              ,
   7779                              decorators, accessorGetterNode, accessorSetterNode
   7780 #endif
   7781                              ),
   7782                          false);
   7783 
   7784    return handler_.addClassMemberDefinition(classMembers, field);
   7785  }
   7786 
   7787  if (propType != PropertyType::Getter && propType != PropertyType::Setter &&
   7788      propType != PropertyType::Method &&
   7789      propType != PropertyType::GeneratorMethod &&
   7790      propType != PropertyType::AsyncMethod &&
   7791      propType != PropertyType::AsyncGeneratorMethod) {
   7792    errorAt(propNameOffset, JSMSG_BAD_CLASS_MEMBER_DEF);
   7793    return false;
   7794  }
   7795 
   7796  bool isConstructor =
   7797      !isStatic && propAtom == TaggedParserAtomIndex::WellKnown::constructor();
   7798  if (isConstructor) {
   7799    if (propType != PropertyType::Method) {
   7800      errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
   7801      return false;
   7802    }
   7803    if (classStmt.constructorBox) {
   7804      errorAt(propNameOffset, JSMSG_DUPLICATE_CONSTRUCTOR);
   7805      return false;
   7806    }
   7807    propType = hasHeritage == HasHeritage::Yes
   7808                   ? PropertyType::DerivedConstructor
   7809                   : PropertyType::Constructor;
   7810  } else if (isStatic &&
   7811             propAtom == TaggedParserAtomIndex::WellKnown::prototype()) {
   7812    errorAt(propNameOffset, JSMSG_CLASS_STATIC_PROTO);
   7813    return false;
   7814  }
   7815 
   7816  TaggedParserAtomIndex funName;
   7817  switch (propType) {
   7818    case PropertyType::Getter:
   7819    case PropertyType::Setter: {
   7820      bool hasStaticName =
   7821          !anyChars.isCurrentTokenType(TokenKind::RightBracket) && propAtom;
   7822      if (hasStaticName) {
   7823        funName = prefixAccessorName(propType, propAtom);
   7824        if (!funName) {
   7825          return false;
   7826        }
   7827      }
   7828      break;
   7829    }
   7830    case PropertyType::Constructor:
   7831    case PropertyType::DerivedConstructor:
   7832      funName = className;
   7833      break;
   7834    default:
   7835      if (!anyChars.isCurrentTokenType(TokenKind::RightBracket)) {
   7836        funName = propAtom;
   7837      }
   7838  }
   7839 
   7840  // When |super()| is invoked, we search for the nearest scope containing
   7841  // |.initializers| to initialize the class fields. This set-up precludes
   7842  // declaring |.initializers| in the class scope, because in some syntactic
   7843  // contexts |super()| can appear nested in a class, while actually belonging
   7844  // to an outer class definition.
   7845  //
   7846  // Example:
   7847  // class Outer extends Base {
   7848  //   field = 1;
   7849  //   constructor() {
   7850  //     class Inner {
   7851  //       field = 2;
   7852  //
   7853  //       // The super() call in the computed property name mustn't access
   7854  //       // Inner's |.initializers| array, but instead Outer's.
   7855  //       [super()]() {}
   7856  //     }
   7857  //   }
   7858  // }
   7859  Maybe<ParseContext::Scope> dotInitializersScope;
   7860  if (isConstructor && !options().selfHostingMode) {
   7861    dotInitializersScope.emplace(this);
   7862    if (!dotInitializersScope->init(pc_)) {
   7863      return false;
   7864    }
   7865 
   7866    if (!noteDeclaredName(TaggedParserAtomIndex::WellKnown::dot_initializers_(),
   7867                          DeclarationKind::Let, pos())) {
   7868      return false;
   7869    }
   7870 
   7871 #ifdef ENABLE_DECORATORS
   7872    if (!noteDeclaredName(
   7873            TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_(),
   7874            DeclarationKind::Let, pos())) {
   7875      return false;
   7876    }
   7877 #endif
   7878  }
   7879 
   7880  // Calling toString on constructors need to return the source text for
   7881  // the entire class. The end offset is unknown at this point in
   7882  // parsing and will be amended when class parsing finishes below.
   7883  FunctionNodeType funNode;
   7884  MOZ_TRY_VAR_OR_RETURN(
   7885      funNode,
   7886      methodDefinition(isConstructor ? classStartOffset : propNameOffset,
   7887                       propType, funName),
   7888      false);
   7889 
   7890  AccessorType atype = ToAccessorType(propType);
   7891 
   7892  Maybe<FunctionNodeType> initializerIfPrivate = Nothing();
   7893  if (handler_.isPrivateName(propName)) {
   7894    if (propAtom == TaggedParserAtomIndex::WellKnown::hash_constructor_()) {
   7895      // #constructor is an invalid private name.
   7896      errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
   7897      return false;
   7898    }
   7899 
   7900    TaggedParserAtomIndex privateName = propAtom;
   7901    if (!noteDeclaredPrivateName(
   7902            propName, privateName, propType,
   7903            isStatic ? FieldPlacement::Static : FieldPlacement::Instance,
   7904            pos())) {
   7905      return false;
   7906    }
   7907 
   7908    // Private non-static methods are stored in the class body environment.
   7909    // Private non-static accessors are stamped onto every instance using
   7910    // initializers. Private static methods are stamped onto the constructor
   7911    // during class evaluation; see BytecodeEmitter::emitPropertyList.
   7912    if (!isStatic) {
   7913      if (atype == AccessorType::Getter || atype == AccessorType::Setter) {
   7914        classInitializedMembers.privateAccessors++;
   7915        TokenPos propNamePos(propNameOffset, pos().end);
   7916        FunctionNodeType initializerNode;
   7917        MOZ_TRY_VAR_OR_RETURN(
   7918            initializerNode,
   7919            synthesizePrivateMethodInitializer(propAtom, atype, propNamePos),
   7920            false);
   7921        initializerIfPrivate = Some(initializerNode);
   7922      } else {
   7923        MOZ_ASSERT(atype == AccessorType::None);
   7924        classInitializedMembers.privateMethods++;
   7925      }
   7926    }
   7927  }
   7928 
   7929 #ifdef ENABLE_DECORATORS
   7930  if (decorators) {
   7931    classInitializedMembers.hasInstanceDecorators = true;
   7932  }
   7933 #endif
   7934 
   7935  Node method;
   7936  MOZ_TRY_VAR_OR_RETURN(
   7937      method,
   7938      handler_.newClassMethodDefinition(propName, funNode, atype, isStatic,
   7939                                        initializerIfPrivate
   7940 #ifdef ENABLE_DECORATORS
   7941                                        ,
   7942                                        decorators
   7943 #endif
   7944                                        ),
   7945      false);
   7946 
   7947  if (dotInitializersScope.isSome()) {
   7948    MOZ_TRY_VAR_OR_RETURN(
   7949        method, finishLexicalScope(*dotInitializersScope, method), false);
   7950    dotInitializersScope.reset();
   7951  }
   7952 
   7953  return handler_.addClassMemberDefinition(classMembers, method);
   7954 }
   7955 
   7956 template <class ParseHandler, typename Unit>
   7957 bool GeneralParser<ParseHandler, Unit>::finishClassConstructor(
   7958    const ParseContext::ClassStatement& classStmt,
   7959    TaggedParserAtomIndex className, HasHeritage hasHeritage,
   7960    uint32_t classStartOffset, uint32_t classEndOffset,
   7961    const ClassInitializedMembers& classInitializedMembers,
   7962    ListNodeType& classMembers) {
   7963  if (classStmt.constructorBox == nullptr) {
   7964    MOZ_ASSERT(!options().selfHostingMode);
   7965    // Unconditionally create the scope here, because it's always the
   7966    // constructor.
   7967    ParseContext::Scope dotInitializersScope(this);
   7968    if (!dotInitializersScope.init(pc_)) {
   7969      return false;
   7970    }
   7971 
   7972    if (!noteDeclaredName(TaggedParserAtomIndex::WellKnown::dot_initializers_(),
   7973                          DeclarationKind::Let, pos())) {
   7974      return false;
   7975    }
   7976 
   7977 #ifdef ENABLE_DECORATORS
   7978    if (!noteDeclaredName(
   7979            TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_(),
   7980            DeclarationKind::Let, pos(), ClosedOver::Yes)) {
   7981      return false;
   7982    }
   7983 #endif
   7984 
   7985    // synthesizeConstructor assigns to classStmt.constructorBox
   7986    TokenPos synthesizedBodyPos(classStartOffset, classEndOffset);
   7987    FunctionNodeType synthesizedCtor;
   7988    MOZ_TRY_VAR_OR_RETURN(
   7989        synthesizedCtor,
   7990        synthesizeConstructor(className, synthesizedBodyPos, hasHeritage),
   7991        false);
   7992 
   7993    // Note: the *function* has the name of the class, but the *property*
   7994    // containing the function has the name "constructor"
   7995    Node constructorNameNode;
   7996    MOZ_TRY_VAR_OR_RETURN(
   7997        constructorNameNode,
   7998        handler_.newObjectLiteralPropertyName(
   7999            TaggedParserAtomIndex::WellKnown::constructor(), pos()),
   8000        false);
   8001    ClassMethodType method;
   8002    MOZ_TRY_VAR_OR_RETURN(method,
   8003                          handler_.newDefaultClassConstructor(
   8004                              constructorNameNode, synthesizedCtor),
   8005                          false);
   8006    LexicalScopeNodeType scope;
   8007    MOZ_TRY_VAR_OR_RETURN(
   8008        scope, finishLexicalScope(dotInitializersScope, method), false);
   8009    if (!handler_.addClassMemberDefinition(classMembers, scope)) {
   8010      return false;
   8011    }
   8012  }
   8013 
   8014  MOZ_ASSERT(classStmt.constructorBox);
   8015  FunctionBox* ctorbox = classStmt.constructorBox;
   8016 
   8017  // Amend the toStringEnd offset for the constructor now that we've
   8018  // finished parsing the class.
   8019  ctorbox->setCtorToStringEnd(classEndOffset);
   8020 
   8021  size_t numMemberInitializers = classInitializedMembers.privateAccessors +
   8022                                 classInitializedMembers.instanceFields;
   8023  bool hasPrivateBrand = classInitializedMembers.hasPrivateBrand();
   8024  if (hasPrivateBrand || numMemberInitializers > 0) {
   8025    // Now that we have full set of initializers, update the constructor.
   8026    MemberInitializers initializers(
   8027        hasPrivateBrand,
   8028 #ifdef ENABLE_DECORATORS
   8029        classInitializedMembers.hasInstanceDecorators,
   8030 #endif
   8031        numMemberInitializers);
   8032    ctorbox->setMemberInitializers(initializers);
   8033 
   8034    // Field initialization need access to `this`.
   8035    ctorbox->setCtorFunctionHasThisBinding();
   8036  }
   8037 
   8038  return true;
   8039 }
   8040 
   8041 template <class ParseHandler, typename Unit>
   8042 typename ParseHandler::ClassNodeResult
   8043 GeneralParser<ParseHandler, Unit>::classDefinition(
   8044    YieldHandling yieldHandling, ClassContext classContext,
   8045    DefaultHandling defaultHandling) {
   8046 #ifdef ENABLE_DECORATORS
   8047  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::At) ||
   8048             anyChars.isCurrentTokenType(TokenKind::Class));
   8049 
   8050  ListNodeType decorators = null();
   8051  FunctionNodeType addInitializerFunction = null();
   8052  if (anyChars.isCurrentTokenType(TokenKind::At)) {
   8053    decorators = MOZ_TRY(decoratorList(yieldHandling));
   8054    TokenKind next;
   8055    if (!tokenStream.getToken(&next)) {
   8056      return errorResult();
   8057    }
   8058    if (next != TokenKind::Class) {
   8059      error(JSMSG_CLASS_EXPECTED);
   8060      return errorResult();
   8061    }
   8062  }
   8063 #else
   8064  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Class));
   8065 #endif
   8066 
   8067  uint32_t classStartOffset = pos().begin;
   8068  bool savedStrictness = setLocalStrictMode(true);
   8069 
   8070  // Classes are quite broken in self-hosted code.
   8071  if (options().selfHostingMode) {
   8072    error(JSMSG_SELFHOSTED_CLASS);
   8073    return errorResult();
   8074  }
   8075 
   8076  TokenKind tt;
   8077  if (!tokenStream.getToken(&tt)) {
   8078    return errorResult();
   8079  }
   8080 
   8081  TaggedParserAtomIndex className;
   8082  if (TokenKindIsPossibleIdentifier(tt)) {
   8083    className = bindingIdentifier(yieldHandling);
   8084    if (!className) {
   8085      return errorResult();
   8086    }
   8087  } else if (classContext == ClassStatement) {
   8088    if (defaultHandling == AllowDefaultName) {
   8089      className = TaggedParserAtomIndex::WellKnown::default_();
   8090      anyChars.ungetToken();
   8091    } else {
   8092      // Class statements must have a bound name
   8093      error(JSMSG_UNNAMED_CLASS_STMT);
   8094      return errorResult();
   8095    }
   8096  } else {
   8097    // Make sure to put it back, whatever it was
   8098    anyChars.ungetToken();
   8099  }
   8100 
   8101  // Because the binding definitions keep track of their blockId, we need to
   8102  // create at least the inner binding later. Keep track of the name's
   8103  // position in order to provide it for the nodes created later.
   8104  TokenPos namePos = pos();
   8105 
   8106  auto isClass = [](ParseContext::Statement* stmt) {
   8107    return stmt->kind() == StatementKind::Class;
   8108  };
   8109 
   8110  bool isInClass = pc_->sc()->inClass() || pc_->findInnermostStatement(isClass);
   8111 
   8112  // Push a ParseContext::ClassStatement to keep track of the constructor
   8113  // funbox.
   8114  ParseContext::ClassStatement classStmt(pc_);
   8115 
   8116  NameNodeType innerName;
   8117  Node nameNode = null();
   8118  Node classHeritage = null();
   8119  LexicalScopeNodeType classBlock = null();
   8120  ClassBodyScopeNodeType classBodyBlock = null();
   8121  uint32_t classEndOffset;
   8122  {
   8123    // A named class creates a new lexical scope with a const binding of the
   8124    // class name for the "inner name".
   8125    ParseContext::Statement innerScopeStmt(pc_, StatementKind::Block);
   8126    ParseContext::Scope innerScope(this);
   8127    if (!innerScope.init(pc_)) {
   8128      return errorResult();
   8129    }
   8130 
   8131    bool hasHeritageBool;
   8132    if (!tokenStream.matchToken(&hasHeritageBool, TokenKind::Extends)) {
   8133      return errorResult();
   8134    }
   8135    HasHeritage hasHeritage =
   8136        hasHeritageBool ? HasHeritage::Yes : HasHeritage::No;
   8137    if (hasHeritage == HasHeritage::Yes) {
   8138      if (!tokenStream.getToken(&tt)) {
   8139        return errorResult();
   8140      }
   8141      classHeritage =
   8142          MOZ_TRY(optionalExpr(yieldHandling, TripledotProhibited, tt));
   8143    }
   8144 
   8145    if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_CLASS)) {
   8146      return errorResult();
   8147    }
   8148 
   8149    {
   8150      ParseContext::Statement bodyScopeStmt(pc_, StatementKind::Block);
   8151      ParseContext::Scope bodyScope(this);
   8152      if (!bodyScope.init(pc_)) {
   8153        return errorResult();
   8154      }
   8155 
   8156      ListNodeType classMembers =
   8157          MOZ_TRY(handler_.newClassMemberList(pos().begin));
   8158 
   8159      ClassInitializedMembers classInitializedMembers{};
   8160      for (;;) {
   8161        bool done;
   8162        if (!classMember(yieldHandling, classStmt, className, classStartOffset,
   8163                         hasHeritage, classInitializedMembers, classMembers,
   8164                         &done)) {
   8165          return errorResult();
   8166        }
   8167        if (done) {
   8168          break;
   8169        }
   8170      }
   8171 #ifdef ENABLE_DECORATORS
   8172      if (classInitializedMembers.hasInstanceDecorators) {
   8173        addInitializerFunction = MOZ_TRY(synthesizeAddInitializerFunction(
   8174            TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_(),
   8175            yieldHandling));
   8176      }
   8177 #endif
   8178 
   8179      if (classInitializedMembers.privateMethods +
   8180              classInitializedMembers.privateAccessors >
   8181          0) {
   8182        // We declare `.privateBrand` as ClosedOver because the constructor
   8183        // always uses it, even a default constructor. We could equivalently
   8184        // `noteUsedName` when parsing the constructor, except that at that
   8185        // time, we don't necessarily know if the class has a private brand.
   8186        if (!noteDeclaredName(
   8187                TaggedParserAtomIndex::WellKnown::dot_privateBrand_(),
   8188                DeclarationKind::Synthetic, namePos, ClosedOver::Yes)) {
   8189          return errorResult();
   8190        }
   8191      }
   8192 
   8193      if (classInitializedMembers.instanceFieldKeys > 0) {
   8194        if (!noteDeclaredName(
   8195                TaggedParserAtomIndex::WellKnown::dot_fieldKeys_(),
   8196                DeclarationKind::Synthetic, namePos)) {
   8197          return errorResult();
   8198        }
   8199      }
   8200 
   8201      if (classInitializedMembers.staticFields > 0) {
   8202        if (!noteDeclaredName(
   8203                TaggedParserAtomIndex::WellKnown::dot_staticInitializers_(),
   8204                DeclarationKind::Synthetic, namePos)) {
   8205          return errorResult();
   8206        }
   8207      }
   8208 
   8209      if (classInitializedMembers.staticFieldKeys > 0) {
   8210        if (!noteDeclaredName(
   8211                TaggedParserAtomIndex::WellKnown::dot_staticFieldKeys_(),
   8212                DeclarationKind::Synthetic, namePos)) {
   8213          return errorResult();
   8214        }
   8215      }
   8216 
   8217      classEndOffset = pos().end;
   8218      if (!finishClassConstructor(classStmt, className, hasHeritage,
   8219                                  classStartOffset, classEndOffset,
   8220                                  classInitializedMembers, classMembers)) {
   8221        return errorResult();
   8222      }
   8223 
   8224      classBodyBlock = MOZ_TRY(finishClassBodyScope(bodyScope, classMembers));
   8225 
   8226      // Pop the class body scope
   8227    }
   8228 
   8229    if (className) {
   8230      // The inner name is immutable.
   8231      if (!noteDeclaredName(className, DeclarationKind::Const, namePos)) {
   8232        return errorResult();
   8233      }
   8234 
   8235      innerName = MOZ_TRY(newName(className, namePos));
   8236    }
   8237 
   8238    classBlock = MOZ_TRY(finishLexicalScope(innerScope, classBodyBlock));
   8239 
   8240    // Pop the inner scope.
   8241  }
   8242 
   8243  if (className) {
   8244    NameNodeType outerName = null();
   8245    if (classContext == ClassStatement) {
   8246      // The outer name is mutable.
   8247      if (!noteDeclaredName(className, DeclarationKind::Class, namePos)) {
   8248        return errorResult();
   8249      }
   8250 
   8251      outerName = MOZ_TRY(newName(className, namePos));
   8252    }
   8253 
   8254    nameNode = MOZ_TRY(handler_.newClassNames(outerName, innerName, namePos));
   8255  }
   8256  MOZ_ALWAYS_TRUE(setLocalStrictMode(savedStrictness));
   8257  // We're leaving a class definition that was not itself nested within a class
   8258  if (!isInClass) {
   8259    mozilla::Maybe<UnboundPrivateName> maybeUnboundName;
   8260    if (!usedNames_.hasUnboundPrivateNames(fc_, maybeUnboundName)) {
   8261      return errorResult();
   8262    }
   8263    if (maybeUnboundName) {
   8264      UniqueChars str =
   8265          this->parserAtoms().toPrintableString(maybeUnboundName->atom);
   8266      if (!str) {
   8267        ReportOutOfMemory(this->fc_);
   8268        return errorResult();
   8269      }
   8270 
   8271      errorAt(maybeUnboundName->position.begin, JSMSG_MISSING_PRIVATE_DECL,
   8272              str.get());
   8273      return errorResult();
   8274    }
   8275  }
   8276 
   8277  return handler_.newClass(nameNode, classHeritage, classBlock,
   8278 #ifdef ENABLE_DECORATORS
   8279                           decorators, addInitializerFunction,
   8280 #endif
   8281                           TokenPos(classStartOffset, classEndOffset));
   8282 }
   8283 
   8284 template <class ParseHandler, typename Unit>
   8285 typename ParseHandler::FunctionNodeResult
   8286 GeneralParser<ParseHandler, Unit>::synthesizeConstructor(
   8287    TaggedParserAtomIndex className, TokenPos synthesizedBodyPos,
   8288    HasHeritage hasHeritage) {
   8289  FunctionSyntaxKind functionSyntaxKind =
   8290      hasHeritage == HasHeritage::Yes
   8291          ? FunctionSyntaxKind::DerivedClassConstructor
   8292          : FunctionSyntaxKind::ClassConstructor;
   8293 
   8294  bool isSelfHosting = options().selfHostingMode;
   8295  FunctionFlags flags =
   8296      InitialFunctionFlags(functionSyntaxKind, GeneratorKind::NotGenerator,
   8297                           FunctionAsyncKind::SyncFunction, isSelfHosting);
   8298 
   8299  // Create the top-level field initializer node.
   8300  FunctionNodeType funNode =
   8301      MOZ_TRY(handler_.newFunction(functionSyntaxKind, synthesizedBodyPos));
   8302 
   8303  // If we see any inner function, note it on our current context. The bytecode
   8304  // emitter may eliminate the function later, but we use a conservative
   8305  // definition for consistency between lazy and full parsing.
   8306  pc_->sc()->setHasInnerFunctions();
   8307 
   8308  // When fully parsing a lazy script, we do not fully reparse its inner
   8309  // functions, which are also lazy. Instead, their free variables and source
   8310  // extents are recorded and may be skipped.
   8311  if (handler_.reuseLazyInnerFunctions()) {
   8312    if (!skipLazyInnerFunction(funNode, synthesizedBodyPos.begin,
   8313                               /* tryAnnexB = */ false)) {
   8314      return errorResult();
   8315    }
   8316 
   8317    return funNode;
   8318  }
   8319 
   8320  // Create the FunctionBox and link it to the function object.
   8321  Directives directives(true);
   8322  FunctionBox* funbox = newFunctionBox(
   8323      funNode, className, flags, synthesizedBodyPos.begin, directives,
   8324      GeneratorKind::NotGenerator, FunctionAsyncKind::SyncFunction);
   8325  if (!funbox) {
   8326    return errorResult();
   8327  }
   8328  funbox->initWithEnclosingParseContext(pc_, functionSyntaxKind);
   8329  setFunctionEndFromCurrentToken(funbox);
   8330 
   8331  // Mark this function as being synthesized by the parser. This means special
   8332  // handling in delazification will be used since we don't have typical
   8333  // function syntax.
   8334  funbox->setSyntheticFunction();
   8335 
   8336  // Push a SourceParseContext on to the stack.
   8337  ParseContext* outerpc = pc_;
   8338  SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
   8339  if (!funpc.init()) {
   8340    return errorResult();
   8341  }
   8342 
   8343  if (!synthesizeConstructorBody(synthesizedBodyPos, hasHeritage, funNode,
   8344                                 funbox)) {
   8345    return errorResult();
   8346  }
   8347 
   8348  if (!leaveInnerFunction(outerpc)) {
   8349    return errorResult();
   8350  }
   8351 
   8352  return funNode;
   8353 }
   8354 
   8355 template <class ParseHandler, typename Unit>
   8356 bool GeneralParser<ParseHandler, Unit>::synthesizeConstructorBody(
   8357    TokenPos synthesizedBodyPos, HasHeritage hasHeritage,
   8358    FunctionNodeType funNode, FunctionBox* funbox) {
   8359  MOZ_ASSERT(funbox->isClassConstructor());
   8360 
   8361  // Create a ParamsBodyNode for the parameters + body (there are no
   8362  // parameters).
   8363  ParamsBodyNodeType argsbody;
   8364  MOZ_TRY_VAR_OR_RETURN(argsbody, handler_.newParamsBody(synthesizedBodyPos),
   8365                        false);
   8366  handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
   8367  setFunctionStartAtPosition(funbox, synthesizedBodyPos);
   8368 
   8369  if (hasHeritage == HasHeritage::Yes) {
   8370    // Synthesize the equivalent to `function f(...args)`
   8371    funbox->setHasRest();
   8372    if (!notePositionalFormalParameter(
   8373            funNode, TaggedParserAtomIndex::WellKnown::dot_args_(),
   8374            synthesizedBodyPos.begin,
   8375            /* disallowDuplicateParams = */ false,
   8376            /* duplicatedParam = */ nullptr)) {
   8377      return false;
   8378    }
   8379    funbox->setArgCount(1);
   8380  } else {
   8381    funbox->setArgCount(0);
   8382  }
   8383 
   8384  pc_->functionScope().useAsVarScope(pc_);
   8385 
   8386  ListNodeType stmtList;
   8387  MOZ_TRY_VAR_OR_RETURN(stmtList, handler_.newStatementList(synthesizedBodyPos),
   8388                        false);
   8389 
   8390  if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_this_())) {
   8391    return false;
   8392  }
   8393 
   8394  if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
   8395    return false;
   8396  }
   8397 
   8398 #ifdef ENABLE_DECORATORS
   8399  if (!noteUsedName(
   8400          TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_())) {
   8401    return false;
   8402  }
   8403 #endif
   8404 
   8405  if (hasHeritage == HasHeritage::Yes) {
   8406    // |super()| implicitly reads |new.target|.
   8407    if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_newTarget_())) {
   8408      return false;
   8409    }
   8410 
   8411    NameNodeType thisName;
   8412    MOZ_TRY_VAR_OR_RETURN(thisName, newThisName(), false);
   8413 
   8414    UnaryNodeType superBase;
   8415    MOZ_TRY_VAR_OR_RETURN(
   8416        superBase, handler_.newSuperBase(thisName, synthesizedBodyPos), false);
   8417 
   8418    ListNodeType arguments;
   8419    MOZ_TRY_VAR_OR_RETURN(arguments, handler_.newArguments(synthesizedBodyPos),
   8420                          false);
   8421 
   8422    NameNodeType argsNameNode;
   8423    MOZ_TRY_VAR_OR_RETURN(argsNameNode,
   8424                          newName(TaggedParserAtomIndex::WellKnown::dot_args_(),
   8425                                  synthesizedBodyPos),
   8426                          false);
   8427    if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_args_())) {
   8428      return false;
   8429    }
   8430 
   8431    UnaryNodeType spreadArgs;
   8432    MOZ_TRY_VAR_OR_RETURN(
   8433        spreadArgs, handler_.newSpread(synthesizedBodyPos.begin, argsNameNode),
   8434        false);
   8435    handler_.addList(arguments, spreadArgs);
   8436 
   8437    CallNodeType superCall;
   8438    MOZ_TRY_VAR_OR_RETURN(
   8439        superCall,
   8440        handler_.newSuperCall(superBase, arguments, /* isSpread = */ true),
   8441        false);
   8442 
   8443    BinaryNodeType setThis;
   8444    MOZ_TRY_VAR_OR_RETURN(setThis, handler_.newSetThis(thisName, superCall),
   8445                          false);
   8446 
   8447    UnaryNodeType exprStatement;
   8448    MOZ_TRY_VAR_OR_RETURN(
   8449        exprStatement,
   8450        handler_.newExprStatement(setThis, synthesizedBodyPos.end), false);
   8451 
   8452    handler_.addStatementToList(stmtList, exprStatement);
   8453  }
   8454 
   8455  bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
   8456  if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
   8457    return false;
   8458  }
   8459  if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
   8460    return false;
   8461  }
   8462 
   8463  LexicalScopeNodeType initializerBody;
   8464  MOZ_TRY_VAR_OR_RETURN(
   8465      initializerBody,
   8466      finishLexicalScope(pc_->varScope(), stmtList, ScopeKind::FunctionLexical),
   8467      false);
   8468  handler_.setBeginPosition(initializerBody, stmtList);
   8469  handler_.setEndPosition(initializerBody, stmtList);
   8470 
   8471  handler_.setFunctionBody(funNode, initializerBody);
   8472 
   8473  return finishFunction();
   8474 }
   8475 
   8476 template <class ParseHandler, typename Unit>
   8477 typename ParseHandler::FunctionNodeResult
   8478 GeneralParser<ParseHandler, Unit>::privateMethodInitializer(
   8479    TokenPos propNamePos, TaggedParserAtomIndex propAtom,
   8480    TaggedParserAtomIndex storedMethodAtom) {
   8481  if (!abortIfSyntaxParser()) {
   8482    return errorResult();
   8483  }
   8484 
   8485  // Synthesize an initializer function that the constructor can use to stamp a
   8486  // private method onto an instance object.
   8487  FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::FieldInitializer;
   8488  FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
   8489  GeneratorKind generatorKind = GeneratorKind::NotGenerator;
   8490  bool isSelfHosting = options().selfHostingMode;
   8491  FunctionFlags flags =
   8492      InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
   8493 
   8494  FunctionNodeType funNode =
   8495      MOZ_TRY(handler_.newFunction(syntaxKind, propNamePos));
   8496 
   8497  Directives directives(true);
   8498  FunctionBox* funbox =
   8499      newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags,
   8500                     propNamePos.begin, directives, generatorKind, asyncKind);
   8501  if (!funbox) {
   8502    return errorResult();
   8503  }
   8504  funbox->initWithEnclosingParseContext(pc_, syntaxKind);
   8505 
   8506  // Push a SourceParseContext on to the stack.
   8507  ParseContext* outerpc = pc_;
   8508  SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
   8509  if (!funpc.init()) {
   8510    return errorResult();
   8511  }
   8512  pc_->functionScope().useAsVarScope(pc_);
   8513 
   8514  // Add empty parameter list.
   8515  ParamsBodyNodeType argsbody = MOZ_TRY(handler_.newParamsBody(propNamePos));
   8516  handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
   8517  setFunctionStartAtCurrentToken(funbox);
   8518  funbox->setArgCount(0);
   8519 
   8520  // Note both the stored private method body and it's private name as being
   8521  // used in the initializer. They will be emitted into the method body in the
   8522  // BCE.
   8523  if (!noteUsedName(storedMethodAtom)) {
   8524    return errorResult();
   8525  }
   8526  MOZ_TRY(privateNameReference(propAtom));
   8527 
   8528  // Unlike field initializers, private method initializers are not created with
   8529  // a body of synthesized AST nodes. Instead, the body is left empty and the
   8530  // initializer is synthesized at the bytecode level.
   8531  // See BytecodeEmitter::emitPrivateMethodInitializer.
   8532  ListNodeType stmtList = MOZ_TRY(handler_.newStatementList(propNamePos));
   8533 
   8534  bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
   8535  if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
   8536    return errorResult();
   8537  }
   8538  if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
   8539    return errorResult();
   8540  }
   8541 
   8542  LexicalScopeNodeType initializerBody = MOZ_TRY(finishLexicalScope(
   8543      pc_->varScope(), stmtList, ScopeKind::FunctionLexical));
   8544  handler_.setBeginPosition(initializerBody, stmtList);
   8545  handler_.setEndPosition(initializerBody, stmtList);
   8546  handler_.setFunctionBody(funNode, initializerBody);
   8547 
   8548  // Set field-initializer lambda boundary to start at property name and end
   8549  // after method body.
   8550  setFunctionStartAtPosition(funbox, propNamePos);
   8551  setFunctionEndFromCurrentToken(funbox);
   8552 
   8553  if (!finishFunction()) {
   8554    return errorResult();
   8555  }
   8556 
   8557  if (!leaveInnerFunction(outerpc)) {
   8558    return errorResult();
   8559  }
   8560 
   8561  return funNode;
   8562 }
   8563 
   8564 template <class ParseHandler, typename Unit>
   8565 typename ParseHandler::FunctionNodeResult
   8566 GeneralParser<ParseHandler, Unit>::staticClassBlock(
   8567    ClassInitializedMembers& classInitializedMembers) {
   8568  // Both for getting-this-done, and because this will invariably be executed,
   8569  // syntax parsing should be aborted.
   8570  if (!abortIfSyntaxParser()) {
   8571    return errorResult();
   8572  }
   8573 
   8574  FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::StaticClassBlock;
   8575  FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
   8576  GeneratorKind generatorKind = GeneratorKind::NotGenerator;
   8577  bool isSelfHosting = options().selfHostingMode;
   8578  FunctionFlags flags =
   8579      InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
   8580 
   8581  AutoAwaitIsKeyword awaitIsKeyword(this, AwaitHandling::AwaitIsDisallowed);
   8582 
   8583  // Create the function node for the static class body.
   8584  FunctionNodeType funNode = MOZ_TRY(handler_.newFunction(syntaxKind, pos()));
   8585 
   8586  // Create the FunctionBox and link it to the function object.
   8587  Directives directives(true);
   8588  FunctionBox* funbox =
   8589      newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags, pos().begin,
   8590                     directives, generatorKind, asyncKind);
   8591  if (!funbox) {
   8592    return errorResult();
   8593  }
   8594  funbox->initWithEnclosingParseContext(pc_, syntaxKind);
   8595  MOZ_ASSERT(funbox->isSyntheticFunction());
   8596  MOZ_ASSERT(!funbox->allowSuperCall());
   8597  MOZ_ASSERT(!funbox->allowArguments());
   8598  MOZ_ASSERT(!funbox->allowReturn());
   8599 
   8600  // Set start at `static` token.
   8601  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Static));
   8602  setFunctionStartAtCurrentToken(funbox);
   8603 
   8604  // Push a SourceParseContext on to the stack.
   8605  ParseContext* outerpc = pc_;
   8606  SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
   8607  if (!funpc.init()) {
   8608    return errorResult();
   8609  }
   8610 
   8611  pc_->functionScope().useAsVarScope(pc_);
   8612 
   8613  uint32_t start = pos().begin;
   8614 
   8615  tokenStream.consumeKnownToken(TokenKind::LeftCurly);
   8616 
   8617  // Static class blocks are code-generated as if they were static field
   8618  // initializers, so we bump the staticFields count here, which ensures
   8619  // .staticInitializers is noted as used.
   8620  classInitializedMembers.staticFields++;
   8621 
   8622  LexicalScopeNodeType body =
   8623      MOZ_TRY(functionBody(InHandling::InAllowed, YieldHandling::YieldIsKeyword,
   8624                           syntaxKind, FunctionBodyType::StatementListBody));
   8625 
   8626  if (anyChars.isEOF()) {
   8627    error(JSMSG_UNTERMINATED_STATIC_CLASS_BLOCK);
   8628    return errorResult();
   8629  }
   8630 
   8631  tokenStream.consumeKnownToken(TokenKind::RightCurly,
   8632                                TokenStream::Modifier::SlashIsRegExp);
   8633 
   8634  TokenPos wholeBodyPos(start, pos().end);
   8635 
   8636  handler_.setEndPosition(funNode, wholeBodyPos.end);
   8637  setFunctionEndFromCurrentToken(funbox);
   8638 
   8639  // Create a ParamsBodyNode for the parameters + body (there are no
   8640  // parameters).
   8641  ParamsBodyNodeType argsbody = MOZ_TRY(handler_.newParamsBody(wholeBodyPos));
   8642 
   8643  handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
   8644  funbox->setArgCount(0);
   8645 
   8646  if (pc_->superScopeNeedsHomeObject()) {
   8647    funbox->setNeedsHomeObject();
   8648  }
   8649 
   8650  handler_.setEndPosition(body, pos().begin);
   8651  handler_.setEndPosition(funNode, pos().end);
   8652  handler_.setFunctionBody(funNode, body);
   8653 
   8654  if (!finishFunction()) {
   8655    return errorResult();
   8656  }
   8657 
   8658  if (!leaveInnerFunction(outerpc)) {
   8659    return errorResult();
   8660  }
   8661 
   8662  return funNode;
   8663 }
   8664 
   8665 template <class ParseHandler, typename Unit>
   8666 typename ParseHandler::FunctionNodeResult
   8667 GeneralParser<ParseHandler, Unit>::fieldInitializerOpt(
   8668    TokenPos propNamePos, Node propName, TaggedParserAtomIndex propAtom,
   8669    ClassInitializedMembers& classInitializedMembers, bool isStatic,
   8670    HasHeritage hasHeritage) {
   8671  if (!abortIfSyntaxParser()) {
   8672    return errorResult();
   8673  }
   8674 
   8675  bool hasInitializer = false;
   8676  if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
   8677                              TokenStream::SlashIsDiv)) {
   8678    return errorResult();
   8679  }
   8680 
   8681  FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::FieldInitializer;
   8682  FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
   8683  GeneratorKind generatorKind = GeneratorKind::NotGenerator;
   8684  bool isSelfHosting = options().selfHostingMode;
   8685  FunctionFlags flags =
   8686      InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
   8687 
   8688  // Create the top-level field initializer node.
   8689  FunctionNodeType funNode =
   8690      MOZ_TRY(handler_.newFunction(syntaxKind, propNamePos));
   8691 
   8692  // Create the FunctionBox and link it to the function object.
   8693  Directives directives(true);
   8694  FunctionBox* funbox =
   8695      newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags,
   8696                     propNamePos.begin, directives, generatorKind, asyncKind);
   8697  if (!funbox) {
   8698    return errorResult();
   8699  }
   8700  funbox->initWithEnclosingParseContext(pc_, syntaxKind);
   8701  MOZ_ASSERT(funbox->isSyntheticFunction());
   8702 
   8703  // We can't use setFunctionStartAtCurrentToken because that uses pos().begin,
   8704  // which is incorrect for fields without initializers (pos() points to the
   8705  // field identifier)
   8706  setFunctionStartAtPosition(funbox, propNamePos);
   8707 
   8708  // Push a SourceParseContext on to the stack.
   8709  ParseContext* outerpc = pc_;
   8710  SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
   8711  if (!funpc.init()) {
   8712    return errorResult();
   8713  }
   8714 
   8715  pc_->functionScope().useAsVarScope(pc_);
   8716 
   8717  Node initializerExpr;
   8718  if (hasInitializer) {
   8719    // Parse the expression for the field initializer.
   8720    {
   8721      AutoAwaitIsKeyword awaitHandling(this, AwaitIsName);
   8722      initializerExpr =
   8723          MOZ_TRY(assignExpr(InAllowed, YieldIsName, TripledotProhibited));
   8724    }
   8725 
   8726    handler_.checkAndSetIsDirectRHSAnonFunction(initializerExpr);
   8727  } else {
   8728    initializerExpr = MOZ_TRY(handler_.newRawUndefinedLiteral(propNamePos));
   8729  }
   8730 
   8731  TokenPos wholeInitializerPos(propNamePos.begin, pos().end);
   8732 
   8733  // Update the end position of the parse node.
   8734  handler_.setEndPosition(funNode, wholeInitializerPos.end);
   8735  setFunctionEndFromCurrentToken(funbox);
   8736 
   8737  // Create a ParamsBodyNode for the parameters + body (there are no
   8738  // parameters).
   8739  ParamsBodyNodeType argsbody =
   8740      MOZ_TRY(handler_.newParamsBody(wholeInitializerPos));
   8741  handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
   8742  funbox->setArgCount(0);
   8743 
   8744  NameNodeType thisName = MOZ_TRY(newThisName());
   8745 
   8746  // Build `this.field` expression.
   8747  ThisLiteralType propAssignThis =
   8748      MOZ_TRY(handler_.newThisLiteral(wholeInitializerPos, thisName));
   8749 
   8750  Node propAssignFieldAccess;
   8751  uint32_t indexValue;
   8752  if (!propAtom) {
   8753    // See BytecodeEmitter::emitCreateFieldKeys for an explanation of what
   8754    // .fieldKeys means and its purpose.
   8755    NameNodeType fieldKeysName;
   8756    if (isStatic) {
   8757      fieldKeysName = MOZ_TRY(newInternalDotName(
   8758          TaggedParserAtomIndex::WellKnown::dot_staticFieldKeys_()));
   8759    } else {
   8760      fieldKeysName = MOZ_TRY(newInternalDotName(
   8761          TaggedParserAtomIndex::WellKnown::dot_fieldKeys_()));
   8762    }
   8763    if (!fieldKeysName) {
   8764      return errorResult();
   8765    }
   8766 
   8767    double fieldKeyIndex;
   8768    if (isStatic) {
   8769      fieldKeyIndex = classInitializedMembers.staticFieldKeys++;
   8770    } else {
   8771      fieldKeyIndex = classInitializedMembers.instanceFieldKeys++;
   8772    }
   8773    Node fieldKeyIndexNode = MOZ_TRY(handler_.newNumber(
   8774        fieldKeyIndex, DecimalPoint::NoDecimal, wholeInitializerPos));
   8775 
   8776    Node fieldKeyValue = MOZ_TRY(handler_.newPropertyByValue(
   8777        fieldKeysName, fieldKeyIndexNode, wholeInitializerPos.end));
   8778 
   8779    propAssignFieldAccess = MOZ_TRY(handler_.newPropertyByValue(
   8780        propAssignThis, fieldKeyValue, wholeInitializerPos.end));
   8781  } else if (handler_.isPrivateName(propName)) {
   8782    // It would be nice if we could tweak this here such that only if
   8783    // HasHeritage::Yes we end up emitting CheckPrivateField, but otherwise we
   8784    // emit InitElem -- this is an optimization to minimize HasOwn checks
   8785    // in InitElem for classes without heritage.
   8786    //
   8787    // Further tweaking would be to ultimately only do CheckPrivateField for the
   8788    // -first- field in a derived class, which would suffice to match the
   8789    // semantic check.
   8790 
   8791    NameNodeType privateNameNode = MOZ_TRY(privateNameReference(propAtom));
   8792 
   8793    propAssignFieldAccess = MOZ_TRY(handler_.newPrivateMemberAccess(
   8794        propAssignThis, privateNameNode, wholeInitializerPos.end));
   8795  } else if (this->parserAtoms().isIndex(propAtom, &indexValue)) {
   8796    propAssignFieldAccess = MOZ_TRY(handler_.newPropertyByValue(
   8797        propAssignThis, propName, wholeInitializerPos.end));
   8798  } else {
   8799    NameNodeType propAssignName =
   8800        MOZ_TRY(handler_.newPropertyName(propAtom, wholeInitializerPos));
   8801 
   8802    propAssignFieldAccess =
   8803        MOZ_TRY(handler_.newPropertyAccess(propAssignThis, propAssignName));
   8804  }
   8805 
   8806  // Synthesize an property init.
   8807  BinaryNodeType initializerPropInit =
   8808      MOZ_TRY(handler_.newInitExpr(propAssignFieldAccess, initializerExpr));
   8809 
   8810  UnaryNodeType exprStatement = MOZ_TRY(
   8811      handler_.newExprStatement(initializerPropInit, wholeInitializerPos.end));
   8812 
   8813  ListNodeType statementList =
   8814      MOZ_TRY(handler_.newStatementList(wholeInitializerPos));
   8815  handler_.addStatementToList(statementList, exprStatement);
   8816 
   8817  bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
   8818  if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
   8819    return errorResult();
   8820  }
   8821  if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
   8822    return errorResult();
   8823  }
   8824 
   8825  // Set the function's body to the field assignment.
   8826  LexicalScopeNodeType initializerBody = MOZ_TRY(finishLexicalScope(
   8827      pc_->varScope(), statementList, ScopeKind::FunctionLexical));
   8828 
   8829  handler_.setFunctionBody(funNode, initializerBody);
   8830 
   8831  if (pc_->superScopeNeedsHomeObject()) {
   8832    funbox->setNeedsHomeObject();
   8833  }
   8834 
   8835  if (!finishFunction()) {
   8836    return errorResult();
   8837  }
   8838 
   8839  if (!leaveInnerFunction(outerpc)) {
   8840    return errorResult();
   8841  }
   8842 
   8843  return funNode;
   8844 }
   8845 
   8846 template <class ParseHandler, typename Unit>
   8847 typename ParseHandler::FunctionNodeResult
   8848 GeneralParser<ParseHandler, Unit>::synthesizePrivateMethodInitializer(
   8849    TaggedParserAtomIndex propAtom, AccessorType accessorType,
   8850    TokenPos propNamePos) {
   8851  if (!abortIfSyntaxParser()) {
   8852    return errorResult();
   8853  }
   8854 
   8855  // Synthesize a name for the lexical variable that will store the
   8856  // accessor body.
   8857  StringBuilder storedMethodName(fc_);
   8858  if (!storedMethodName.append(this->parserAtoms(), propAtom)) {
   8859    return errorResult();
   8860  }
   8861  if (!storedMethodName.append(
   8862          accessorType == AccessorType::Getter ? ".getter" : ".setter")) {
   8863    return errorResult();
   8864  }
   8865  auto storedMethodProp =
   8866      storedMethodName.finishParserAtom(this->parserAtoms(), fc_);
   8867  if (!storedMethodProp) {
   8868    return errorResult();
   8869  }
   8870  if (!noteDeclaredName(storedMethodProp, DeclarationKind::Synthetic, pos())) {
   8871    return errorResult();
   8872  }
   8873 
   8874  return privateMethodInitializer(propNamePos, propAtom, storedMethodProp);
   8875 }
   8876 
   8877 #ifdef ENABLE_DECORATORS
   8878 template <class ParseHandler, typename Unit>
   8879 typename ParseHandler::FunctionNodeResult
   8880 GeneralParser<ParseHandler, Unit>::synthesizeAddInitializerFunction(
   8881    TaggedParserAtomIndex initializers, YieldHandling yieldHandling) {
   8882  if (!abortIfSyntaxParser()) {
   8883    return errorResult();
   8884  }
   8885 
   8886  // TODO: Add support for static and class extra initializers, see bug 1868220
   8887  // and bug 1868221.
   8888  MOZ_ASSERT(
   8889      initializers ==
   8890      TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_());
   8891 
   8892  TokenPos propNamePos = pos();
   8893 
   8894  // Synthesize an addInitializer function that can be used to append to
   8895  // .initializers
   8896  FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Statement;
   8897  FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
   8898  GeneratorKind generatorKind = GeneratorKind::NotGenerator;
   8899  bool isSelfHosting = options().selfHostingMode;
   8900  FunctionFlags flags =
   8901      InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
   8902 
   8903  FunctionNodeType funNode =
   8904      MOZ_TRY(handler_.newFunction(syntaxKind, propNamePos));
   8905 
   8906  Directives directives(true);
   8907  FunctionBox* funbox =
   8908      newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags,
   8909                     propNamePos.begin, directives, generatorKind, asyncKind);
   8910  if (!funbox) {
   8911    return errorResult();
   8912  }
   8913  funbox->initWithEnclosingParseContext(pc_, syntaxKind);
   8914 
   8915  ParseContext* outerpc = pc_;
   8916  SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
   8917  if (!funpc.init()) {
   8918    return errorResult();
   8919  }
   8920  pc_->functionScope().useAsVarScope(pc_);
   8921 
   8922  // Takes a single parameter, `initializer`.
   8923  ParamsBodyNodeType params = MOZ_TRY(handler_.newParamsBody(propNamePos));
   8924 
   8925  handler_.setFunctionFormalParametersAndBody(funNode, params);
   8926 
   8927  constexpr bool disallowDuplicateParams = true;
   8928  bool duplicatedParam = false;
   8929  if (!notePositionalFormalParameter(
   8930          funNode, TaggedParserAtomIndex::WellKnown::initializer(), pos().begin,
   8931          disallowDuplicateParams, &duplicatedParam)) {
   8932    return null();
   8933  }
   8934  MOZ_ASSERT(!duplicatedParam);
   8935  MOZ_ASSERT(pc_->positionalFormalParameterNames().length() == 1);
   8936 
   8937  funbox->setLength(1);
   8938  funbox->setArgCount(1);
   8939  setFunctionStartAtCurrentToken(funbox);
   8940 
   8941  // Like private method initializers, the addInitializer method is not created
   8942  // with a body of synthesized AST nodes. Instead, the body is left empty and
   8943  // the initializer is synthesized at the bytecode level. See
   8944  // DecoratorEmitter::emitCreateAddInitializerFunction.
   8945  ListNodeType stmtList = MOZ_TRY(handler_.newStatementList(propNamePos));
   8946 
   8947  if (!noteUsedName(initializers)) {
   8948    return null();
   8949  }
   8950 
   8951  bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
   8952  if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
   8953    return null();
   8954  }
   8955  if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
   8956    return null();
   8957  }
   8958 
   8959  LexicalScopeNodeType addInitializerBody = MOZ_TRY(finishLexicalScope(
   8960      pc_->varScope(), stmtList, ScopeKind::FunctionLexical));
   8961  handler_.setBeginPosition(addInitializerBody, stmtList);
   8962  handler_.setEndPosition(addInitializerBody, stmtList);
   8963  handler_.setFunctionBody(funNode, addInitializerBody);
   8964 
   8965  // Set field-initializer lambda boundary to start at property name and end
   8966  // after method body.
   8967  setFunctionStartAtPosition(funbox, propNamePos);
   8968  setFunctionEndFromCurrentToken(funbox);
   8969 
   8970  if (!finishFunction()) {
   8971    return errorResult();
   8972  }
   8973 
   8974  if (!leaveInnerFunction(outerpc)) {
   8975    return errorResult();
   8976  }
   8977 
   8978  return funNode;
   8979 }
   8980 
   8981 template <class ParseHandler, typename Unit>
   8982 typename ParseHandler::ClassMethodResult
   8983 GeneralParser<ParseHandler, Unit>::synthesizeAccessor(
   8984    Node propName, TokenPos propNamePos, TaggedParserAtomIndex propAtom,
   8985    TaggedParserAtomIndex privateStateNameAtom, bool isStatic,
   8986    FunctionSyntaxKind syntaxKind,
   8987    ClassInitializedMembers& classInitializedMembers) {
   8988  // Decorators Proposal
   8989  // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
   8990  // The abstract operation MakeAutoAccessorGetter takes arguments homeObject
   8991  // (an Object), name (a property key or Private Name), and privateStateName (a
   8992  // Private Name) and returns a function object.
   8993  //
   8994  // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
   8995  // The abstract operation MakeAutoAccessorSetter takes arguments homeObject
   8996  // (an Object), name (a property key or Private Name), and privateStateName (a
   8997  // Private Name) and returns a function object.
   8998  if (!abortIfSyntaxParser()) {
   8999    return errorResult();
   9000  }
   9001 
   9002  AccessorType accessorType = syntaxKind == FunctionSyntaxKind::Getter
   9003                                  ? AccessorType::Getter
   9004                                  : AccessorType::Setter;
   9005 
   9006  mozilla::Maybe<FunctionNodeType> initializerIfPrivate = Nothing();
   9007  if (!isStatic && handler_.isPrivateName(propName)) {
   9008    classInitializedMembers.privateAccessors++;
   9009    FunctionNodeType initializerNode =
   9010        MOZ_TRY(synthesizePrivateMethodInitializer(propAtom, accessorType,
   9011                                                   propNamePos));
   9012    initializerIfPrivate = Some(initializerNode);
   9013    handler_.setPrivateNameKind(propName, PrivateNameKind::GetterSetter);
   9014  }
   9015 
   9016  // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
   9017  // 2. Let getter be CreateBuiltinFunction(getterClosure, 0, "get", « »).
   9018  //
   9019  // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
   9020  // 2. Let setter be CreateBuiltinFunction(setterClosure, 1, "set", « »).
   9021  StringBuilder storedMethodName(fc_);
   9022  if (!storedMethodName.append(accessorType == AccessorType::Getter ? "get"
   9023                                                                    : "set")) {
   9024    return errorResult();
   9025  }
   9026  TaggedParserAtomIndex funNameAtom =
   9027      storedMethodName.finishParserAtom(this->parserAtoms(), fc_);
   9028 
   9029  FunctionNodeType funNode = MOZ_TRY(synthesizeAccessorBody(
   9030      funNameAtom, propNamePos, privateStateNameAtom, syntaxKind));
   9031 
   9032  // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
   9033  // 3. Perform MakeMethod(getter, homeObject).
   9034  // 4. Return getter.
   9035  //
   9036  // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
   9037  // 3. Perform MakeMethod(setter, homeObject).
   9038  // 4. Return setter.
   9039  return handler_.newClassMethodDefinition(
   9040      propName, funNode, accessorType, isStatic, initializerIfPrivate, null());
   9041 }
   9042 
   9043 template <class ParseHandler, typename Unit>
   9044 typename ParseHandler::FunctionNodeResult
   9045 GeneralParser<ParseHandler, Unit>::synthesizeAccessorBody(
   9046    TaggedParserAtomIndex funNameAtom, TokenPos propNamePos,
   9047    TaggedParserAtomIndex propNameAtom, FunctionSyntaxKind syntaxKind) {
   9048  if (!abortIfSyntaxParser()) {
   9049    return errorResult();
   9050  }
   9051 
   9052  FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
   9053  GeneratorKind generatorKind = GeneratorKind::NotGenerator;
   9054  bool isSelfHosting = options().selfHostingMode;
   9055  FunctionFlags flags =
   9056      InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
   9057 
   9058  // Create the top-level function node.
   9059  FunctionNodeType funNode =
   9060      MOZ_TRY(handler_.newFunction(syntaxKind, propNamePos));
   9061 
   9062  // Create the FunctionBox and link it to the function object.
   9063  Directives directives(true);
   9064  FunctionBox* funbox =
   9065      newFunctionBox(funNode, funNameAtom, flags, propNamePos.begin, directives,
   9066                     generatorKind, asyncKind);
   9067  if (!funbox) {
   9068    return errorResult();
   9069  }
   9070  funbox->initWithEnclosingParseContext(pc_, syntaxKind);
   9071  funbox->setSyntheticFunction();
   9072 
   9073  // Push a SourceParseContext on to the stack.
   9074  ParseContext* outerpc = pc_;
   9075  SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
   9076  if (!funpc.init()) {
   9077    return errorResult();
   9078  }
   9079 
   9080  pc_->functionScope().useAsVarScope(pc_);
   9081 
   9082  // The function we synthesize is located at the field with the
   9083  // accessor.
   9084  setFunctionStartAtCurrentToken(funbox);
   9085  setFunctionEndFromCurrentToken(funbox);
   9086 
   9087  // Create a ListNode for the parameters + body
   9088  ParamsBodyNodeType paramsbody = MOZ_TRY(handler_.newParamsBody(propNamePos));
   9089  handler_.setFunctionFormalParametersAndBody(funNode, paramsbody);
   9090 
   9091  if (syntaxKind == FunctionSyntaxKind::Getter) {
   9092    funbox->setArgCount(0);
   9093  } else {
   9094    funbox->setArgCount(1);
   9095  }
   9096 
   9097  // Build `this` expression to access the privateStateName for use in the
   9098  // operations to create the getter and setter below.
   9099  NameNodeType thisName = MOZ_TRY(newThisName());
   9100 
   9101  ThisLiteralType propThis =
   9102      MOZ_TRY(handler_.newThisLiteral(propNamePos, thisName));
   9103 
   9104  NameNodeType privateNameNode = MOZ_TRY(privateNameReference(propNameAtom));
   9105 
   9106  Node propFieldAccess = MOZ_TRY(handler_.newPrivateMemberAccess(
   9107      propThis, privateNameNode, propNamePos.end));
   9108 
   9109  Node accessorBody;
   9110  if (syntaxKind == FunctionSyntaxKind::Getter) {
   9111    // Decorators Proposal
   9112    // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
   9113    // 1. Let getterClosure be a new Abstract Closure with no parameters that
   9114    // captures privateStateName and performs the following steps when called:
   9115    //  1.a. Let o be the this value.
   9116    //  1.b. Return ? PrivateGet(privateStateName, o).
   9117    accessorBody =
   9118        MOZ_TRY(handler_.newReturnStatement(propFieldAccess, propNamePos));
   9119  } else {
   9120    // Decorators Proposal
   9121    // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
   9122    // The abstract operation MakeAutoAccessorSetter takes arguments homeObject
   9123    // (an Object), name (a property key or Private Name), and privateStateName
   9124    // (a Private Name) and returns a function object.
   9125    // 1. Let setterClosure be a new Abstract Closure with parameters (value)
   9126    // that captures privateStateName and performs the following steps when
   9127    // called:
   9128    //   1.a. Let o be the this value.
   9129    notePositionalFormalParameter(funNode,
   9130                                  TaggedParserAtomIndex::WellKnown::value(),
   9131                                  /* pos = */ 0, false,
   9132                                  /* duplicatedParam = */ nullptr);
   9133 
   9134    Node initializerExpr = MOZ_TRY(handler_.newName(
   9135        TaggedParserAtomIndex::WellKnown::value(), propNamePos));
   9136 
   9137    //   1.b. Perform ? PrivateSet(privateStateName, o, value).
   9138    Node assignment = MOZ_TRY(handler_.newAssignment(
   9139        ParseNodeKind::AssignExpr, propFieldAccess, initializerExpr));
   9140 
   9141    accessorBody =
   9142        MOZ_TRY(handler_.newExprStatement(assignment, propNamePos.end));
   9143 
   9144    //   1.c. Return undefined.
   9145  }
   9146 
   9147  ListNodeType statementList = MOZ_TRY(handler_.newStatementList(propNamePos));
   9148  handler_.addStatementToList(statementList, accessorBody);
   9149 
   9150  bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
   9151  if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
   9152    return errorResult();
   9153  }
   9154  if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
   9155    return errorResult();
   9156  }
   9157 
   9158  LexicalScopeNodeType initializerBody = MOZ_TRY(finishLexicalScope(
   9159      pc_->varScope(), statementList, ScopeKind::FunctionLexical));
   9160 
   9161  handler_.setFunctionBody(funNode, initializerBody);
   9162 
   9163  if (pc_->superScopeNeedsHomeObject()) {
   9164    funbox->setNeedsHomeObject();
   9165  }
   9166 
   9167  if (!finishFunction()) {
   9168    return errorResult();
   9169  }
   9170 
   9171  if (!leaveInnerFunction(outerpc)) {
   9172    return errorResult();
   9173  }
   9174 
   9175  return funNode;
   9176 }
   9177 
   9178 #endif
   9179 
   9180 bool ParserBase::nextTokenContinuesLetDeclaration(TokenKind next) {
   9181  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Let));
   9182  MOZ_ASSERT(anyChars.nextToken().type == next);
   9183 
   9184  TokenStreamShared::verifyConsistentModifier(TokenStreamShared::SlashIsDiv,
   9185                                              anyChars.nextToken());
   9186 
   9187  // Destructuring continues a let declaration.
   9188  if (next == TokenKind::LeftBracket || next == TokenKind::LeftCurly) {
   9189    return true;
   9190  }
   9191 
   9192  // A "let" edge case deserves special comment.  Consider this:
   9193  //
   9194  //   let     // not an ASI opportunity
   9195  //   let;
   9196  //
   9197  // Static semantics in §13.3.1.1 turn a LexicalDeclaration that binds
   9198  // "let" into an early error.  Does this retroactively permit ASI so
   9199  // that we should parse this as two ExpressionStatements?   No.  ASI
   9200  // resolves during parsing.  Static semantics only apply to the full
   9201  // parse tree with ASI applied.  No backsies!
   9202 
   9203  // Otherwise a let declaration must have a name.
   9204  return TokenKindIsPossibleIdentifier(next);
   9205 }
   9206 
   9207 template <class ParseHandler, typename Unit>
   9208 typename ParseHandler::DeclarationListNodeResult
   9209 GeneralParser<ParseHandler, Unit>::variableStatement(
   9210    YieldHandling yieldHandling) {
   9211  DeclarationListNodeType vars =
   9212      MOZ_TRY(declarationList(yieldHandling, ParseNodeKind::VarStmt));
   9213  if (!matchOrInsertSemicolon()) {
   9214    return errorResult();
   9215  }
   9216  return vars;
   9217 }
   9218 
   9219 template <class ParseHandler, typename Unit>
   9220 typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::statement(
   9221    YieldHandling yieldHandling) {
   9222  MOZ_ASSERT(checkOptionsCalled_);
   9223 
   9224  AutoCheckRecursionLimit recursion(this->fc_);
   9225  if (!recursion.check(this->fc_)) {
   9226    return errorResult();
   9227  }
   9228 
   9229  TokenKind tt;
   9230  if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
   9231    return errorResult();
   9232  }
   9233 
   9234  switch (tt) {
   9235    // BlockStatement[?Yield, ?Return]
   9236    case TokenKind::LeftCurly:
   9237      return blockStatement(yieldHandling);
   9238 
   9239    // VariableStatement[?Yield]
   9240    case TokenKind::Var:
   9241      return variableStatement(yieldHandling);
   9242 
   9243    // EmptyStatement
   9244    case TokenKind::Semi:
   9245      return handler_.newEmptyStatement(pos());
   9246 
   9247      // ExpressionStatement[?Yield].
   9248 
   9249    case TokenKind::Yield: {
   9250      // Don't use a ternary operator here due to obscure linker issues
   9251      // around using static consts in the arms of a ternary.
   9252      Modifier modifier;
   9253      if (yieldExpressionsSupported()) {
   9254        modifier = TokenStream::SlashIsRegExp;
   9255      } else {
   9256        modifier = TokenStream::SlashIsDiv;
   9257      }
   9258 
   9259      TokenKind next;
   9260      if (!tokenStream.peekToken(&next, modifier)) {
   9261        return errorResult();
   9262      }
   9263 
   9264      if (next == TokenKind::Colon) {
   9265        return labeledStatement(yieldHandling);
   9266      }
   9267 
   9268      return expressionStatement(yieldHandling);
   9269    }
   9270 
   9271    default: {
   9272      // If we encounter an await in a module, and the module is not marked
   9273      // as async, mark the module as async.
   9274      if (tt == TokenKind::Await && !pc_->isAsync()) {
   9275        if (pc_->atModuleTopLevel()) {
   9276          if (!options().topLevelAwait) {
   9277            error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
   9278            return errorResult();
   9279          }
   9280          pc_->sc()->asModuleContext()->setIsAsync();
   9281          MOZ_ASSERT(pc_->isAsync());
   9282        }
   9283      }
   9284 
   9285      // Avoid getting next token with SlashIsDiv.
   9286      if (tt == TokenKind::Await && pc_->isAsync()) {
   9287        return expressionStatement(yieldHandling);
   9288      }
   9289 
   9290      if (!TokenKindIsPossibleIdentifier(tt)) {
   9291        return expressionStatement(yieldHandling);
   9292      }
   9293 
   9294      TokenKind next;
   9295      if (!tokenStream.peekToken(&next)) {
   9296        return errorResult();
   9297      }
   9298 
   9299      // |let| here can only be an Identifier, not a declaration.  Give nicer
   9300      // errors for declaration-looking typos.
   9301      if (tt == TokenKind::Let) {
   9302        bool forbiddenLetDeclaration = false;
   9303 
   9304        if (next == TokenKind::LeftBracket) {
   9305          // Enforce ExpressionStatement's 'let [' lookahead restriction.
   9306          forbiddenLetDeclaration = true;
   9307        } else if (next == TokenKind::LeftCurly ||
   9308                   TokenKindIsPossibleIdentifier(next)) {
   9309          // 'let {' and 'let foo' aren't completely forbidden, if ASI
   9310          // causes 'let' to be the entire Statement.  But if they're
   9311          // same-line, we can aggressively give a better error message.
   9312          //
   9313          // Note that this ignores 'yield' as TokenKind::Yield: we'll handle it
   9314          // correctly but with a worse error message.
   9315          TokenKind nextSameLine;
   9316          if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
   9317            return errorResult();
   9318          }
   9319 
   9320          MOZ_ASSERT(TokenKindIsPossibleIdentifier(nextSameLine) ||
   9321                     nextSameLine == TokenKind::LeftCurly ||
   9322                     nextSameLine == TokenKind::Eol);
   9323 
   9324          forbiddenLetDeclaration = nextSameLine != TokenKind::Eol;
   9325        }
   9326 
   9327        if (forbiddenLetDeclaration) {
   9328          error(JSMSG_FORBIDDEN_AS_STATEMENT, "lexical declarations");
   9329          return errorResult();
   9330        }
   9331      } else if (tt == TokenKind::Async) {
   9332        // Peek only on the same line: ExpressionStatement's lookahead
   9333        // restriction is phrased as
   9334        //
   9335        //   [lookahead ∉ { '{',
   9336        //                  function,
   9337        //                  async [no LineTerminator here] function,
   9338        //                  class,
   9339        //                  let '[' }]
   9340        //
   9341        // meaning that code like this is valid:
   9342        //
   9343        //   if (true)
   9344        //     async       // ASI opportunity
   9345        //   function clownshoes() {}
   9346        TokenKind maybeFunction;
   9347        if (!tokenStream.peekTokenSameLine(&maybeFunction)) {
   9348          return errorResult();
   9349        }
   9350 
   9351        if (maybeFunction == TokenKind::Function) {
   9352          error(JSMSG_FORBIDDEN_AS_STATEMENT, "async function declarations");
   9353          return errorResult();
   9354        }
   9355 
   9356        // Otherwise this |async| begins an ExpressionStatement or is a
   9357        // label name.
   9358      }
   9359 
   9360      // NOTE: It's unfortunately allowed to have a label named 'let' in
   9361      //       non-strict code.  💯
   9362      if (next == TokenKind::Colon) {
   9363        return labeledStatement(yieldHandling);
   9364      }
   9365 
   9366      return expressionStatement(yieldHandling);
   9367    }
   9368 
   9369    case TokenKind::New:
   9370      return expressionStatement(yieldHandling, PredictInvoked);
   9371 
   9372    // IfStatement[?Yield, ?Return]
   9373    case TokenKind::If:
   9374      return ifStatement(yieldHandling);
   9375 
   9376    // BreakableStatement[?Yield, ?Return]
   9377    //
   9378    // BreakableStatement[Yield, Return]:
   9379    //   IterationStatement[?Yield, ?Return]
   9380    //   SwitchStatement[?Yield, ?Return]
   9381    case TokenKind::Do:
   9382      return doWhileStatement(yieldHandling);
   9383 
   9384    case TokenKind::While:
   9385      return whileStatement(yieldHandling);
   9386 
   9387    case TokenKind::For:
   9388      return forStatement(yieldHandling);
   9389 
   9390    case TokenKind::Switch:
   9391      return switchStatement(yieldHandling);
   9392 
   9393    // ContinueStatement[?Yield]
   9394    case TokenKind::Continue:
   9395      return continueStatement(yieldHandling);
   9396 
   9397    // BreakStatement[?Yield]
   9398    case TokenKind::Break:
   9399      return breakStatement(yieldHandling);
   9400 
   9401    // [+Return] ReturnStatement[?Yield]
   9402    case TokenKind::Return:
   9403      // The Return parameter is only used here, and the effect is easily
   9404      // detected this way, so don't bother passing around an extra parameter
   9405      // everywhere.
   9406      if (!pc_->allowReturn()) {
   9407        error(JSMSG_BAD_RETURN_OR_YIELD, "return");
   9408        return errorResult();
   9409      }
   9410      return returnStatement(yieldHandling);
   9411 
   9412    // WithStatement[?Yield, ?Return]
   9413    case TokenKind::With:
   9414      return withStatement(yieldHandling);
   9415 
   9416    // LabelledStatement[?Yield, ?Return]
   9417    // This is really handled by default and TokenKind::Yield cases above.
   9418 
   9419    // ThrowStatement[?Yield]
   9420    case TokenKind::Throw:
   9421      return throwStatement(yieldHandling);
   9422 
   9423    // TryStatement[?Yield, ?Return]
   9424    case TokenKind::Try:
   9425      return tryStatement(yieldHandling);
   9426 
   9427    // DebuggerStatement
   9428    case TokenKind::Debugger:
   9429      return debuggerStatement();
   9430 
   9431    // |function| is forbidden by lookahead restriction (unless as child
   9432    // statement of |if| or |else|, but Parser::consequentOrAlternative
   9433    // handles that).
   9434    case TokenKind::Function:
   9435      error(JSMSG_FORBIDDEN_AS_STATEMENT, "function declarations");
   9436      return errorResult();
   9437 
   9438    // |class| is also forbidden by lookahead restriction.
   9439    case TokenKind::Class:
   9440      error(JSMSG_FORBIDDEN_AS_STATEMENT, "classes");
   9441      return errorResult();
   9442 
   9443    // ImportDeclaration (only inside modules)
   9444    case TokenKind::Import:
   9445      return importDeclarationOrImportExpr(yieldHandling);
   9446 
   9447    // ExportDeclaration (only inside modules)
   9448    case TokenKind::Export:
   9449      return exportDeclaration();
   9450 
   9451      // Miscellaneous error cases arguably better caught here than elsewhere.
   9452 
   9453    case TokenKind::Catch:
   9454      error(JSMSG_CATCH_WITHOUT_TRY);
   9455      return errorResult();
   9456 
   9457    case TokenKind::Finally:
   9458      error(JSMSG_FINALLY_WITHOUT_TRY);
   9459      return errorResult();
   9460 
   9461      // NOTE: default case handled in the ExpressionStatement section.
   9462  }
   9463 }
   9464 
   9465 template <class ParseHandler, typename Unit>
   9466 typename ParseHandler::NodeResult
   9467 GeneralParser<ParseHandler, Unit>::statementListItem(
   9468    YieldHandling yieldHandling, bool canHaveDirectives /* = false */) {
   9469  MOZ_ASSERT(checkOptionsCalled_);
   9470 
   9471  AutoCheckRecursionLimit recursion(this->fc_);
   9472  if (!recursion.check(this->fc_)) {
   9473    return errorResult();
   9474  }
   9475 
   9476  TokenKind tt;
   9477  if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
   9478    return errorResult();
   9479  }
   9480 
   9481  switch (tt) {
   9482    // BlockStatement[?Yield, ?Return]
   9483    case TokenKind::LeftCurly:
   9484      return blockStatement(yieldHandling);
   9485 
   9486    // VariableStatement[?Yield]
   9487    case TokenKind::Var:
   9488      return variableStatement(yieldHandling);
   9489 
   9490    // EmptyStatement
   9491    case TokenKind::Semi:
   9492      return handler_.newEmptyStatement(pos());
   9493 
   9494    // ExpressionStatement[?Yield].
   9495    //
   9496    // These should probably be handled by a single ExpressionStatement
   9497    // function in a default, not split up this way.
   9498    case TokenKind::String:
   9499      if (!canHaveDirectives &&
   9500          anyChars.currentToken().atom() ==
   9501              TaggedParserAtomIndex::WellKnown::use_asm_()) {
   9502        if (!warning(JSMSG_USE_ASM_DIRECTIVE_FAIL)) {
   9503          return errorResult();
   9504        }
   9505      }
   9506      return expressionStatement(yieldHandling);
   9507 
   9508    case TokenKind::Yield: {
   9509      // Don't use a ternary operator here due to obscure linker issues
   9510      // around using static consts in the arms of a ternary.
   9511      Modifier modifier;
   9512      if (yieldExpressionsSupported()) {
   9513        modifier = TokenStream::SlashIsRegExp;
   9514      } else {
   9515        modifier = TokenStream::SlashIsDiv;
   9516      }
   9517 
   9518      TokenKind next;
   9519      if (!tokenStream.peekToken(&next, modifier)) {
   9520        return errorResult();
   9521      }
   9522 
   9523      if (next == TokenKind::Colon) {
   9524        return labeledStatement(yieldHandling);
   9525      }
   9526 
   9527      return expressionStatement(yieldHandling);
   9528    }
   9529 
   9530    default: {
   9531      // If we encounter an await in a module, and the module is not marked
   9532      // as async, mark the module as async.
   9533      if (tt == TokenKind::Await && !pc_->isAsync()) {
   9534        if (pc_->atModuleTopLevel()) {
   9535          if (!options().topLevelAwait) {
   9536            error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
   9537            return errorResult();
   9538          }
   9539          pc_->sc()->asModuleContext()->setIsAsync();
   9540          MOZ_ASSERT(pc_->isAsync());
   9541        }
   9542      }
   9543 
   9544      if (tt == TokenKind::Await && pc_->isAsync()) {
   9545 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   9546        if (options().explicitResourceManagement()) {
   9547          // Try finding evidence of a AwaitUsingDeclaration the syntax for
   9548          // which
   9549          // would be:
   9550          //   await [no LineTerminator here] using [no LineTerminator here]
   9551          //     identifier
   9552 
   9553          TokenKind nextTokUsing = TokenKind::Eof;
   9554          // Scan with regex modifier because when its await expression, `/`
   9555          // should be treated as a regexp.
   9556          if (!tokenStream.peekTokenSameLine(&nextTokUsing,
   9557                                             TokenStream::SlashIsRegExp)) {
   9558            return errorResult();
   9559          }
   9560 
   9561          if (nextTokUsing == TokenKind::Using &&
   9562              this->pc_->isUsingSyntaxAllowed()) {
   9563            tokenStream.consumeKnownToken(nextTokUsing,
   9564                                          TokenStream::SlashIsRegExp);
   9565            TokenKind nextTokIdentifier = TokenKind::Eof;
   9566            // Here we can use the Div modifier because if the next token is
   9567            // using then a `/` as the next token can only be considered a
   9568            // division.
   9569            if (!tokenStream.peekTokenSameLine(&nextTokIdentifier)) {
   9570              return errorResult();
   9571            }
   9572            if (TokenKindIsPossibleIdentifier(nextTokIdentifier)) {
   9573              return lexicalDeclaration(yieldHandling,
   9574                                        DeclarationKind::AwaitUsing);
   9575            }
   9576            anyChars.ungetToken();  // put back using.
   9577          }
   9578        }
   9579 #endif
   9580        return expressionStatement(yieldHandling);
   9581      }
   9582 
   9583      if (!TokenKindIsPossibleIdentifier(tt)) {
   9584        return expressionStatement(yieldHandling);
   9585      }
   9586 
   9587      TokenKind next;
   9588      if (!tokenStream.peekToken(&next)) {
   9589        return errorResult();
   9590      }
   9591 
   9592      if (tt == TokenKind::Let && nextTokenContinuesLetDeclaration(next)) {
   9593        return lexicalDeclaration(yieldHandling, DeclarationKind::Let);
   9594      }
   9595 
   9596      if (tt == TokenKind::Async) {
   9597        TokenKind nextSameLine = TokenKind::Eof;
   9598        if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
   9599          return errorResult();
   9600        }
   9601        if (nextSameLine == TokenKind::Function) {
   9602          uint32_t toStringStart = pos().begin;
   9603          tokenStream.consumeKnownToken(TokenKind::Function);
   9604          return functionStmt(toStringStart, yieldHandling, NameRequired,
   9605                              FunctionAsyncKind::AsyncFunction);
   9606        }
   9607      }
   9608 
   9609      if (next == TokenKind::Colon) {
   9610        return labeledStatement(yieldHandling);
   9611      }
   9612 
   9613      return expressionStatement(yieldHandling);
   9614    }
   9615 
   9616    case TokenKind::New:
   9617      return expressionStatement(yieldHandling, PredictInvoked);
   9618 
   9619    // IfStatement[?Yield, ?Return]
   9620    case TokenKind::If:
   9621      return ifStatement(yieldHandling);
   9622 
   9623    // BreakableStatement[?Yield, ?Return]
   9624    //
   9625    // BreakableStatement[Yield, Return]:
   9626    //   IterationStatement[?Yield, ?Return]
   9627    //   SwitchStatement[?Yield, ?Return]
   9628    case TokenKind::Do:
   9629      return doWhileStatement(yieldHandling);
   9630 
   9631    case TokenKind::While:
   9632      return whileStatement(yieldHandling);
   9633 
   9634    case TokenKind::For:
   9635      return forStatement(yieldHandling);
   9636 
   9637    case TokenKind::Switch:
   9638      return switchStatement(yieldHandling);
   9639 
   9640    // ContinueStatement[?Yield]
   9641    case TokenKind::Continue:
   9642      return continueStatement(yieldHandling);
   9643 
   9644    // BreakStatement[?Yield]
   9645    case TokenKind::Break:
   9646      return breakStatement(yieldHandling);
   9647 
   9648    // [+Return] ReturnStatement[?Yield]
   9649    case TokenKind::Return:
   9650      // The Return parameter is only used here, and the effect is easily
   9651      // detected this way, so don't bother passing around an extra parameter
   9652      // everywhere.
   9653      if (!pc_->allowReturn()) {
   9654        error(JSMSG_BAD_RETURN_OR_YIELD, "return");
   9655        return errorResult();
   9656      }
   9657      return returnStatement(yieldHandling);
   9658 
   9659    // WithStatement[?Yield, ?Return]
   9660    case TokenKind::With:
   9661      return withStatement(yieldHandling);
   9662 
   9663    // LabelledStatement[?Yield, ?Return]
   9664    // This is really handled by default and TokenKind::Yield cases above.
   9665 
   9666    // ThrowStatement[?Yield]
   9667    case TokenKind::Throw:
   9668      return throwStatement(yieldHandling);
   9669 
   9670    // TryStatement[?Yield, ?Return]
   9671    case TokenKind::Try:
   9672      return tryStatement(yieldHandling);
   9673 
   9674    // DebuggerStatement
   9675    case TokenKind::Debugger:
   9676      return debuggerStatement();
   9677 
   9678    // Declaration[Yield]:
   9679 
   9680    //   HoistableDeclaration[?Yield, ~Default]
   9681    case TokenKind::Function:
   9682      return functionStmt(pos().begin, yieldHandling, NameRequired);
   9683 
   9684      //   DecoratorList[?Yield, ?Await] opt ClassDeclaration[?Yield, ~Default]
   9685 #ifdef ENABLE_DECORATORS
   9686    case TokenKind::At:
   9687      return classDefinition(yieldHandling, ClassStatement, NameRequired);
   9688 #endif
   9689 
   9690    case TokenKind::Class:
   9691      return classDefinition(yieldHandling, ClassStatement, NameRequired);
   9692 
   9693    //   LexicalDeclaration[In, ?Yield]
   9694    //     LetOrConst BindingList[?In, ?Yield]
   9695    case TokenKind::Const:
   9696      // [In] is the default behavior, because for-loops specially parse
   9697      // their heads to handle |in| in this situation.
   9698      return lexicalDeclaration(yieldHandling, DeclarationKind::Const);
   9699 
   9700 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   9701    case TokenKind::Using: {
   9702      TokenKind nextTok = TokenKind::Eol;
   9703      if (!tokenStream.peekTokenSameLine(&nextTok)) {
   9704        return errorResult();
   9705      }
   9706      if (!options().explicitResourceManagement() ||
   9707          !TokenKindIsPossibleIdentifier(nextTok) ||
   9708          !this->pc_->isUsingSyntaxAllowed()) {
   9709        if (!tokenStream.peekToken(&nextTok)) {
   9710          return errorResult();
   9711        }
   9712        // labelled statement could be like using\n:\nexpr
   9713        if (nextTok == TokenKind::Colon) {
   9714          return labeledStatement(yieldHandling);
   9715        }
   9716        return expressionStatement(yieldHandling);
   9717      }
   9718      return lexicalDeclaration(yieldHandling, DeclarationKind::Using);
   9719    }
   9720 #endif
   9721 
   9722    // ImportDeclaration (only inside modules)
   9723    case TokenKind::Import:
   9724      return importDeclarationOrImportExpr(yieldHandling);
   9725 
   9726    // ExportDeclaration (only inside modules)
   9727    case TokenKind::Export:
   9728      return exportDeclaration();
   9729 
   9730      // Miscellaneous error cases arguably better caught here than elsewhere.
   9731 
   9732    case TokenKind::Catch:
   9733      error(JSMSG_CATCH_WITHOUT_TRY);
   9734      return errorResult();
   9735 
   9736    case TokenKind::Finally:
   9737      error(JSMSG_FINALLY_WITHOUT_TRY);
   9738      return errorResult();
   9739 
   9740      // NOTE: default case handled in the ExpressionStatement section.
   9741  }
   9742 }
   9743 
   9744 template <class ParseHandler, typename Unit>
   9745 typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::expr(
   9746    InHandling inHandling, YieldHandling yieldHandling,
   9747    TripledotHandling tripledotHandling,
   9748    PossibleError* possibleError /* = nullptr */,
   9749    InvokedPrediction invoked /* = PredictUninvoked */) {
   9750  Node pn = MOZ_TRY(assignExpr(inHandling, yieldHandling, tripledotHandling,
   9751                               possibleError, invoked));
   9752 
   9753  bool matched;
   9754  if (!tokenStream.matchToken(&matched, TokenKind::Comma,
   9755                              TokenStream::SlashIsRegExp)) {
   9756    return errorResult();
   9757  }
   9758  if (!matched) {
   9759    return pn;
   9760  }
   9761 
   9762  ListNodeType seq = MOZ_TRY(handler_.newCommaExpressionList(pn));
   9763  while (true) {
   9764    // Trailing comma before the closing parenthesis is valid in an arrow
   9765    // function parameters list: `(a, b, ) => body`. Check if we are
   9766    // directly under CoverParenthesizedExpressionAndArrowParameterList,
   9767    // and the next two tokens are closing parenthesis and arrow. If all
   9768    // are present allow the trailing comma.
   9769    if (tripledotHandling == TripledotAllowed) {
   9770      TokenKind tt;
   9771      if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
   9772        return errorResult();
   9773      }
   9774 
   9775      if (tt == TokenKind::RightParen) {
   9776        tokenStream.consumeKnownToken(TokenKind::RightParen,
   9777                                      TokenStream::SlashIsRegExp);
   9778 
   9779        if (!tokenStream.peekToken(&tt)) {
   9780          return errorResult();
   9781        }
   9782        if (tt != TokenKind::Arrow) {
   9783          error(JSMSG_UNEXPECTED_TOKEN, "expression",
   9784                TokenKindToDesc(TokenKind::RightParen));
   9785          return errorResult();
   9786        }
   9787 
   9788        anyChars.ungetToken();  // put back right paren
   9789        break;
   9790      }
   9791    }
   9792 
   9793    // Additional calls to assignExpr should not reuse the possibleError
   9794    // which had been passed into the function. Otherwise we would lose
   9795    // information needed to determine whether or not we're dealing with
   9796    // a non-recoverable situation.
   9797    PossibleError possibleErrorInner(*this);
   9798    pn = MOZ_TRY(assignExpr(inHandling, yieldHandling, tripledotHandling,
   9799                            &possibleErrorInner));
   9800 
   9801    if (!possibleError) {
   9802      // Report any pending expression error.
   9803      if (!possibleErrorInner.checkForExpressionError()) {
   9804        return errorResult();
   9805      }
   9806    } else {
   9807      possibleErrorInner.transferErrorsTo(possibleError);
   9808    }
   9809 
   9810    handler_.addList(seq, pn);
   9811 
   9812    if (!tokenStream.matchToken(&matched, TokenKind::Comma,
   9813                                TokenStream::SlashIsRegExp)) {
   9814      return errorResult();
   9815    }
   9816    if (!matched) {
   9817      break;
   9818    }
   9819  }
   9820  return seq;
   9821 }
   9822 
   9823 static ParseNodeKind BinaryOpTokenKindToParseNodeKind(TokenKind tok) {
   9824  MOZ_ASSERT(TokenKindIsBinaryOp(tok));
   9825  return ParseNodeKind(size_t(ParseNodeKind::BinOpFirst) +
   9826                       (size_t(tok) - size_t(TokenKind::BinOpFirst)));
   9827 }
   9828 
   9829 // This list must be kept in the same order in several places:
   9830 //   - The binary operators in ParseNode.h ,
   9831 //   - the binary operators in TokenKind.h
   9832 //   - the JSOp code list in BytecodeEmitter.cpp
   9833 static const int PrecedenceTable[] = {
   9834    1,  /* ParseNodeKind::Coalesce */
   9835    2,  /* ParseNodeKind::Or */
   9836    3,  /* ParseNodeKind::And */
   9837    4,  /* ParseNodeKind::BitOr */
   9838    5,  /* ParseNodeKind::BitXor */
   9839    6,  /* ParseNodeKind::BitAnd */
   9840    7,  /* ParseNodeKind::StrictEq */
   9841    7,  /* ParseNodeKind::Eq */
   9842    7,  /* ParseNodeKind::StrictNe */
   9843    7,  /* ParseNodeKind::Ne */
   9844    8,  /* ParseNodeKind::Lt */
   9845    8,  /* ParseNodeKind::Le */
   9846    8,  /* ParseNodeKind::Gt */
   9847    8,  /* ParseNodeKind::Ge */
   9848    8,  /* ParseNodeKind::InstanceOf */
   9849    8,  /* ParseNodeKind::In */
   9850    8,  /* ParseNodeKind::PrivateIn */
   9851    9,  /* ParseNodeKind::Lsh */
   9852    9,  /* ParseNodeKind::Rsh */
   9853    9,  /* ParseNodeKind::Ursh */
   9854    10, /* ParseNodeKind::Add */
   9855    10, /* ParseNodeKind::Sub */
   9856    11, /* ParseNodeKind::Star */
   9857    11, /* ParseNodeKind::Div */
   9858    11, /* ParseNodeKind::Mod */
   9859    12  /* ParseNodeKind::Pow */
   9860 };
   9861 
   9862 static const int PRECEDENCE_CLASSES = 12;
   9863 
   9864 static int Precedence(ParseNodeKind pnk) {
   9865  // Everything binds tighter than ParseNodeKind::Limit, because we want
   9866  // to reduce all nodes to a single node when we reach a token that is not
   9867  // another binary operator.
   9868  if (pnk == ParseNodeKind::Limit) {
   9869    return 0;
   9870  }
   9871 
   9872  MOZ_ASSERT(pnk >= ParseNodeKind::BinOpFirst);
   9873  MOZ_ASSERT(pnk <= ParseNodeKind::BinOpLast);
   9874  return PrecedenceTable[size_t(pnk) - size_t(ParseNodeKind::BinOpFirst)];
   9875 }
   9876 
   9877 enum class EnforcedParentheses : uint8_t { CoalesceExpr, AndOrExpr, None };
   9878 
   9879 template <class ParseHandler, typename Unit>
   9880 MOZ_ALWAYS_INLINE typename ParseHandler::NodeResult
   9881 GeneralParser<ParseHandler, Unit>::orExpr(InHandling inHandling,
   9882                                          YieldHandling yieldHandling,
   9883                                          TripledotHandling tripledotHandling,
   9884                                          PossibleError* possibleError,
   9885                                          InvokedPrediction invoked) {
   9886  // Shift-reduce parser for the binary operator part of the JS expression
   9887  // syntax.
   9888 
   9889  // Conceptually there's just one stack, a stack of pairs (lhs, op).
   9890  // It's implemented using two separate arrays, though.
   9891  Node nodeStack[PRECEDENCE_CLASSES];
   9892  ParseNodeKind kindStack[PRECEDENCE_CLASSES];
   9893  int depth = 0;
   9894  Node pn;
   9895  EnforcedParentheses unparenthesizedExpression = EnforcedParentheses::None;
   9896  for (;;) {
   9897    pn = MOZ_TRY(unaryExpr(yieldHandling, tripledotHandling, possibleError,
   9898                           invoked, PrivateNameHandling::PrivateNameAllowed));
   9899 
   9900    // If a binary operator follows, consume it and compute the
   9901    // corresponding operator.
   9902    TokenKind tok;
   9903    if (!tokenStream.getToken(&tok)) {
   9904      return errorResult();
   9905    }
   9906 
   9907    // Ensure that if we have a private name lhs we are legally constructing a
   9908    // `#x in obj` expessions:
   9909    if (handler_.isPrivateName(pn)) {
   9910      if (tok != TokenKind::In || inHandling != InAllowed) {
   9911        error(JSMSG_ILLEGAL_PRIVATE_NAME);
   9912        return errorResult();
   9913      }
   9914    }
   9915 
   9916    ParseNodeKind pnk;
   9917    if (tok == TokenKind::In ? inHandling == InAllowed
   9918                             : TokenKindIsBinaryOp(tok)) {
   9919      // We're definitely not in a destructuring context, so report any
   9920      // pending expression error now.
   9921      if (possibleError && !possibleError->checkForExpressionError()) {
   9922        return errorResult();
   9923      }
   9924 
   9925      bool isErgonomicBrandCheck = false;
   9926      switch (tok) {
   9927        // Report an error for unary expressions on the LHS of **.
   9928        case TokenKind::Pow:
   9929          if (handler_.isUnparenthesizedUnaryExpression(pn)) {
   9930            error(JSMSG_BAD_POW_LEFTSIDE);
   9931            return errorResult();
   9932          }
   9933          break;
   9934 
   9935        case TokenKind::Or:
   9936        case TokenKind::And:
   9937          // In the case that the `??` is on the left hand side of the
   9938          // expression: Disallow Mixing of ?? and other logical operators (||
   9939          // and &&) unless one expression is parenthesized
   9940          if (unparenthesizedExpression == EnforcedParentheses::CoalesceExpr) {
   9941            error(JSMSG_BAD_COALESCE_MIXING);
   9942            return errorResult();
   9943          }
   9944          // If we have not detected a mixing error at this point, record that
   9945          // we have an unparenthesized expression, in case we have one later.
   9946          unparenthesizedExpression = EnforcedParentheses::AndOrExpr;
   9947          break;
   9948 
   9949        case TokenKind::Coalesce:
   9950          if (unparenthesizedExpression == EnforcedParentheses::AndOrExpr) {
   9951            error(JSMSG_BAD_COALESCE_MIXING);
   9952            return errorResult();
   9953          }
   9954          // If we have not detected a mixing error at this point, record that
   9955          // we have an unparenthesized expression, in case we have one later.
   9956          unparenthesizedExpression = EnforcedParentheses::CoalesceExpr;
   9957          break;
   9958 
   9959        case TokenKind::In:
   9960          // if the LHS is a private name, and the operator is In,
   9961          // ensure we're construcing an ergonomic brand check of
   9962          // '#x in y', rather than having a higher precedence operator
   9963          // like + cause a different reduction, such as
   9964          // 1 + #x in y.
   9965          if (handler_.isPrivateName(pn)) {
   9966            if (depth > 0 && Precedence(kindStack[depth - 1]) >=
   9967                                 Precedence(ParseNodeKind::InExpr)) {
   9968              error(JSMSG_INVALID_PRIVATE_NAME_PRECEDENCE);
   9969              return errorResult();
   9970            }
   9971 
   9972            isErgonomicBrandCheck = true;
   9973          }
   9974          break;
   9975 
   9976        default:
   9977          // do nothing in other cases
   9978          break;
   9979      }
   9980 
   9981      if (isErgonomicBrandCheck) {
   9982        pnk = ParseNodeKind::PrivateInExpr;
   9983      } else {
   9984        pnk = BinaryOpTokenKindToParseNodeKind(tok);
   9985      }
   9986 
   9987    } else {
   9988      tok = TokenKind::Eof;
   9989      pnk = ParseNodeKind::Limit;
   9990    }
   9991 
   9992    // From this point on, destructuring defaults are definitely an error.
   9993    possibleError = nullptr;
   9994 
   9995    // If pnk has precedence less than or equal to another operator on the
   9996    // stack, reduce. This combines nodes on the stack until we form the
   9997    // actual lhs of pnk.
   9998    //
   9999    // The >= in this condition works because it is appendOrCreateList's
  10000    // job to decide if the operator in question is left- or
  10001    // right-associative, and build the corresponding tree.
  10002    while (depth > 0 && Precedence(kindStack[depth - 1]) >= Precedence(pnk)) {
  10003      depth--;
  10004      ParseNodeKind combiningPnk = kindStack[depth];
  10005      pn = MOZ_TRY(
  10006          handler_.appendOrCreateList(combiningPnk, nodeStack[depth], pn, pc_));
  10007    }
  10008 
  10009    if (pnk == ParseNodeKind::Limit) {
  10010      break;
  10011    }
  10012 
  10013    nodeStack[depth] = pn;
  10014    kindStack[depth] = pnk;
  10015    depth++;
  10016    MOZ_ASSERT(depth <= PRECEDENCE_CLASSES);
  10017  }
  10018 
  10019  anyChars.ungetToken();
  10020 
  10021  // Had the next token been a Div, we would have consumed it. So there's no
  10022  // ambiguity if we later (after ASI) re-get this token with SlashIsRegExp.
  10023  anyChars.allowGettingNextTokenWithSlashIsRegExp();
  10024 
  10025  MOZ_ASSERT(depth == 0);
  10026  return pn;
  10027 }
  10028 
  10029 template <class ParseHandler, typename Unit>
  10030 MOZ_ALWAYS_INLINE typename ParseHandler::NodeResult
  10031 GeneralParser<ParseHandler, Unit>::condExpr(InHandling inHandling,
  10032                                            YieldHandling yieldHandling,
  10033                                            TripledotHandling tripledotHandling,
  10034                                            PossibleError* possibleError,
  10035                                            InvokedPrediction invoked) {
  10036  Node condition = MOZ_TRY(orExpr(inHandling, yieldHandling, tripledotHandling,
  10037                                  possibleError, invoked));
  10038 
  10039  bool matched;
  10040  if (!tokenStream.matchToken(&matched, TokenKind::Hook,
  10041                              TokenStream::SlashIsInvalid)) {
  10042    return errorResult();
  10043  }
  10044  if (!matched) {
  10045    return condition;
  10046  }
  10047 
  10048  Node thenExpr =
  10049      MOZ_TRY(assignExpr(InAllowed, yieldHandling, TripledotProhibited));
  10050 
  10051  if (!mustMatchToken(TokenKind::Colon, JSMSG_COLON_IN_COND)) {
  10052    return errorResult();
  10053  }
  10054 
  10055  Node elseExpr =
  10056      MOZ_TRY(assignExpr(inHandling, yieldHandling, TripledotProhibited));
  10057 
  10058  return handler_.newConditional(condition, thenExpr, elseExpr);
  10059 }
  10060 
  10061 template <class ParseHandler, typename Unit>
  10062 typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::assignExpr(
  10063    InHandling inHandling, YieldHandling yieldHandling,
  10064    TripledotHandling tripledotHandling,
  10065    PossibleError* possibleError /* = nullptr */,
  10066    InvokedPrediction invoked /* = PredictUninvoked */) {
  10067  AutoCheckRecursionLimit recursion(this->fc_);
  10068  if (!recursion.check(this->fc_)) {
  10069    return errorResult();
  10070  }
  10071 
  10072  // It's very common at this point to have a "detectably simple" expression,
  10073  // i.e. a name/number/string token followed by one of the following tokens
  10074  // that obviously isn't part of an expression: , ; : ) ] }
  10075  //
  10076  // (In Parsemark this happens 81.4% of the time;  in code with large
  10077  // numeric arrays, such as some Kraken benchmarks, it happens more often.)
  10078  //
  10079  // In such cases, we can avoid the full expression parsing route through
  10080  // assignExpr(), condExpr(), orExpr(), unaryExpr(), memberExpr(), and
  10081  // primaryExpr().
  10082 
  10083  TokenKind firstToken;
  10084  if (!tokenStream.getToken(&firstToken, TokenStream::SlashIsRegExp)) {
  10085    return errorResult();
  10086  }
  10087 
  10088  TokenPos exprPos = pos();
  10089 
  10090  bool endsExpr;
  10091 
  10092  // This only handles identifiers that *never* have special meaning anywhere
  10093  // in the language.  Contextual keywords, reserved words in strict mode,
  10094  // and other hard cases are handled outside this fast path.
  10095  if (firstToken == TokenKind::Name) {
  10096    if (!tokenStream.nextTokenEndsExpr(&endsExpr)) {
  10097      return errorResult();
  10098    }
  10099    if (endsExpr) {
  10100      TaggedParserAtomIndex name = identifierReference(yieldHandling);
  10101      if (!name) {
  10102        return errorResult();
  10103      }
  10104 
  10105      return identifierReference(name);
  10106    }
  10107  }
  10108 
  10109  if (firstToken == TokenKind::Number) {
  10110    if (!tokenStream.nextTokenEndsExpr(&endsExpr)) {
  10111      return errorResult();
  10112    }
  10113    if (endsExpr) {
  10114      return newNumber(anyChars.currentToken());
  10115    }
  10116  }
  10117 
  10118  if (firstToken == TokenKind::String) {
  10119    if (!tokenStream.nextTokenEndsExpr(&endsExpr)) {
  10120      return errorResult();
  10121    }
  10122    if (endsExpr) {
  10123      return stringLiteral();
  10124    }
  10125  }
  10126 
  10127  if (firstToken == TokenKind::Yield && yieldExpressionsSupported()) {
  10128    return yieldExpression(inHandling);
  10129  }
  10130 
  10131  bool maybeAsyncArrow = false;
  10132  if (firstToken == TokenKind::Async) {
  10133    TokenKind nextSameLine = TokenKind::Eof;
  10134    if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
  10135      return errorResult();
  10136    }
  10137 
  10138    if (TokenKindIsPossibleIdentifier(nextSameLine)) {
  10139      maybeAsyncArrow = true;
  10140    }
  10141  }
  10142 
  10143  anyChars.ungetToken();
  10144 
  10145  // Save the tokenizer state in case we find an arrow function and have to
  10146  // rewind.
  10147  Position start(tokenStream);
  10148  auto ghostToken = this->compilationState_.getPosition();
  10149 
  10150  PossibleError possibleErrorInner(*this);
  10151  Node lhs;
  10152  TokenKind tokenAfterLHS;
  10153  bool isArrow;
  10154  if (maybeAsyncArrow) {
  10155    tokenStream.consumeKnownToken(TokenKind::Async, TokenStream::SlashIsRegExp);
  10156 
  10157    TokenKind tokenAfterAsync;
  10158    if (!tokenStream.getToken(&tokenAfterAsync)) {
  10159      return errorResult();
  10160    }
  10161    MOZ_ASSERT(TokenKindIsPossibleIdentifier(tokenAfterAsync));
  10162 
  10163    // Check yield validity here.
  10164    TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
  10165    if (!name) {
  10166      return errorResult();
  10167    }
  10168 
  10169    if (!tokenStream.peekToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)) {
  10170      return errorResult();
  10171    }
  10172 
  10173    isArrow = tokenAfterLHS == TokenKind::Arrow;
  10174 
  10175    // |async [no LineTerminator] of| without being followed by => is only
  10176    // possible in for-await-of loops, e.g. |for await (async of [])|. Pretend
  10177    // the |async| token was parsed an identifier reference and then proceed
  10178    // with the rest of this function.
  10179    if (!isArrow) {
  10180      anyChars.ungetToken();  // unget the binding identifier
  10181 
  10182      // The next token is guaranteed to never be a Div (, because it's an
  10183      // identifier), so it's okay to re-get the token with SlashIsRegExp.
  10184      anyChars.allowGettingNextTokenWithSlashIsRegExp();
  10185 
  10186      TaggedParserAtomIndex asyncName = identifierReference(yieldHandling);
  10187      if (!asyncName) {
  10188        return errorResult();
  10189      }
  10190 
  10191      lhs = MOZ_TRY(identifierReference(asyncName));
  10192    }
  10193  } else {
  10194    lhs = MOZ_TRY(condExpr(inHandling, yieldHandling, tripledotHandling,
  10195                           &possibleErrorInner, invoked));
  10196 
  10197    // Use SlashIsRegExp here because the ConditionalExpression parsed above
  10198    // could be the entirety of this AssignmentExpression, and then ASI
  10199    // permits this token to be a regular expression.
  10200    if (!tokenStream.peekToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)) {
  10201      return errorResult();
  10202    }
  10203 
  10204    isArrow = tokenAfterLHS == TokenKind::Arrow;
  10205  }
  10206 
  10207  if (isArrow) {
  10208    // Rewind to reparse as an arrow function.
  10209    //
  10210    // Note: We do not call CompilationState::rewind here because parsing
  10211    // during delazification will see the same rewind and need the same sequence
  10212    // of inner functions to skip over.
  10213    // Instead, we mark inner functions as "ghost".
  10214    //
  10215    // See GHOST_FUNCTION in FunctionFlags.h for more details.
  10216    tokenStream.rewind(start);
  10217    this->compilationState_.markGhost(ghostToken);
  10218 
  10219    TokenKind next;
  10220    if (!tokenStream.getToken(&next, TokenStream::SlashIsRegExp)) {
  10221      return errorResult();
  10222    }
  10223    TokenPos startPos = pos();
  10224    uint32_t toStringStart = startPos.begin;
  10225    anyChars.ungetToken();
  10226 
  10227    FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
  10228 
  10229    if (next == TokenKind::Async) {
  10230      tokenStream.consumeKnownToken(next, TokenStream::SlashIsRegExp);
  10231 
  10232      TokenKind nextSameLine = TokenKind::Eof;
  10233      if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
  10234        return errorResult();
  10235      }
  10236 
  10237      // The AsyncArrowFunction production are
  10238      //   async [no LineTerminator here] AsyncArrowBindingIdentifier ...
  10239      //   async [no LineTerminator here] ArrowFormalParameters ...
  10240      if (TokenKindIsPossibleIdentifier(nextSameLine) ||
  10241          nextSameLine == TokenKind::LeftParen) {
  10242        asyncKind = FunctionAsyncKind::AsyncFunction;
  10243      } else {
  10244        anyChars.ungetToken();
  10245      }
  10246    }
  10247 
  10248    FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Arrow;
  10249    FunctionNodeType funNode =
  10250        MOZ_TRY(handler_.newFunction(syntaxKind, startPos));
  10251 
  10252    return functionDefinition(funNode, toStringStart, inHandling, yieldHandling,
  10253                              TaggedParserAtomIndex::null(), syntaxKind,
  10254                              GeneratorKind::NotGenerator, asyncKind);
  10255  }
  10256 
  10257  MOZ_ALWAYS_TRUE(
  10258      tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp));
  10259 
  10260  ParseNodeKind kind;
  10261  switch (tokenAfterLHS) {
  10262    case TokenKind::Assign:
  10263      kind = ParseNodeKind::AssignExpr;
  10264      break;
  10265    case TokenKind::AddAssign:
  10266      kind = ParseNodeKind::AddAssignExpr;
  10267      break;
  10268    case TokenKind::SubAssign:
  10269      kind = ParseNodeKind::SubAssignExpr;
  10270      break;
  10271    case TokenKind::CoalesceAssign:
  10272      kind = ParseNodeKind::CoalesceAssignExpr;
  10273      break;
  10274    case TokenKind::OrAssign:
  10275      kind = ParseNodeKind::OrAssignExpr;
  10276      break;
  10277    case TokenKind::AndAssign:
  10278      kind = ParseNodeKind::AndAssignExpr;
  10279      break;
  10280    case TokenKind::BitOrAssign:
  10281      kind = ParseNodeKind::BitOrAssignExpr;
  10282      break;
  10283    case TokenKind::BitXorAssign:
  10284      kind = ParseNodeKind::BitXorAssignExpr;
  10285      break;
  10286    case TokenKind::BitAndAssign:
  10287      kind = ParseNodeKind::BitAndAssignExpr;
  10288      break;
  10289    case TokenKind::LshAssign:
  10290      kind = ParseNodeKind::LshAssignExpr;
  10291      break;
  10292    case TokenKind::RshAssign:
  10293      kind = ParseNodeKind::RshAssignExpr;
  10294      break;
  10295    case TokenKind::UrshAssign:
  10296      kind = ParseNodeKind::UrshAssignExpr;
  10297      break;
  10298    case TokenKind::MulAssign:
  10299      kind = ParseNodeKind::MulAssignExpr;
  10300      break;
  10301    case TokenKind::DivAssign:
  10302      kind = ParseNodeKind::DivAssignExpr;
  10303      break;
  10304    case TokenKind::ModAssign:
  10305      kind = ParseNodeKind::ModAssignExpr;
  10306      break;
  10307    case TokenKind::PowAssign:
  10308      kind = ParseNodeKind::PowAssignExpr;
  10309      break;
  10310 
  10311    default:
  10312      MOZ_ASSERT(!anyChars.isCurrentTokenAssignment());
  10313      if (!possibleError) {
  10314        if (!possibleErrorInner.checkForExpressionError()) {
  10315          return errorResult();
  10316        }
  10317      } else {
  10318        possibleErrorInner.transferErrorsTo(possibleError);
  10319      }
  10320 
  10321      anyChars.ungetToken();
  10322      return lhs;
  10323  }
  10324 
  10325  // Verify the left-hand side expression doesn't have a forbidden form.
  10326  if (handler_.isUnparenthesizedDestructuringPattern(lhs)) {
  10327    if (kind != ParseNodeKind::AssignExpr) {
  10328      error(JSMSG_BAD_DESTRUCT_ASS);
  10329      return errorResult();
  10330    }
  10331 
  10332    if (!possibleErrorInner.checkForDestructuringErrorOrWarning()) {
  10333      return errorResult();
  10334    }
  10335  } else if (handler_.isName(lhs)) {
  10336    if (const char* chars = nameIsArgumentsOrEval(lhs)) {
  10337      // |chars| is "arguments" or "eval" here.
  10338      if (!strictModeErrorAt(exprPos.begin, JSMSG_BAD_STRICT_ASSIGN, chars)) {
  10339        return errorResult();
  10340      }
  10341    }
  10342  } else if (handler_.isArgumentsLength(lhs)) {
  10343    pc_->sc()->setIneligibleForArgumentsLength();
  10344  } else if (handler_.isPropertyOrPrivateMemberAccess(lhs)) {
  10345    // Permitted: no additional testing/fixup needed.
  10346  } else if (handler_.isFunctionCall(lhs)) {
  10347    // We don't have to worry about backward compatibility issues with the new
  10348    // compound assignment operators, so we always throw here. Also that way we
  10349    // don't have to worry if |f() &&= expr| should always throw an error or
  10350    // only if |f()| returns true.
  10351    if (kind == ParseNodeKind::CoalesceAssignExpr ||
  10352        kind == ParseNodeKind::OrAssignExpr ||
  10353        kind == ParseNodeKind::AndAssignExpr) {
  10354      errorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS);
  10355      return errorResult();
  10356    }
  10357 
  10358    if (!strictModeErrorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS)) {
  10359      return errorResult();
  10360    }
  10361 
  10362    if (possibleError) {
  10363      possibleError->setPendingDestructuringErrorAt(exprPos,
  10364                                                    JSMSG_BAD_DESTRUCT_TARGET);
  10365    }
  10366  } else {
  10367    errorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS);
  10368    return errorResult();
  10369  }
  10370 
  10371  if (!possibleErrorInner.checkForExpressionError()) {
  10372    return errorResult();
  10373  }
  10374 
  10375  Node rhs =
  10376      MOZ_TRY(assignExpr(inHandling, yieldHandling, TripledotProhibited));
  10377 
  10378  return handler_.newAssignment(kind, lhs, rhs);
  10379 }
  10380 
  10381 template <class ParseHandler>
  10382 const char* PerHandlerParser<ParseHandler>::nameIsArgumentsOrEval(Node node) {
  10383  MOZ_ASSERT(handler_.isName(node),
  10384             "must only call this function on known names");
  10385 
  10386  if (handler_.isEvalName(node)) {
  10387    return "eval";
  10388  }
  10389  if (handler_.isArgumentsName(node)) {
  10390    return "arguments";
  10391  }
  10392  return nullptr;
  10393 }
  10394 
  10395 template <class ParseHandler, typename Unit>
  10396 bool GeneralParser<ParseHandler, Unit>::checkIncDecOperand(
  10397    Node operand, uint32_t operandOffset) {
  10398  if (handler_.isName(operand)) {
  10399    if (const char* chars = nameIsArgumentsOrEval(operand)) {
  10400      if (!strictModeErrorAt(operandOffset, JSMSG_BAD_STRICT_ASSIGN, chars)) {
  10401        return false;
  10402      }
  10403    }
  10404  } else if (handler_.isArgumentsLength(operand)) {
  10405    pc_->sc()->setIneligibleForArgumentsLength();
  10406  } else if (handler_.isPropertyOrPrivateMemberAccess(operand)) {
  10407    // Permitted: no additional testing/fixup needed.
  10408  } else if (handler_.isFunctionCall(operand)) {
  10409    // Assignment to function calls is forbidden in ES6.  We're still
  10410    // somewhat concerned about sites using this in dead code, so forbid it
  10411    // only in strict mode code.
  10412    if (!strictModeErrorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND)) {
  10413      return false;
  10414    }
  10415  } else {
  10416    errorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND);
  10417    return false;
  10418  }
  10419  return true;
  10420 }
  10421 
  10422 template <class ParseHandler, typename Unit>
  10423 typename ParseHandler::UnaryNodeResult
  10424 GeneralParser<ParseHandler, Unit>::unaryOpExpr(YieldHandling yieldHandling,
  10425                                               ParseNodeKind kind,
  10426                                               uint32_t begin) {
  10427  Node kid = MOZ_TRY(unaryExpr(yieldHandling, TripledotProhibited));
  10428  return handler_.newUnary(kind, begin, kid);
  10429 }
  10430 
  10431 template <class ParseHandler, typename Unit>
  10432 typename ParseHandler::NodeResult
  10433 GeneralParser<ParseHandler, Unit>::optionalExpr(
  10434    YieldHandling yieldHandling, TripledotHandling tripledotHandling,
  10435    TokenKind tt, PossibleError* possibleError /* = nullptr */,
  10436    InvokedPrediction invoked /* = PredictUninvoked */) {
  10437  AutoCheckRecursionLimit recursion(this->fc_);
  10438  if (!recursion.check(this->fc_)) {
  10439    return errorResult();
  10440  }
  10441 
  10442  uint32_t begin = pos().begin;
  10443 
  10444  Node lhs =
  10445      MOZ_TRY(memberExpr(yieldHandling, tripledotHandling, tt,
  10446                         /* allowCallSyntax = */ true, possibleError, invoked));
  10447 
  10448  if (!tokenStream.peekToken(&tt, TokenStream::SlashIsDiv)) {
  10449    return errorResult();
  10450  }
  10451 
  10452  if (tt != TokenKind::OptionalChain) {
  10453    return lhs;
  10454  }
  10455 
  10456  while (true) {
  10457    if (!tokenStream.getToken(&tt)) {
  10458      return errorResult();
  10459    }
  10460 
  10461    if (tt == TokenKind::Eof) {
  10462      anyChars.ungetToken();
  10463      break;
  10464    }
  10465 
  10466    Node nextMember;
  10467    if (tt == TokenKind::OptionalChain) {
  10468      if (!tokenStream.getToken(&tt)) {
  10469        return errorResult();
  10470      }
  10471      if (TokenKindIsPossibleIdentifierName(tt)) {
  10472        nextMember = MOZ_TRY(memberPropertyAccess(lhs, OptionalKind::Optional));
  10473      } else if (tt == TokenKind::PrivateName) {
  10474        nextMember = MOZ_TRY(memberPrivateAccess(lhs, OptionalKind::Optional));
  10475      } else if (tt == TokenKind::LeftBracket) {
  10476        nextMember = MOZ_TRY(
  10477            memberElemAccess(lhs, yieldHandling, OptionalKind::Optional));
  10478      } else if (tt == TokenKind::LeftParen) {
  10479        nextMember = MOZ_TRY(memberCall(tt, lhs, yieldHandling, possibleError,
  10480                                        OptionalKind::Optional));
  10481      } else {
  10482        error(JSMSG_NAME_AFTER_DOT);
  10483        return errorResult();
  10484      }
  10485    } else if (tt == TokenKind::Dot) {
  10486      if (!tokenStream.getToken(&tt)) {
  10487        return errorResult();
  10488      }
  10489      if (TokenKindIsPossibleIdentifierName(tt)) {
  10490        nextMember = MOZ_TRY(memberPropertyAccess(lhs));
  10491      } else if (tt == TokenKind::PrivateName) {
  10492        nextMember = MOZ_TRY(memberPrivateAccess(lhs));
  10493      } else {
  10494        error(JSMSG_NAME_AFTER_DOT);
  10495        return errorResult();
  10496      }
  10497    } else if (tt == TokenKind::LeftBracket) {
  10498      nextMember = MOZ_TRY(memberElemAccess(lhs, yieldHandling));
  10499    } else if (tt == TokenKind::LeftParen) {
  10500      nextMember = MOZ_TRY(memberCall(tt, lhs, yieldHandling, possibleError));
  10501    } else if (tt == TokenKind::TemplateHead ||
  10502               tt == TokenKind::NoSubsTemplate) {
  10503      error(JSMSG_BAD_OPTIONAL_TEMPLATE);
  10504      return errorResult();
  10505    } else {
  10506      anyChars.ungetToken();
  10507      break;
  10508    }
  10509 
  10510    MOZ_ASSERT(nextMember);
  10511    lhs = nextMember;
  10512  }
  10513 
  10514  return handler_.newOptionalChain(begin, lhs);
  10515 }
  10516 
  10517 template <class ParseHandler, typename Unit>
  10518 typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::unaryExpr(
  10519    YieldHandling yieldHandling, TripledotHandling tripledotHandling,
  10520    PossibleError* possibleError /* = nullptr */,
  10521    InvokedPrediction invoked /* = PredictUninvoked */,
  10522    PrivateNameHandling privateNameHandling /* = PrivateNameProhibited */) {
  10523  AutoCheckRecursionLimit recursion(this->fc_);
  10524  if (!recursion.check(this->fc_)) {
  10525    return errorResult();
  10526  }
  10527 
  10528  TokenKind tt;
  10529  if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
  10530    return errorResult();
  10531  }
  10532  uint32_t begin = pos().begin;
  10533  switch (tt) {
  10534    case TokenKind::Void:
  10535      return unaryOpExpr(yieldHandling, ParseNodeKind::VoidExpr, begin);
  10536    case TokenKind::Not:
  10537      return unaryOpExpr(yieldHandling, ParseNodeKind::NotExpr, begin);
  10538    case TokenKind::BitNot:
  10539      return unaryOpExpr(yieldHandling, ParseNodeKind::BitNotExpr, begin);
  10540    case TokenKind::Add:
  10541      return unaryOpExpr(yieldHandling, ParseNodeKind::PosExpr, begin);
  10542    case TokenKind::Sub:
  10543      return unaryOpExpr(yieldHandling, ParseNodeKind::NegExpr, begin);
  10544 
  10545    case TokenKind::TypeOf: {
  10546      // The |typeof| operator is specially parsed to distinguish its
  10547      // application to a name, from its application to a non-name
  10548      // expression:
  10549      //
  10550      //   // Looks up the name, doesn't find it and so evaluates to
  10551      //   // "undefined".
  10552      //   assertEq(typeof nonExistentName, "undefined");
  10553      //
  10554      //   // Evaluates expression, triggering a runtime ReferenceError for
  10555      //   // the undefined name.
  10556      //   typeof (1, nonExistentName);
  10557      Node kid = MOZ_TRY(unaryExpr(yieldHandling, TripledotProhibited));
  10558 
  10559      return handler_.newTypeof(begin, kid);
  10560    }
  10561 
  10562    case TokenKind::Inc:
  10563    case TokenKind::Dec: {
  10564      TokenKind tt2;
  10565      if (!tokenStream.getToken(&tt2, TokenStream::SlashIsRegExp)) {
  10566        return errorResult();
  10567      }
  10568 
  10569      uint32_t operandOffset = pos().begin;
  10570      Node operand =
  10571          MOZ_TRY(optionalExpr(yieldHandling, TripledotProhibited, tt2));
  10572      if (!checkIncDecOperand(operand, operandOffset)) {
  10573        return errorResult();
  10574      }
  10575      ParseNodeKind pnk = (tt == TokenKind::Inc)
  10576                              ? ParseNodeKind::PreIncrementExpr
  10577                              : ParseNodeKind::PreDecrementExpr;
  10578      return handler_.newUpdate(pnk, begin, operand);
  10579    }
  10580    case TokenKind::PrivateName: {
  10581      if (privateNameHandling == PrivateNameHandling::PrivateNameAllowed) {
  10582        TaggedParserAtomIndex field = anyChars.currentName();
  10583        return privateNameReference(field);
  10584      }
  10585      error(JSMSG_INVALID_PRIVATE_NAME_IN_UNARY_EXPR);
  10586      return errorResult();
  10587    }
  10588 
  10589    case TokenKind::Delete: {
  10590      uint32_t exprOffset;
  10591      if (!tokenStream.peekOffset(&exprOffset, TokenStream::SlashIsRegExp)) {
  10592        return errorResult();
  10593      }
  10594 
  10595      Node expr = MOZ_TRY(unaryExpr(yieldHandling, TripledotProhibited));
  10596 
  10597      // Per spec, deleting most unary expressions is valid -- it simply
  10598      // returns true -- except for two cases:
  10599      // 1. `var x; ...; delete x` is a syntax error in strict mode.
  10600      // 2. Private fields cannot be deleted.
  10601      if (handler_.isName(expr)) {
  10602        if (!strictModeErrorAt(exprOffset, JSMSG_DEPRECATED_DELETE_OPERAND)) {
  10603          return errorResult();
  10604        }
  10605 
  10606        pc_->sc()->setBindingsAccessedDynamically();
  10607      }
  10608 
  10609      if (handler_.isPrivateMemberAccess(expr)) {
  10610        errorAt(exprOffset, JSMSG_PRIVATE_DELETE);
  10611        return errorResult();
  10612      }
  10613 
  10614      return handler_.newDelete(begin, expr);
  10615    }
  10616    case TokenKind::Await: {
  10617      // If we encounter an await in a module, mark it as async.
  10618      if (!pc_->isAsync() && pc_->sc()->isModule()) {
  10619        if (!options().topLevelAwait) {
  10620          error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
  10621          return errorResult();
  10622        }
  10623        pc_->sc()->asModuleContext()->setIsAsync();
  10624        MOZ_ASSERT(pc_->isAsync());
  10625      }
  10626 
  10627      if (pc_->isAsync()) {
  10628        if (inParametersOfAsyncFunction()) {
  10629          error(JSMSG_AWAIT_IN_PARAMETER);
  10630          return errorResult();
  10631        }
  10632        Node kid = MOZ_TRY(unaryExpr(yieldHandling, tripledotHandling,
  10633                                     possibleError, invoked));
  10634        pc_->lastAwaitOffset = begin;
  10635        return handler_.newAwaitExpression(begin, kid);
  10636      }
  10637    }
  10638 
  10639      [[fallthrough]];
  10640 
  10641    default: {
  10642      Node expr = MOZ_TRY(optionalExpr(yieldHandling, tripledotHandling, tt,
  10643                                       possibleError, invoked));
  10644 
  10645      /* Don't look across a newline boundary for a postfix incop. */
  10646      if (!tokenStream.peekTokenSameLine(&tt)) {
  10647        return errorResult();
  10648      }
  10649 
  10650      if (tt != TokenKind::Inc && tt != TokenKind::Dec) {
  10651        return expr;
  10652      }
  10653 
  10654      tokenStream.consumeKnownToken(tt);
  10655      if (!checkIncDecOperand(expr, begin)) {
  10656        return errorResult();
  10657      }
  10658 
  10659      ParseNodeKind pnk = (tt == TokenKind::Inc)
  10660                              ? ParseNodeKind::PostIncrementExpr
  10661                              : ParseNodeKind::PostDecrementExpr;
  10662      return handler_.newUpdate(pnk, begin, expr);
  10663    }
  10664  }
  10665 }
  10666 
  10667 template <class ParseHandler, typename Unit>
  10668 typename ParseHandler::NodeResult
  10669 GeneralParser<ParseHandler, Unit>::assignExprWithoutYieldOrAwait(
  10670    YieldHandling yieldHandling) {
  10671  uint32_t startYieldOffset = pc_->lastYieldOffset;
  10672  uint32_t startAwaitOffset = pc_->lastAwaitOffset;
  10673 
  10674  Node res = MOZ_TRY(assignExpr(InAllowed, yieldHandling, TripledotProhibited));
  10675 
  10676  if (pc_->lastYieldOffset != startYieldOffset) {
  10677    errorAt(pc_->lastYieldOffset, JSMSG_YIELD_IN_PARAMETER);
  10678    return errorResult();
  10679  }
  10680  if (pc_->lastAwaitOffset != startAwaitOffset) {
  10681    errorAt(pc_->lastAwaitOffset, JSMSG_AWAIT_IN_PARAMETER);
  10682    return errorResult();
  10683  }
  10684  return res;
  10685 }
  10686 
  10687 template <class ParseHandler, typename Unit>
  10688 typename ParseHandler::ListNodeResult
  10689 GeneralParser<ParseHandler, Unit>::argumentList(
  10690    YieldHandling yieldHandling, bool* isSpread,
  10691    PossibleError* possibleError /* = nullptr */) {
  10692  ListNodeType argsList = MOZ_TRY(handler_.newArguments(pos()));
  10693 
  10694  bool matched;
  10695  if (!tokenStream.matchToken(&matched, TokenKind::RightParen,
  10696                              TokenStream::SlashIsRegExp)) {
  10697    return errorResult();
  10698  }
  10699  if (matched) {
  10700    handler_.setEndPosition(argsList, pos().end);
  10701    return argsList;
  10702  }
  10703 
  10704  while (true) {
  10705    bool spread = false;
  10706    uint32_t begin = 0;
  10707    if (!tokenStream.matchToken(&matched, TokenKind::TripleDot,
  10708                                TokenStream::SlashIsRegExp)) {
  10709      return errorResult();
  10710    }
  10711    if (matched) {
  10712      spread = true;
  10713      begin = pos().begin;
  10714      *isSpread = true;
  10715    }
  10716 
  10717    Node argNode = MOZ_TRY(assignExpr(InAllowed, yieldHandling,
  10718                                      TripledotProhibited, possibleError));
  10719    if (spread) {
  10720      argNode = MOZ_TRY(handler_.newSpread(begin, argNode));
  10721    }
  10722 
  10723    handler_.addList(argsList, argNode);
  10724 
  10725    bool matched;
  10726    if (!tokenStream.matchToken(&matched, TokenKind::Comma,
  10727                                TokenStream::SlashIsRegExp)) {
  10728      return errorResult();
  10729    }
  10730    if (!matched) {
  10731      break;
  10732    }
  10733 
  10734    TokenKind tt;
  10735    if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
  10736      return errorResult();
  10737    }
  10738    if (tt == TokenKind::RightParen) {
  10739      break;
  10740    }
  10741  }
  10742 
  10743  if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_ARGS)) {
  10744    return errorResult();
  10745  }
  10746 
  10747  handler_.setEndPosition(argsList, pos().end);
  10748  return argsList;
  10749 }
  10750 
  10751 bool ParserBase::checkAndMarkSuperScope() {
  10752  if (!pc_->sc()->allowSuperProperty()) {
  10753    return false;
  10754  }
  10755 
  10756  pc_->setSuperScopeNeedsHomeObject();
  10757  return true;
  10758 }
  10759 
  10760 template <class ParseHandler, typename Unit>
  10761 bool GeneralParser<ParseHandler, Unit>::computeErrorMetadata(
  10762    ErrorMetadata* err, const ErrorReportMixin::ErrorOffset& offset) const {
  10763  if (offset.is<ErrorReportMixin::Current>()) {
  10764    return tokenStream.computeErrorMetadata(err, AsVariant(pos().begin));
  10765  }
  10766  return tokenStream.computeErrorMetadata(err, offset);
  10767 }
  10768 
  10769 template <class ParseHandler, typename Unit>
  10770 typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::memberExpr(
  10771    YieldHandling yieldHandling, TripledotHandling tripledotHandling,
  10772    TokenKind tt, bool allowCallSyntax, PossibleError* possibleError,
  10773    InvokedPrediction invoked) {
  10774  MOZ_ASSERT(anyChars.isCurrentTokenType(tt));
  10775 
  10776  Node lhs;
  10777 
  10778  AutoCheckRecursionLimit recursion(this->fc_);
  10779  if (!recursion.check(this->fc_)) {
  10780    return errorResult();
  10781  }
  10782 
  10783  /* Check for new expression first. */
  10784  if (tt == TokenKind::New) {
  10785    uint32_t newBegin = pos().begin;
  10786    // Make sure this wasn't a |new.target| in disguise.
  10787    NewTargetNodeType newTarget;
  10788    if (!tryNewTarget(&newTarget)) {
  10789      return errorResult();
  10790    }
  10791    if (newTarget) {
  10792      lhs = newTarget;
  10793    } else {
  10794      // Gotten by tryNewTarget
  10795      tt = anyChars.currentToken().type;
  10796      Node ctorExpr =
  10797          MOZ_TRY(memberExpr(yieldHandling, TripledotProhibited, tt,
  10798                             /* allowCallSyntax = */ false,
  10799                             /* possibleError = */ nullptr, PredictInvoked));
  10800 
  10801      // If we have encountered an optional chain, in the form of `new
  10802      // ClassName?.()` then we need to throw, as this is disallowed by the
  10803      // spec.
  10804      bool optionalToken;
  10805      if (!tokenStream.matchToken(&optionalToken, TokenKind::OptionalChain)) {
  10806        return errorResult();
  10807      }
  10808      if (optionalToken) {
  10809        errorAt(newBegin, JSMSG_BAD_NEW_OPTIONAL);
  10810        return errorResult();
  10811      }
  10812 
  10813      bool matched;
  10814      if (!tokenStream.matchToken(&matched, TokenKind::LeftParen)) {
  10815        return errorResult();
  10816      }
  10817 
  10818      bool isSpread = false;
  10819      ListNodeType args;
  10820      if (matched) {
  10821        args = MOZ_TRY(argumentList(yieldHandling, &isSpread));
  10822      } else {
  10823        args = MOZ_TRY(handler_.newArguments(pos()));
  10824      }
  10825 
  10826      if (!args) {
  10827        return errorResult();
  10828      }
  10829 
  10830      lhs = MOZ_TRY(
  10831          handler_.newNewExpression(newBegin, ctorExpr, args, isSpread));
  10832    }
  10833  } else if (tt == TokenKind::Super) {
  10834    NameNodeType thisName = MOZ_TRY(newThisName());
  10835    lhs = MOZ_TRY(handler_.newSuperBase(thisName, pos()));
  10836  } else if (tt == TokenKind::Import) {
  10837    lhs = MOZ_TRY(importExpr(yieldHandling, allowCallSyntax));
  10838  } else {
  10839    lhs = MOZ_TRY(primaryExpr(yieldHandling, tripledotHandling, tt,
  10840                              possibleError, invoked));
  10841  }
  10842 
  10843  MOZ_ASSERT_IF(handler_.isSuperBase(lhs),
  10844                anyChars.isCurrentTokenType(TokenKind::Super));
  10845 
  10846  while (true) {
  10847    if (!tokenStream.getToken(&tt)) {
  10848      return errorResult();
  10849    }
  10850    if (tt == TokenKind::Eof) {
  10851      anyChars.ungetToken();
  10852      break;
  10853    }
  10854 
  10855    Node nextMember;
  10856    if (tt == TokenKind::Dot) {
  10857      if (!tokenStream.getToken(&tt)) {
  10858        return errorResult();
  10859      }
  10860 
  10861      if (TokenKindIsPossibleIdentifierName(tt)) {
  10862        nextMember = MOZ_TRY(memberPropertyAccess(lhs));
  10863      } else if (tt == TokenKind::PrivateName) {
  10864        nextMember = MOZ_TRY(memberPrivateAccess(lhs));
  10865      } else {
  10866        error(JSMSG_NAME_AFTER_DOT);
  10867        return errorResult();
  10868      }
  10869    } else if (tt == TokenKind::LeftBracket) {
  10870      nextMember = MOZ_TRY(memberElemAccess(lhs, yieldHandling));
  10871    } else if ((allowCallSyntax && tt == TokenKind::LeftParen) ||
  10872               tt == TokenKind::TemplateHead ||
  10873               tt == TokenKind::NoSubsTemplate) {
  10874      if (handler_.isSuperBase(lhs)) {
  10875        if (!pc_->sc()->allowSuperCall()) {
  10876          error(JSMSG_BAD_SUPERCALL);
  10877          return errorResult();
  10878        }
  10879 
  10880        if (tt != TokenKind::LeftParen) {
  10881          error(JSMSG_BAD_SUPER);
  10882          return errorResult();
  10883        }
  10884 
  10885        nextMember = MOZ_TRY(memberSuperCall(lhs, yieldHandling));
  10886 
  10887        if (!noteUsedName(
  10888                TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
  10889          return errorResult();
  10890        }
  10891 #ifdef ENABLE_DECORATORS
  10892        if (!noteUsedName(TaggedParserAtomIndex::WellKnown::
  10893                              dot_instanceExtraInitializers_())) {
  10894          return null();
  10895        }
  10896 #endif
  10897      } else {
  10898        nextMember = MOZ_TRY(memberCall(tt, lhs, yieldHandling, possibleError));
  10899      }
  10900    } else {
  10901      anyChars.ungetToken();
  10902      if (handler_.isSuperBase(lhs)) {
  10903        break;
  10904      }
  10905      return lhs;
  10906    }
  10907 
  10908    lhs = nextMember;
  10909  }
  10910 
  10911  if (handler_.isSuperBase(lhs)) {
  10912    error(JSMSG_BAD_SUPER);
  10913    return errorResult();
  10914  }
  10915 
  10916  return lhs;
  10917 }
  10918 
  10919 template <class ParseHandler, typename Unit>
  10920 typename ParseHandler::NodeResult
  10921 GeneralParser<ParseHandler, Unit>::decoratorExpr(YieldHandling yieldHandling,
  10922                                                 TokenKind tt) {
  10923  MOZ_ASSERT(anyChars.isCurrentTokenType(tt));
  10924 
  10925  AutoCheckRecursionLimit recursion(this->fc_);
  10926  if (!recursion.check(this->fc_)) {
  10927    return errorResult();
  10928  }
  10929 
  10930  if (tt == TokenKind::LeftParen) {
  10931    // DecoratorParenthesizedExpression
  10932    Node expr = MOZ_TRY(exprInParens(InAllowed, yieldHandling, TripledotAllowed,
  10933                                     /* possibleError*/ nullptr));
  10934    if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_DECORATOR)) {
  10935      return errorResult();
  10936    }
  10937 
  10938    return handler_.parenthesize(expr);
  10939  }
  10940 
  10941  if (!TokenKindIsPossibleIdentifier(tt)) {
  10942    error(JSMSG_DECORATOR_NAME_EXPECTED);
  10943    return errorResult();
  10944  }
  10945 
  10946  TaggedParserAtomIndex name = identifierReference(yieldHandling);
  10947  if (!name) {
  10948    return errorResult();
  10949  }
  10950 
  10951  Node lhs = MOZ_TRY(identifierReference(name));
  10952 
  10953  while (true) {
  10954    if (!tokenStream.getToken(&tt)) {
  10955      return errorResult();
  10956    }
  10957    if (tt == TokenKind::Eof) {
  10958      anyChars.ungetToken();
  10959      break;
  10960    }
  10961 
  10962    Node nextMember;
  10963    if (tt == TokenKind::Dot) {
  10964      if (!tokenStream.getToken(&tt)) {
  10965        return errorResult();
  10966      }
  10967 
  10968      if (TokenKindIsPossibleIdentifierName(tt)) {
  10969        nextMember = MOZ_TRY(memberPropertyAccess(lhs));
  10970      } else if (tt == TokenKind::PrivateName) {
  10971        nextMember = MOZ_TRY(memberPrivateAccess(lhs));
  10972      } else {
  10973        error(JSMSG_NAME_AFTER_DOT);
  10974        return errorResult();
  10975      }
  10976    } else if (tt == TokenKind::LeftParen) {
  10977      nextMember = MOZ_TRY(memberCall(tt, lhs, yieldHandling,
  10978                                      /* possibleError */ nullptr));
  10979      lhs = nextMember;
  10980      // This is a `DecoratorCallExpression` and it's defined at the top level
  10981      // of `Decorator`, no other `DecoratorMemberExpression` is allowed to
  10982      // follow after the arguments.
  10983      break;
  10984    } else {
  10985      anyChars.ungetToken();
  10986      break;
  10987    }
  10988 
  10989    lhs = nextMember;
  10990  }
  10991 
  10992  return lhs;
  10993 }
  10994 
  10995 template <class ParseHandler>
  10996 inline typename ParseHandler::NameNodeResult
  10997 PerHandlerParser<ParseHandler>::newName(TaggedParserAtomIndex name) {
  10998  return newName(name, pos());
  10999 }
  11000 
  11001 template <class ParseHandler>
  11002 inline typename ParseHandler::NameNodeResult
  11003 PerHandlerParser<ParseHandler>::newName(TaggedParserAtomIndex name,
  11004                                        TokenPos pos) {
  11005  if (name == TaggedParserAtomIndex::WellKnown::arguments()) {
  11006    this->pc_->numberOfArgumentsNames++;
  11007  }
  11008  return handler_.newName(name, pos);
  11009 }
  11010 
  11011 template <class ParseHandler>
  11012 inline typename ParseHandler::NameNodeResult
  11013 PerHandlerParser<ParseHandler>::newPrivateName(TaggedParserAtomIndex name) {
  11014  return handler_.newPrivateName(name, pos());
  11015 }
  11016 
  11017 template <class ParseHandler, typename Unit>
  11018 typename ParseHandler::NodeResult
  11019 GeneralParser<ParseHandler, Unit>::memberPropertyAccess(
  11020    Node lhs, OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
  11021  MOZ_ASSERT(TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) ||
  11022             anyChars.currentToken().type == TokenKind::PrivateName);
  11023  TaggedParserAtomIndex field = anyChars.currentName();
  11024  if (handler_.isSuperBase(lhs) && !checkAndMarkSuperScope()) {
  11025    error(JSMSG_BAD_SUPERPROP, "property");
  11026    return errorResult();
  11027  }
  11028 
  11029  NameNodeType name = MOZ_TRY(handler_.newPropertyName(field, pos()));
  11030 
  11031  if (optionalKind == OptionalKind::Optional) {
  11032    MOZ_ASSERT(!handler_.isSuperBase(lhs));
  11033    return handler_.newOptionalPropertyAccess(lhs, name);
  11034  }
  11035 
  11036  if (handler_.isArgumentsName(lhs) && handler_.isLengthName(name)) {
  11037    MOZ_ASSERT(pc_->numberOfArgumentsNames > 0);
  11038    pc_->numberOfArgumentsNames--;
  11039    // Currently when resuming Generators don't get their argument length set
  11040    // in the interpreter frame (see InterpreterStack::resumeGeneratorCallFrame,
  11041    // and its call to initCallFrame).
  11042    if (pc_->isGeneratorOrAsync()) {
  11043      pc_->sc()->setIneligibleForArgumentsLength();
  11044    }
  11045    return handler_.newArgumentsLength(lhs, name);
  11046  }
  11047 
  11048  return handler_.newPropertyAccess(lhs, name);
  11049 }
  11050 
  11051 template <class ParseHandler, typename Unit>
  11052 typename ParseHandler::NodeResult
  11053 GeneralParser<ParseHandler, Unit>::memberPrivateAccess(
  11054    Node lhs, OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
  11055  MOZ_ASSERT(anyChars.currentToken().type == TokenKind::PrivateName);
  11056 
  11057  TaggedParserAtomIndex field = anyChars.currentName();
  11058  // Cannot access private fields on super.
  11059  if (handler_.isSuperBase(lhs)) {
  11060    error(JSMSG_BAD_SUPERPRIVATE);
  11061    return errorResult();
  11062  }
  11063 
  11064  NameNodeType privateName = MOZ_TRY(privateNameReference(field));
  11065 
  11066  if (optionalKind == OptionalKind::Optional) {
  11067    MOZ_ASSERT(!handler_.isSuperBase(lhs));
  11068    return handler_.newOptionalPrivateMemberAccess(lhs, privateName, pos().end);
  11069  }
  11070  return handler_.newPrivateMemberAccess(lhs, privateName, pos().end);
  11071 }
  11072 
  11073 template <class ParseHandler, typename Unit>
  11074 typename ParseHandler::NodeResult
  11075 GeneralParser<ParseHandler, Unit>::memberElemAccess(
  11076    Node lhs, YieldHandling yieldHandling,
  11077    OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
  11078  MOZ_ASSERT(anyChars.currentToken().type == TokenKind::LeftBracket);
  11079  Node propExpr = MOZ_TRY(expr(InAllowed, yieldHandling, TripledotProhibited));
  11080 
  11081  if (!mustMatchToken(TokenKind::RightBracket, JSMSG_BRACKET_IN_INDEX)) {
  11082    return errorResult();
  11083  }
  11084 
  11085  if (handler_.isSuperBase(lhs) && !checkAndMarkSuperScope()) {
  11086    error(JSMSG_BAD_SUPERPROP, "member");
  11087    return errorResult();
  11088  }
  11089  if (optionalKind == OptionalKind::Optional) {
  11090    MOZ_ASSERT(!handler_.isSuperBase(lhs));
  11091    return handler_.newOptionalPropertyByValue(lhs, propExpr, pos().end);
  11092  }
  11093  return handler_.newPropertyByValue(lhs, propExpr, pos().end);
  11094 }
  11095 
  11096 template <class ParseHandler, typename Unit>
  11097 typename ParseHandler::NodeResult
  11098 GeneralParser<ParseHandler, Unit>::memberSuperCall(
  11099    Node lhs, YieldHandling yieldHandling) {
  11100  MOZ_ASSERT(anyChars.currentToken().type == TokenKind::LeftParen);
  11101  // Despite the fact that it's impossible to have |super()| in a
  11102  // generator, we still inherit the yieldHandling of the
  11103  // memberExpression, per spec. Curious.
  11104  bool isSpread = false;
  11105  ListNodeType args = MOZ_TRY(argumentList(yieldHandling, &isSpread));
  11106 
  11107  CallNodeType superCall = MOZ_TRY(handler_.newSuperCall(lhs, args, isSpread));
  11108 
  11109  // |super()| implicitly reads |new.target|.
  11110  if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_newTarget_())) {
  11111    return errorResult();
  11112  }
  11113 
  11114  NameNodeType thisName = MOZ_TRY(newThisName());
  11115 
  11116  return handler_.newSetThis(thisName, superCall);
  11117 }
  11118 
  11119 template <class ParseHandler, typename Unit>
  11120 typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::memberCall(
  11121    TokenKind tt, Node lhs, YieldHandling yieldHandling,
  11122    PossibleError* possibleError /* = nullptr */,
  11123    OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
  11124  if (options().selfHostingMode &&
  11125      (handler_.isPropertyOrPrivateMemberAccess(lhs) ||
  11126       handler_.isOptionalPropertyOrPrivateMemberAccess(lhs))) {
  11127    error(JSMSG_SELFHOSTED_METHOD_CALL);
  11128    return errorResult();
  11129  }
  11130 
  11131  MOZ_ASSERT(tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead ||
  11132                 tt == TokenKind::NoSubsTemplate,
  11133             "Unexpected token kind for member call");
  11134 
  11135  JSOp op = JSOp::Call;
  11136  bool maybeAsyncArrow = false;
  11137  if (tt == TokenKind::LeftParen && optionalKind == OptionalKind::NonOptional) {
  11138    if (handler_.isAsyncKeyword(lhs)) {
  11139      // |async (| can be the start of an async arrow
  11140      // function, so we need to defer reporting possible
  11141      // errors from destructuring syntax. To give better
  11142      // error messages, we only allow the AsyncArrowHead
  11143      // part of the CoverCallExpressionAndAsyncArrowHead
  11144      // syntax when the initial name is "async".
  11145      maybeAsyncArrow = true;
  11146    } else if (handler_.isEvalName(lhs)) {
  11147      // Select the right Eval op and flag pc_ as having a
  11148      // direct eval.
  11149      op = pc_->sc()->strict() ? JSOp::StrictEval : JSOp::Eval;
  11150      pc_->sc()->setBindingsAccessedDynamically();
  11151      pc_->sc()->setHasDirectEval();
  11152 
  11153      // In non-strict mode code, direct calls to eval can
  11154      // add variables to the call object.
  11155      if (pc_->isFunctionBox() && !pc_->sc()->strict()) {
  11156        pc_->functionBox()->setFunHasExtensibleScope();
  11157      }
  11158 
  11159      // If we're in a method, mark the method as requiring
  11160      // support for 'super', since direct eval code can use
  11161      // it. (If we're not in a method, that's fine, so
  11162      // ignore the return value.)
  11163      checkAndMarkSuperScope();
  11164    }
  11165  }
  11166 
  11167  if (tt == TokenKind::LeftParen) {
  11168    bool isSpread = false;
  11169    PossibleError* asyncPossibleError =
  11170        maybeAsyncArrow ? possibleError : nullptr;
  11171    ListNodeType args =
  11172        MOZ_TRY(argumentList(yieldHandling, &isSpread, asyncPossibleError));
  11173    if (isSpread) {
  11174      if (op == JSOp::Eval) {
  11175        op = JSOp::SpreadEval;
  11176      } else if (op == JSOp::StrictEval) {
  11177        op = JSOp::StrictSpreadEval;
  11178      } else {
  11179        op = JSOp::SpreadCall;
  11180      }
  11181    }
  11182 
  11183    if (optionalKind == OptionalKind::Optional) {
  11184      return handler_.newOptionalCall(lhs, args, op);
  11185    }
  11186    return handler_.newCall(lhs, args, op);
  11187  }
  11188 
  11189  ListNodeType args = MOZ_TRY(handler_.newArguments(pos()));
  11190 
  11191  if (!taggedTemplate(yieldHandling, args, tt)) {
  11192    return errorResult();
  11193  }
  11194 
  11195  if (optionalKind == OptionalKind::Optional) {
  11196    error(JSMSG_BAD_OPTIONAL_TEMPLATE);
  11197    return errorResult();
  11198  }
  11199 
  11200  return handler_.newTaggedTemplate(lhs, args, op);
  11201 }
  11202 
  11203 template <class ParseHandler, typename Unit>
  11204 bool GeneralParser<ParseHandler, Unit>::checkLabelOrIdentifierReference(
  11205    TaggedParserAtomIndex ident, uint32_t offset, YieldHandling yieldHandling,
  11206    TokenKind hint /* = TokenKind::Limit */) {
  11207  TokenKind tt;
  11208  if (hint == TokenKind::Limit) {
  11209    tt = ReservedWordTokenKind(ident);
  11210  } else {
  11211    // All non-reserved word kinds are folded into TokenKind::Limit in
  11212    // ReservedWordTokenKind and the following code.
  11213    if (hint == TokenKind::Name || hint == TokenKind::PrivateName) {
  11214      hint = TokenKind::Limit;
  11215    }
  11216    MOZ_ASSERT(hint == ReservedWordTokenKind(ident),
  11217               "hint doesn't match actual token kind");
  11218    tt = hint;
  11219  }
  11220 
  11221  if (!pc_->sc()->allowArguments() &&
  11222      ident == TaggedParserAtomIndex::WellKnown::arguments()) {
  11223    error(JSMSG_BAD_ARGUMENTS);
  11224    return false;
  11225  }
  11226 
  11227  if (tt == TokenKind::Limit) {
  11228    // Either TokenKind::Name or TokenKind::PrivateName
  11229    return true;
  11230  }
  11231  if (TokenKindIsContextualKeyword(tt)) {
  11232    if (tt == TokenKind::Yield) {
  11233      if (yieldHandling == YieldIsKeyword) {
  11234        errorAt(offset, JSMSG_RESERVED_ID, "yield");
  11235        return false;
  11236      }
  11237      if (pc_->sc()->strict()) {
  11238        if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "yield")) {
  11239          return false;
  11240        }
  11241      }
  11242      return true;
  11243    }
  11244    if (tt == TokenKind::Await) {
  11245      if (awaitIsKeyword() || awaitIsDisallowed()) {
  11246        errorAt(offset, JSMSG_RESERVED_ID, "await");
  11247        return false;
  11248      }
  11249      return true;
  11250    }
  11251    if (pc_->sc()->strict()) {
  11252      if (tt == TokenKind::Let) {
  11253        if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "let")) {
  11254          return false;
  11255        }
  11256        return true;
  11257      }
  11258      if (tt == TokenKind::Static) {
  11259        if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "static")) {
  11260          return false;
  11261        }
  11262        return true;
  11263      }
  11264    }
  11265    return true;
  11266  }
  11267  if (TokenKindIsStrictReservedWord(tt)) {
  11268    if (pc_->sc()->strict()) {
  11269      if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID,
  11270                             ReservedWordToCharZ(tt))) {
  11271        return false;
  11272      }
  11273    }
  11274    return true;
  11275  }
  11276  if (TokenKindIsKeyword(tt) || TokenKindIsReservedWordLiteral(tt)) {
  11277    errorAt(offset, JSMSG_INVALID_ID, ReservedWordToCharZ(tt));
  11278    return false;
  11279  }
  11280  if (TokenKindIsFutureReservedWord(tt)) {
  11281    errorAt(offset, JSMSG_RESERVED_ID, ReservedWordToCharZ(tt));
  11282    return false;
  11283  }
  11284  MOZ_ASSERT_UNREACHABLE("Unexpected reserved word kind.");
  11285  return false;
  11286 }
  11287 
  11288 template <class ParseHandler, typename Unit>
  11289 bool GeneralParser<ParseHandler, Unit>::checkBindingIdentifier(
  11290    TaggedParserAtomIndex ident, uint32_t offset, YieldHandling yieldHandling,
  11291    TokenKind hint /* = TokenKind::Limit */) {
  11292  if (pc_->sc()->strict()) {
  11293    if (ident == TaggedParserAtomIndex::WellKnown::arguments()) {
  11294      if (!strictModeErrorAt(offset, JSMSG_BAD_STRICT_ASSIGN, "arguments")) {
  11295        return false;
  11296      }
  11297      return true;
  11298    }
  11299 
  11300    if (ident == TaggedParserAtomIndex::WellKnown::eval()) {
  11301      if (!strictModeErrorAt(offset, JSMSG_BAD_STRICT_ASSIGN, "eval")) {
  11302        return false;
  11303      }
  11304      return true;
  11305    }
  11306  }
  11307 
  11308  return checkLabelOrIdentifierReference(ident, offset, yieldHandling, hint);
  11309 }
  11310 
  11311 template <class ParseHandler, typename Unit>
  11312 TaggedParserAtomIndex
  11313 GeneralParser<ParseHandler, Unit>::labelOrIdentifierReference(
  11314    YieldHandling yieldHandling) {
  11315  // ES 2017 draft 12.1.1.
  11316  //   StringValue of IdentifierName normalizes any Unicode escape sequences
  11317  //   in IdentifierName hence such escapes cannot be used to write an
  11318  //   Identifier whose code point sequence is the same as a ReservedWord.
  11319  //
  11320  // Use const ParserName* instead of TokenKind to reflect the normalization.
  11321 
  11322  // Unless the name contains escapes, we can reuse the current TokenKind
  11323  // to determine if the name is a restricted identifier.
  11324  TokenKind hint = !anyChars.currentNameHasEscapes(this->parserAtoms())
  11325                       ? anyChars.currentToken().type
  11326                       : TokenKind::Limit;
  11327  TaggedParserAtomIndex ident = anyChars.currentName();
  11328  if (!checkLabelOrIdentifierReference(ident, pos().begin, yieldHandling,
  11329                                       hint)) {
  11330    return TaggedParserAtomIndex::null();
  11331  }
  11332  return ident;
  11333 }
  11334 
  11335 template <class ParseHandler, typename Unit>
  11336 TaggedParserAtomIndex GeneralParser<ParseHandler, Unit>::bindingIdentifier(
  11337    YieldHandling yieldHandling) {
  11338  TokenKind hint = !anyChars.currentNameHasEscapes(this->parserAtoms())
  11339                       ? anyChars.currentToken().type
  11340                       : TokenKind::Limit;
  11341  TaggedParserAtomIndex ident = anyChars.currentName();
  11342  if (!checkBindingIdentifier(ident, pos().begin, yieldHandling, hint)) {
  11343    return TaggedParserAtomIndex::null();
  11344  }
  11345  return ident;
  11346 }
  11347 
  11348 template <class ParseHandler>
  11349 typename ParseHandler::NameNodeResult
  11350 PerHandlerParser<ParseHandler>::identifierReference(
  11351    TaggedParserAtomIndex name) {
  11352  NameNodeType id = MOZ_TRY(newName(name));
  11353 
  11354  if (!noteUsedName(name)) {
  11355    return errorResult();
  11356  }
  11357 
  11358  return id;
  11359 }
  11360 
  11361 template <class ParseHandler>
  11362 typename ParseHandler::NameNodeResult
  11363 PerHandlerParser<ParseHandler>::privateNameReference(
  11364    TaggedParserAtomIndex name) {
  11365  NameNodeType id = MOZ_TRY(newPrivateName(name));
  11366 
  11367  if (!noteUsedName(name, NameVisibility::Private, Some(pos()))) {
  11368    return errorResult();
  11369  }
  11370 
  11371  return id;
  11372 }
  11373 
  11374 template <class ParseHandler>
  11375 typename ParseHandler::NameNodeResult
  11376 PerHandlerParser<ParseHandler>::stringLiteral() {
  11377  return handler_.newStringLiteral(anyChars.currentToken().atom(), pos());
  11378 }
  11379 
  11380 template <class ParseHandler>
  11381 typename ParseHandler::NodeResult
  11382 PerHandlerParser<ParseHandler>::noSubstitutionTaggedTemplate() {
  11383  if (anyChars.hasInvalidTemplateEscape()) {
  11384    anyChars.clearInvalidTemplateEscape();
  11385    return handler_.newRawUndefinedLiteral(pos());
  11386  }
  11387 
  11388  return handler_.newTemplateStringLiteral(anyChars.currentToken().atom(),
  11389                                           pos());
  11390 }
  11391 
  11392 template <class ParseHandler, typename Unit>
  11393 typename ParseHandler::NameNodeResult
  11394 GeneralParser<ParseHandler, Unit>::noSubstitutionUntaggedTemplate() {
  11395  if (!tokenStream.checkForInvalidTemplateEscapeError()) {
  11396    return errorResult();
  11397  }
  11398 
  11399  return handler_.newTemplateStringLiteral(anyChars.currentToken().atom(),
  11400                                           pos());
  11401 }
  11402 
  11403 template <typename Unit>
  11404 FullParseHandler::RegExpLiteralResult
  11405 Parser<FullParseHandler, Unit>::newRegExp() {
  11406  MOZ_ASSERT(!options().selfHostingMode);
  11407 
  11408  // Create the regexp and check its syntax.
  11409  const auto& chars = tokenStream.getCharBuffer();
  11410  mozilla::Range<const char16_t> range(chars.begin(), chars.length());
  11411  RegExpFlags flags = anyChars.currentToken().regExpFlags();
  11412 
  11413  uint32_t offset = anyChars.currentToken().pos.begin;
  11414  uint32_t line;
  11415  JS::LimitedColumnNumberOneOrigin column;
  11416  tokenStream.computeLineAndColumn(offset, &line, &column);
  11417 
  11418  if (!handler_.reuseRegexpSyntaxParse()) {
  11419    // Verify that the Regexp will syntax parse when the time comes to
  11420    // instantiate it. If we have already done a syntax parse, we can
  11421    // skip this.
  11422    if (!irregexp::CheckPatternSyntax(
  11423            this->alloc_, this->fc_->stackLimit(), anyChars, range, flags,
  11424            Some(line), Some(JS::ColumnNumberOneOrigin(column)))) {
  11425      return errorResult();
  11426    }
  11427  }
  11428 
  11429  auto atom =
  11430      this->parserAtoms().internChar16(fc_, chars.begin(), chars.length());
  11431  if (!atom) {
  11432    return errorResult();
  11433  }
  11434  // RegExp patterm must be atomized.
  11435  this->parserAtoms().markUsedByStencil(atom, ParserAtom::Atomize::Yes);
  11436 
  11437  RegExpIndex index(this->compilationState_.regExpData.length());
  11438  if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
  11439    ReportAllocationOverflow(fc_);
  11440    return errorResult();
  11441  }
  11442  if (!this->compilationState_.regExpData.emplaceBack(atom, flags)) {
  11443    js::ReportOutOfMemory(this->fc_);
  11444    return errorResult();
  11445  }
  11446 
  11447  return handler_.newRegExp(index, pos());
  11448 }
  11449 
  11450 template <typename Unit>
  11451 SyntaxParseHandler::RegExpLiteralResult
  11452 Parser<SyntaxParseHandler, Unit>::newRegExp() {
  11453  MOZ_ASSERT(!options().selfHostingMode);
  11454 
  11455  // Only check the regexp's syntax, but don't create a regexp object.
  11456  const auto& chars = tokenStream.getCharBuffer();
  11457  RegExpFlags flags = anyChars.currentToken().regExpFlags();
  11458 
  11459  uint32_t offset = anyChars.currentToken().pos.begin;
  11460  uint32_t line;
  11461  JS::LimitedColumnNumberOneOrigin column;
  11462  tokenStream.computeLineAndColumn(offset, &line, &column);
  11463 
  11464  mozilla::Range<const char16_t> source(chars.begin(), chars.length());
  11465  if (!irregexp::CheckPatternSyntax(this->alloc_, this->fc_->stackLimit(),
  11466                                    anyChars, source, flags, Some(line),
  11467                                    Some(JS::ColumnNumberOneOrigin(column)))) {
  11468    return errorResult();
  11469  }
  11470 
  11471  return handler_.newRegExp(SyntaxParseHandler::Node::NodeGeneric, pos());
  11472 }
  11473 
  11474 template <class ParseHandler, typename Unit>
  11475 typename ParseHandler::RegExpLiteralResult
  11476 GeneralParser<ParseHandler, Unit>::newRegExp() {
  11477  return asFinalParser()->newRegExp();
  11478 }
  11479 
  11480 template <typename Unit>
  11481 FullParseHandler::BigIntLiteralResult
  11482 Parser<FullParseHandler, Unit>::newBigInt() {
  11483  // The token's charBuffer contains the DecimalIntegerLiteral or
  11484  // NonDecimalIntegerLiteral production, and as such does not include the
  11485  // BigIntLiteralSuffix (the trailing "n").  Note that NonDecimalIntegerLiteral
  11486  // productions start with 0[bBoOxX], indicating binary/octal/hex.
  11487  const auto& chars = tokenStream.getCharBuffer();
  11488  if (chars.length() > UINT32_MAX) {
  11489    ReportAllocationOverflow(fc_);
  11490    return errorResult();
  11491  }
  11492 
  11493  BigIntIndex index(this->bigInts().length());
  11494  if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
  11495    ReportAllocationOverflow(fc_);
  11496    return errorResult();
  11497  }
  11498  if (!this->bigInts().emplaceBack()) {
  11499    js::ReportOutOfMemory(this->fc_);
  11500    return errorResult();
  11501  }
  11502 
  11503  if (!this->bigInts()[index].init(this->fc_, this->stencilAlloc(), chars)) {
  11504    return errorResult();
  11505  }
  11506 
  11507  // Should the operations below fail, the buffer held by data will
  11508  // be cleaned up by the CompilationState destructor.
  11509  return handler_.newBigInt(index, pos());
  11510 }
  11511 
  11512 template <typename Unit>
  11513 SyntaxParseHandler::BigIntLiteralResult
  11514 Parser<SyntaxParseHandler, Unit>::newBigInt() {
  11515  // The tokenizer has already checked the syntax of the bigint.
  11516 
  11517  return handler_.newBigInt();
  11518 }
  11519 
  11520 template <class ParseHandler, typename Unit>
  11521 typename ParseHandler::BigIntLiteralResult
  11522 GeneralParser<ParseHandler, Unit>::newBigInt() {
  11523  return asFinalParser()->newBigInt();
  11524 }
  11525 
  11526 // |exprPossibleError| is the PossibleError state within |expr|,
  11527 // |possibleError| is the surrounding PossibleError state.
  11528 template <class ParseHandler, typename Unit>
  11529 bool GeneralParser<ParseHandler, Unit>::checkDestructuringAssignmentTarget(
  11530    Node expr, TokenPos exprPos, PossibleError* exprPossibleError,
  11531    PossibleError* possibleError, TargetBehavior behavior) {
  11532  // Report any pending expression error if we're definitely not in a
  11533  // destructuring context or the possible destructuring target is a
  11534  // property accessor.
  11535  if (!possibleError || handler_.isPropertyOrPrivateMemberAccess(expr)) {
  11536    return exprPossibleError->checkForExpressionError();
  11537  }
  11538 
  11539  // |expr| may end up as a destructuring assignment target, so we need to
  11540  // validate it's either a name or can be parsed as a nested destructuring
  11541  // pattern. Property accessors are also valid assignment targets, but
  11542  // those are already handled above.
  11543 
  11544  exprPossibleError->transferErrorsTo(possibleError);
  11545 
  11546  // Return early if a pending destructuring error is already present.
  11547  if (possibleError->hasPendingDestructuringError()) {
  11548    return true;
  11549  }
  11550 
  11551  if (handler_.isName(expr)) {
  11552    checkDestructuringAssignmentName(handler_.asNameNode(expr), exprPos,
  11553                                     possibleError);
  11554    return true;
  11555  }
  11556 
  11557  if (handler_.isUnparenthesizedDestructuringPattern(expr)) {
  11558    if (behavior == TargetBehavior::ForbidAssignmentPattern) {
  11559      possibleError->setPendingDestructuringErrorAt(exprPos,
  11560                                                    JSMSG_BAD_DESTRUCT_TARGET);
  11561    }
  11562    return true;
  11563  }
  11564 
  11565  // Parentheses are forbidden around destructuring *patterns* (but allowed
  11566  // around names). Use our nicer error message for parenthesized, nested
  11567  // patterns if nested destructuring patterns are allowed.
  11568  if (handler_.isParenthesizedDestructuringPattern(expr) &&
  11569      behavior != TargetBehavior::ForbidAssignmentPattern) {
  11570    possibleError->setPendingDestructuringErrorAt(exprPos,
  11571                                                  JSMSG_BAD_DESTRUCT_PARENS);
  11572  } else {
  11573    possibleError->setPendingDestructuringErrorAt(exprPos,
  11574                                                  JSMSG_BAD_DESTRUCT_TARGET);
  11575  }
  11576 
  11577  return true;
  11578 }
  11579 
  11580 template <class ParseHandler, typename Unit>
  11581 void GeneralParser<ParseHandler, Unit>::checkDestructuringAssignmentName(
  11582    NameNodeType name, TokenPos namePos, PossibleError* possibleError) {
  11583 #ifdef DEBUG
  11584  // GCC 8.0.1 crashes if this is a one-liner.
  11585  bool isName = handler_.isName(name);
  11586  MOZ_ASSERT(isName);
  11587 #endif
  11588 
  11589  // Return early if a pending destructuring error is already present.
  11590  if (possibleError->hasPendingDestructuringError()) {
  11591    return;
  11592  }
  11593 
  11594  if (handler_.isArgumentsLength(name)) {
  11595    pc_->sc()->setIneligibleForArgumentsLength();
  11596  }
  11597 
  11598  if (pc_->sc()->strict()) {
  11599    if (handler_.isArgumentsName(name)) {
  11600      if (pc_->sc()->strict()) {
  11601        possibleError->setPendingDestructuringErrorAt(
  11602            namePos, JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS);
  11603      } else {
  11604        possibleError->setPendingDestructuringWarningAt(
  11605            namePos, JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS);
  11606      }
  11607      return;
  11608    }
  11609 
  11610    if (handler_.isEvalName(name)) {
  11611      if (pc_->sc()->strict()) {
  11612        possibleError->setPendingDestructuringErrorAt(
  11613            namePos, JSMSG_BAD_STRICT_ASSIGN_EVAL);
  11614      } else {
  11615        possibleError->setPendingDestructuringWarningAt(
  11616            namePos, JSMSG_BAD_STRICT_ASSIGN_EVAL);
  11617      }
  11618      return;
  11619    }
  11620  }
  11621 }
  11622 
  11623 template <class ParseHandler, typename Unit>
  11624 bool GeneralParser<ParseHandler, Unit>::checkDestructuringAssignmentElement(
  11625    Node expr, TokenPos exprPos, PossibleError* exprPossibleError,
  11626    PossibleError* possibleError) {
  11627  // ES2018 draft rev 0719f44aab93215ed9a626b2f45bd34f36916834
  11628  // 12.15.5 Destructuring Assignment
  11629  //
  11630  // AssignmentElement[Yield, Await]:
  11631  //   DestructuringAssignmentTarget[?Yield, ?Await]
  11632  //   DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In,
  11633  //                                                             ?Yield,
  11634  //                                                             ?Await]
  11635 
  11636  // If |expr| is an assignment element with an initializer expression, its
  11637  // destructuring assignment target was already validated in assignExpr().
  11638  // Otherwise we need to check that |expr| is a valid destructuring target.
  11639  if (handler_.isUnparenthesizedAssignment(expr)) {
  11640    // Report any pending expression error if we're definitely not in a
  11641    // destructuring context.
  11642    if (!possibleError) {
  11643      return exprPossibleError->checkForExpressionError();
  11644    }
  11645 
  11646    exprPossibleError->transferErrorsTo(possibleError);
  11647    return true;
  11648  }
  11649  return checkDestructuringAssignmentTarget(expr, exprPos, exprPossibleError,
  11650                                            possibleError);
  11651 }
  11652 
  11653 template <class ParseHandler, typename Unit>
  11654 typename ParseHandler::ListNodeResult
  11655 GeneralParser<ParseHandler, Unit>::arrayInitializer(
  11656    YieldHandling yieldHandling, PossibleError* possibleError) {
  11657  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftBracket));
  11658 
  11659  uint32_t begin = pos().begin;
  11660  ListNodeType literal = MOZ_TRY(handler_.newArrayLiteral(begin));
  11661 
  11662  TokenKind tt;
  11663  if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
  11664    return errorResult();
  11665  }
  11666 
  11667  if (tt == TokenKind::RightBracket) {
  11668    /*
  11669     * Mark empty arrays as non-constant, since we cannot easily
  11670     * determine their type.
  11671     */
  11672    handler_.setListHasNonConstInitializer(literal);
  11673  } else {
  11674    anyChars.ungetToken();
  11675 
  11676    for (uint32_t index = 0;; index++) {
  11677      if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
  11678        error(JSMSG_ARRAY_INIT_TOO_BIG);
  11679        return errorResult();
  11680      }
  11681 
  11682      TokenKind tt;
  11683      if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
  11684        return errorResult();
  11685      }
  11686      if (tt == TokenKind::RightBracket) {
  11687        break;
  11688      }
  11689 
  11690      if (tt == TokenKind::Comma) {
  11691        tokenStream.consumeKnownToken(TokenKind::Comma,
  11692                                      TokenStream::SlashIsRegExp);
  11693        if (!handler_.addElision(literal, pos())) {
  11694          return errorResult();
  11695        }
  11696        continue;
  11697      }
  11698 
  11699      if (tt == TokenKind::TripleDot) {
  11700        tokenStream.consumeKnownToken(TokenKind::TripleDot,
  11701                                      TokenStream::SlashIsRegExp);
  11702        uint32_t begin = pos().begin;
  11703 
  11704        TokenPos innerPos;
  11705        if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
  11706          return errorResult();
  11707        }
  11708 
  11709        PossibleError possibleErrorInner(*this);
  11710        Node inner =
  11711            MOZ_TRY(assignExpr(InAllowed, yieldHandling, TripledotProhibited,
  11712                               &possibleErrorInner));
  11713        if (!checkDestructuringAssignmentTarget(
  11714                inner, innerPos, &possibleErrorInner, possibleError)) {
  11715          return errorResult();
  11716        }
  11717 
  11718        if (!handler_.addSpreadElement(literal, begin, inner)) {
  11719          return errorResult();
  11720        }
  11721      } else {
  11722        TokenPos elementPos;
  11723        if (!tokenStream.peekTokenPos(&elementPos,
  11724                                      TokenStream::SlashIsRegExp)) {
  11725          return errorResult();
  11726        }
  11727 
  11728        PossibleError possibleErrorInner(*this);
  11729        Node element =
  11730            MOZ_TRY(assignExpr(InAllowed, yieldHandling, TripledotProhibited,
  11731                               &possibleErrorInner));
  11732        if (!checkDestructuringAssignmentElement(
  11733                element, elementPos, &possibleErrorInner, possibleError)) {
  11734          return errorResult();
  11735        }
  11736        handler_.addArrayElement(literal, element);
  11737      }
  11738 
  11739      bool matched;
  11740      if (!tokenStream.matchToken(&matched, TokenKind::Comma,
  11741                                  TokenStream::SlashIsRegExp)) {
  11742        return errorResult();
  11743      }
  11744      if (!matched) {
  11745        break;
  11746      }
  11747 
  11748      if (tt == TokenKind::TripleDot && possibleError) {
  11749        possibleError->setPendingDestructuringErrorAt(pos(),
  11750                                                      JSMSG_REST_WITH_COMMA);
  11751      }
  11752    }
  11753 
  11754    if (!mustMatchToken(
  11755            TokenKind::RightBracket, [this, begin](TokenKind actual) {
  11756              this->reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
  11757                                         JSMSG_BRACKET_OPENED, begin);
  11758            })) {
  11759      return errorResult();
  11760    }
  11761  }
  11762 
  11763  handler_.setEndPosition(literal, pos().end);
  11764  return literal;
  11765 }
  11766 
  11767 template <class ParseHandler, typename Unit>
  11768 typename ParseHandler::NodeResult
  11769 GeneralParser<ParseHandler, Unit>::propertyName(
  11770    YieldHandling yieldHandling, PropertyNameContext propertyNameContext,
  11771    const Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
  11772    TaggedParserAtomIndex* propAtomOut) {
  11773  // PropertyName[Yield, Await]:
  11774  //   LiteralPropertyName
  11775  //   ComputedPropertyName[?Yield, ?Await]
  11776  //
  11777  // LiteralPropertyName:
  11778  //   IdentifierName
  11779  //   StringLiteral
  11780  //   NumericLiteral
  11781  TokenKind ltok = anyChars.currentToken().type;
  11782 
  11783  *propAtomOut = TaggedParserAtomIndex::null();
  11784  switch (ltok) {
  11785    case TokenKind::Number: {
  11786      auto numAtom = NumberToParserAtom(fc_, this->parserAtoms(),
  11787                                        anyChars.currentToken().number());
  11788      if (!numAtom) {
  11789        return errorResult();
  11790      }
  11791      *propAtomOut = numAtom;
  11792      return newNumber(anyChars.currentToken());
  11793    }
  11794 
  11795    case TokenKind::BigInt: {
  11796      Node biNode = MOZ_TRY(newBigInt());
  11797      return handler_.newSyntheticComputedName(biNode, pos().begin, pos().end);
  11798    }
  11799    case TokenKind::String: {
  11800      auto str = anyChars.currentToken().atom();
  11801      *propAtomOut = str;
  11802      uint32_t index;
  11803      if (this->parserAtoms().isIndex(str, &index)) {
  11804        return handler_.newNumber(index, NoDecimal, pos());
  11805      }
  11806      return stringLiteral();
  11807    }
  11808 
  11809    case TokenKind::LeftBracket:
  11810      return computedPropertyName(yieldHandling, maybeDecl, propertyNameContext,
  11811                                  propList);
  11812 
  11813    case TokenKind::PrivateName: {
  11814      if (propertyNameContext != PropertyNameContext::PropertyNameInClass) {
  11815        error(JSMSG_ILLEGAL_PRIVATE_FIELD);
  11816        return errorResult();
  11817      }
  11818 
  11819      TaggedParserAtomIndex propName = anyChars.currentName();
  11820      *propAtomOut = propName;
  11821      return privateNameReference(propName);
  11822    }
  11823 
  11824    default: {
  11825      if (!TokenKindIsPossibleIdentifierName(ltok)) {
  11826        error(JSMSG_UNEXPECTED_TOKEN, "property name", TokenKindToDesc(ltok));
  11827        return errorResult();
  11828      }
  11829 
  11830      TaggedParserAtomIndex name = anyChars.currentName();
  11831      *propAtomOut = name;
  11832      return handler_.newObjectLiteralPropertyName(name, pos());
  11833    }
  11834  }
  11835 }
  11836 
  11837 // True if `kind` can be the first token of a PropertyName.
  11838 static bool TokenKindCanStartPropertyName(TokenKind tt) {
  11839  return TokenKindIsPossibleIdentifierName(tt) || tt == TokenKind::String ||
  11840         tt == TokenKind::Number || tt == TokenKind::LeftBracket ||
  11841         tt == TokenKind::BigInt || tt == TokenKind::PrivateName;
  11842 }
  11843 
  11844 template <class ParseHandler, typename Unit>
  11845 typename ParseHandler::NodeResult
  11846 GeneralParser<ParseHandler, Unit>::propertyOrMethodName(
  11847    YieldHandling yieldHandling, PropertyNameContext propertyNameContext,
  11848    const Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
  11849    PropertyType* propType, TaggedParserAtomIndex* propAtomOut) {
  11850  // We're parsing an object literal, class, or destructuring pattern;
  11851  // propertyNameContext tells which one. This method parses any of the
  11852  // following, storing the corresponding PropertyType in `*propType` to tell
  11853  // the caller what we parsed:
  11854  //
  11855  //     async [no LineTerminator here] PropertyName
  11856  //                            ==> PropertyType::AsyncMethod
  11857  //     async [no LineTerminator here] * PropertyName
  11858  //                            ==> PropertyType::AsyncGeneratorMethod
  11859  //     * PropertyName         ==> PropertyType::GeneratorMethod
  11860  //     get PropertyName       ==> PropertyType::Getter
  11861  //     set PropertyName       ==> PropertyType::Setter
  11862  //     accessor PropertyName  ==> PropertyType::FieldWithAccessor
  11863  //     PropertyName :         ==> PropertyType::Normal
  11864  //     PropertyName           ==> see below
  11865  //
  11866  // In the last case, where there's not a `:` token to consume, we peek at
  11867  // (but don't consume) the next token to decide how to set `*propType`.
  11868  //
  11869  //     `,` or `}`             ==> PropertyType::Shorthand
  11870  //     `(`                    ==> PropertyType::Method
  11871  //     `=`, not in a class    ==> PropertyType::CoverInitializedName
  11872  //     '=', in a class        ==> PropertyType::Field
  11873  //     any token, in a class  ==> PropertyType::Field (ASI)
  11874  //
  11875  // The caller must check `*propType` and throw if whatever we parsed isn't
  11876  // allowed here (for example, a getter in a destructuring pattern).
  11877  //
  11878  // This method does *not* match `static` (allowed in classes) or `...`
  11879  // (allowed in object literals and patterns). The caller must take care of
  11880  // those before calling this method.
  11881 
  11882  TokenKind ltok;
  11883  if (!tokenStream.getToken(&ltok, TokenStream::SlashIsInvalid)) {
  11884    return errorResult();
  11885  }
  11886 
  11887  MOZ_ASSERT(ltok != TokenKind::RightCurly,
  11888             "caller should have handled TokenKind::RightCurly");
  11889 
  11890  // Accept `async` and/or `*`, indicating an async or generator method;
  11891  // or `get` or `set` or `accessor`, indicating an accessor.
  11892  bool isGenerator = false;
  11893  bool isAsync = false;
  11894  bool isGetter = false;
  11895  bool isSetter = false;
  11896 #ifdef ENABLE_DECORATORS
  11897  bool hasAccessor = false;
  11898 #endif
  11899 
  11900  if (ltok == TokenKind::Async) {
  11901    // `async` is also a PropertyName by itself (it's a conditional keyword),
  11902    // so peek at the next token to see if we're really looking at a method.
  11903    TokenKind tt = TokenKind::Eof;
  11904    if (!tokenStream.peekTokenSameLine(&tt)) {
  11905      return errorResult();
  11906    }
  11907    if (TokenKindCanStartPropertyName(tt) || tt == TokenKind::Mul) {
  11908      isAsync = true;
  11909      tokenStream.consumeKnownToken(tt);
  11910      ltok = tt;
  11911    }
  11912  }
  11913 
  11914  if (ltok == TokenKind::Mul) {
  11915    isGenerator = true;
  11916    if (!tokenStream.getToken(&ltok)) {
  11917      return errorResult();
  11918    }
  11919  }
  11920 
  11921  if (!isAsync && !isGenerator &&
  11922      (ltok == TokenKind::Get || ltok == TokenKind::Set)) {
  11923    // We have parsed |get| or |set|. Look for an accessor property
  11924    // name next.
  11925    TokenKind tt;
  11926    if (!tokenStream.peekToken(&tt)) {
  11927      return errorResult();
  11928    }
  11929    if (TokenKindCanStartPropertyName(tt)) {
  11930      tokenStream.consumeKnownToken(tt);
  11931      isGetter = (ltok == TokenKind::Get);
  11932      isSetter = (ltok == TokenKind::Set);
  11933    }
  11934  }
  11935 
  11936 #ifdef ENABLE_DECORATORS
  11937  if (!isGenerator && !isAsync && propertyNameContext == PropertyNameInClass &&
  11938      ltok == TokenKind::Accessor) {
  11939    MOZ_ASSERT(!isGetter && !isSetter);
  11940    TokenKind tt;
  11941    if (!tokenStream.peekTokenSameLine(&tt)) {
  11942      return errorResult();
  11943    }
  11944 
  11945    // The target rule is `accessor [no LineTerminator here]
  11946    // ClassElementName[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt`
  11947    if (TokenKindCanStartPropertyName(tt)) {
  11948      tokenStream.consumeKnownToken(tt);
  11949      hasAccessor = true;
  11950    }
  11951  }
  11952 #endif
  11953 
  11954  Node propName = MOZ_TRY(propertyName(yieldHandling, propertyNameContext,
  11955                                       maybeDecl, propList, propAtomOut));
  11956 
  11957  // Grab the next token following the property/method name.
  11958  // (If this isn't a colon, we're going to either put it back or throw.)
  11959  TokenKind tt;
  11960  if (!tokenStream.getToken(&tt)) {
  11961    return errorResult();
  11962  }
  11963 
  11964  if (tt == TokenKind::Colon) {
  11965    if (isGenerator || isAsync || isGetter || isSetter
  11966 #ifdef ENABLE_DECORATORS
  11967        || hasAccessor
  11968 #endif
  11969    ) {
  11970      error(JSMSG_BAD_PROP_ID);
  11971      return errorResult();
  11972    }
  11973    *propType = PropertyType::Normal;
  11974    return propName;
  11975  }
  11976 
  11977  if (propertyNameContext != PropertyNameInClass &&
  11978      TokenKindIsPossibleIdentifierName(ltok) &&
  11979      (tt == TokenKind::Comma || tt == TokenKind::RightCurly ||
  11980       tt == TokenKind::Assign)) {
  11981 #ifdef ENABLE_DECORATORS
  11982    MOZ_ASSERT(!hasAccessor);
  11983 #endif
  11984    if (isGenerator || isAsync || isGetter || isSetter) {
  11985      error(JSMSG_BAD_PROP_ID);
  11986      return errorResult();
  11987    }
  11988 
  11989    anyChars.ungetToken();
  11990    *propType = tt == TokenKind::Assign ? PropertyType::CoverInitializedName
  11991                                        : PropertyType::Shorthand;
  11992    return propName;
  11993  }
  11994 
  11995  if (tt == TokenKind::LeftParen) {
  11996    anyChars.ungetToken();
  11997 
  11998 #ifdef ENABLE_DECORATORS
  11999    if (hasAccessor) {
  12000      error(JSMSG_BAD_PROP_ID);
  12001      return errorResult();
  12002    }
  12003 #endif
  12004 
  12005    if (isGenerator && isAsync) {
  12006      *propType = PropertyType::AsyncGeneratorMethod;
  12007    } else if (isGenerator) {
  12008      *propType = PropertyType::GeneratorMethod;
  12009    } else if (isAsync) {
  12010      *propType = PropertyType::AsyncMethod;
  12011    } else if (isGetter) {
  12012      *propType = PropertyType::Getter;
  12013    } else if (isSetter) {
  12014      *propType = PropertyType::Setter;
  12015    } else {
  12016      *propType = PropertyType::Method;
  12017    }
  12018    return propName;
  12019  }
  12020 
  12021  if (propertyNameContext == PropertyNameInClass) {
  12022    if (isGenerator || isAsync || isGetter || isSetter) {
  12023      error(JSMSG_BAD_PROP_ID);
  12024      return errorResult();
  12025    }
  12026    anyChars.ungetToken();
  12027 #ifdef ENABLE_DECORATORS
  12028    if (!hasAccessor) {
  12029      *propType = PropertyType::Field;
  12030    } else {
  12031      *propType = PropertyType::FieldWithAccessor;
  12032    }
  12033 #else
  12034    *propType = PropertyType::Field;
  12035 #endif
  12036    return propName;
  12037  }
  12038 
  12039  error(JSMSG_COLON_AFTER_ID);
  12040  return errorResult();
  12041 }
  12042 
  12043 template <class ParseHandler, typename Unit>
  12044 typename ParseHandler::UnaryNodeResult
  12045 GeneralParser<ParseHandler, Unit>::computedPropertyName(
  12046    YieldHandling yieldHandling, const Maybe<DeclarationKind>& maybeDecl,
  12047    PropertyNameContext propertyNameContext, ListNodeType literal) {
  12048  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftBracket));
  12049 
  12050  uint32_t begin = pos().begin;
  12051 
  12052  if (maybeDecl) {
  12053    if (*maybeDecl == DeclarationKind::FormalParameter) {
  12054      pc_->functionBox()->hasParameterExprs = true;
  12055    }
  12056  } else if (propertyNameContext ==
  12057             PropertyNameContext::PropertyNameInLiteral) {
  12058    handler_.setListHasNonConstInitializer(literal);
  12059  }
  12060 
  12061  Node assignNode =
  12062      MOZ_TRY(assignExpr(InAllowed, yieldHandling, TripledotProhibited));
  12063 
  12064  if (!mustMatchToken(TokenKind::RightBracket, JSMSG_COMP_PROP_UNTERM_EXPR)) {
  12065    return errorResult();
  12066  }
  12067  return handler_.newComputedName(assignNode, begin, pos().end);
  12068 }
  12069 
  12070 template <class ParseHandler, typename Unit>
  12071 typename ParseHandler::ListNodeResult
  12072 GeneralParser<ParseHandler, Unit>::objectLiteral(YieldHandling yieldHandling,
  12073                                                 PossibleError* possibleError) {
  12074  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftCurly));
  12075 
  12076  uint32_t openedPos = pos().begin;
  12077 
  12078  ListNodeType literal = MOZ_TRY(handler_.newObjectLiteral(pos().begin));
  12079 
  12080  bool seenPrototypeMutation = false;
  12081  bool seenCoverInitializedName = false;
  12082  Maybe<DeclarationKind> declKind = Nothing();
  12083  TaggedParserAtomIndex propAtom;
  12084  for (;;) {
  12085    TokenKind tt;
  12086    if (!tokenStream.peekToken(&tt)) {
  12087      return errorResult();
  12088    }
  12089    if (tt == TokenKind::RightCurly) {
  12090      break;
  12091    }
  12092 
  12093    if (tt == TokenKind::TripleDot) {
  12094      tokenStream.consumeKnownToken(TokenKind::TripleDot);
  12095      uint32_t begin = pos().begin;
  12096 
  12097      TokenPos innerPos;
  12098      if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
  12099        return errorResult();
  12100      }
  12101 
  12102      PossibleError possibleErrorInner(*this);
  12103      Node inner = MOZ_TRY(assignExpr(
  12104          InAllowed, yieldHandling, TripledotProhibited, &possibleErrorInner));
  12105      if (!checkDestructuringAssignmentTarget(
  12106              inner, innerPos, &possibleErrorInner, possibleError,
  12107              TargetBehavior::ForbidAssignmentPattern)) {
  12108        return errorResult();
  12109      }
  12110      if (!handler_.addSpreadProperty(literal, begin, inner)) {
  12111        return errorResult();
  12112      }
  12113    } else {
  12114      TokenPos namePos = anyChars.nextToken().pos;
  12115 
  12116      PropertyType propType;
  12117      Node propName = MOZ_TRY(
  12118          propertyOrMethodName(yieldHandling, PropertyNameInLiteral, declKind,
  12119                               literal, &propType, &propAtom));
  12120 
  12121      if (propType == PropertyType::Normal) {
  12122        TokenPos exprPos;
  12123        if (!tokenStream.peekTokenPos(&exprPos, TokenStream::SlashIsRegExp)) {
  12124          return errorResult();
  12125        }
  12126 
  12127        PossibleError possibleErrorInner(*this);
  12128        Node propExpr =
  12129            MOZ_TRY(assignExpr(InAllowed, yieldHandling, TripledotProhibited,
  12130                               &possibleErrorInner));
  12131 
  12132        if (!checkDestructuringAssignmentElement(
  12133                propExpr, exprPos, &possibleErrorInner, possibleError)) {
  12134          return errorResult();
  12135        }
  12136 
  12137        if (propAtom == TaggedParserAtomIndex::WellKnown::proto_()) {
  12138          if (seenPrototypeMutation) {
  12139            // Directly report the error when we're definitely not
  12140            // in a destructuring context.
  12141            if (!possibleError) {
  12142              errorAt(namePos.begin, JSMSG_DUPLICATE_PROTO_PROPERTY);
  12143              return errorResult();
  12144            }
  12145 
  12146            // Otherwise delay error reporting until we've
  12147            // determined whether or not we're destructuring.
  12148            possibleError->setPendingExpressionErrorAt(
  12149                namePos, JSMSG_DUPLICATE_PROTO_PROPERTY);
  12150          }
  12151          seenPrototypeMutation = true;
  12152 
  12153          // This occurs *only* if we observe PropertyType::Normal!
  12154          // Only |__proto__: v| mutates [[Prototype]]. Getters,
  12155          // setters, method/generator definitions, computed
  12156          // property name versions of all of these, and shorthands
  12157          // do not.
  12158          if (!handler_.addPrototypeMutation(literal, namePos.begin,
  12159                                             propExpr)) {
  12160            return errorResult();
  12161          }
  12162        } else {
  12163          BinaryNodeType propDef =
  12164              MOZ_TRY(handler_.newPropertyDefinition(propName, propExpr));
  12165 
  12166          handler_.addPropertyDefinition(literal, propDef);
  12167        }
  12168      } else if (propType == PropertyType::Shorthand) {
  12169        /*
  12170         * Support, e.g., |({x, y} = o)| as destructuring shorthand
  12171         * for |({x: x, y: y} = o)|, and |var o = {x, y}| as
  12172         * initializer shorthand for |var o = {x: x, y: y}|.
  12173         */
  12174        TaggedParserAtomIndex name = identifierReference(yieldHandling);
  12175        if (!name) {
  12176          return errorResult();
  12177        }
  12178 
  12179        NameNodeType nameExpr = MOZ_TRY(identifierReference(name));
  12180 
  12181        if (possibleError) {
  12182          checkDestructuringAssignmentName(nameExpr, namePos, possibleError);
  12183        }
  12184 
  12185        if (!handler_.addShorthand(literal, handler_.asNameNode(propName),
  12186                                   nameExpr)) {
  12187          return errorResult();
  12188        }
  12189      } else if (propType == PropertyType::CoverInitializedName) {
  12190        /*
  12191         * Support, e.g., |({x=1, y=2} = o)| as destructuring
  12192         * shorthand with default values, as per ES6 12.14.5
  12193         */
  12194        TaggedParserAtomIndex name = identifierReference(yieldHandling);
  12195        if (!name) {
  12196          return errorResult();
  12197        }
  12198 
  12199        Node lhs = MOZ_TRY(identifierReference(name));
  12200 
  12201        tokenStream.consumeKnownToken(TokenKind::Assign);
  12202 
  12203        if (!seenCoverInitializedName) {
  12204          // "shorthand default" or "CoverInitializedName" syntax is
  12205          // only valid in the case of destructuring.
  12206          seenCoverInitializedName = true;
  12207 
  12208          if (!possibleError) {
  12209            // Destructuring defaults are definitely not allowed
  12210            // in this object literal, because of something the
  12211            // caller knows about the preceding code. For example,
  12212            // maybe the preceding token is an operator:
  12213            // |x + {y=z}|.
  12214            error(JSMSG_COLON_AFTER_ID);
  12215            return errorResult();
  12216          }
  12217 
  12218          // Here we set a pending error so that later in the parse,
  12219          // once we've determined whether or not we're
  12220          // destructuring, the error can be reported or ignored
  12221          // appropriately.
  12222          possibleError->setPendingExpressionErrorAt(pos(),
  12223                                                     JSMSG_COLON_AFTER_ID);
  12224        }
  12225 
  12226        if (const char* chars = nameIsArgumentsOrEval(lhs)) {
  12227          // |chars| is "arguments" or "eval" here.
  12228          if (!strictModeErrorAt(namePos.begin, JSMSG_BAD_STRICT_ASSIGN,
  12229                                 chars)) {
  12230            return errorResult();
  12231          }
  12232        }
  12233 
  12234        if (handler_.isArgumentsLength(lhs)) {
  12235          pc_->sc()->setIneligibleForArgumentsLength();
  12236        }
  12237 
  12238        Node rhs =
  12239            MOZ_TRY(assignExpr(InAllowed, yieldHandling, TripledotProhibited));
  12240 
  12241        BinaryNodeType propExpr = MOZ_TRY(
  12242            handler_.newAssignment(ParseNodeKind::AssignExpr, lhs, rhs));
  12243 
  12244        if (!handler_.addPropertyDefinition(literal, propName, propExpr)) {
  12245          return errorResult();
  12246        }
  12247      } else {
  12248        TaggedParserAtomIndex funName;
  12249        bool hasStaticName =
  12250            !anyChars.isCurrentTokenType(TokenKind::RightBracket) && propAtom;
  12251        if (hasStaticName) {
  12252          funName = propAtom;
  12253 
  12254          if (propType == PropertyType::Getter ||
  12255              propType == PropertyType::Setter) {
  12256            funName = prefixAccessorName(propType, propAtom);
  12257            if (!funName) {
  12258              return errorResult();
  12259            }
  12260          }
  12261        }
  12262 
  12263        FunctionNodeType funNode =
  12264            MOZ_TRY(methodDefinition(namePos.begin, propType, funName));
  12265 
  12266        AccessorType atype = ToAccessorType(propType);
  12267        if (!handler_.addObjectMethodDefinition(literal, propName, funNode,
  12268                                                atype)) {
  12269          return errorResult();
  12270        }
  12271 
  12272        if (possibleError) {
  12273          possibleError->setPendingDestructuringErrorAt(
  12274              namePos, JSMSG_BAD_DESTRUCT_TARGET);
  12275        }
  12276      }
  12277    }
  12278 
  12279    bool matched;
  12280    if (!tokenStream.matchToken(&matched, TokenKind::Comma,
  12281                                TokenStream::SlashIsInvalid)) {
  12282      return errorResult();
  12283    }
  12284    if (!matched) {
  12285      break;
  12286    }
  12287    if (tt == TokenKind::TripleDot && possibleError) {
  12288      possibleError->setPendingDestructuringErrorAt(pos(),
  12289                                                    JSMSG_REST_WITH_COMMA);
  12290    }
  12291  }
  12292 
  12293  if (!mustMatchToken(
  12294          TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
  12295            this->reportMissingClosing(JSMSG_CURLY_AFTER_LIST,
  12296                                       JSMSG_CURLY_OPENED, openedPos);
  12297          })) {
  12298    return errorResult();
  12299  }
  12300 
  12301  handler_.setEndPosition(literal, pos().end);
  12302  return literal;
  12303 }
  12304 
  12305 template <class ParseHandler, typename Unit>
  12306 typename ParseHandler::FunctionNodeResult
  12307 GeneralParser<ParseHandler, Unit>::methodDefinition(
  12308    uint32_t toStringStart, PropertyType propType,
  12309    TaggedParserAtomIndex funName) {
  12310  FunctionSyntaxKind syntaxKind;
  12311  switch (propType) {
  12312    case PropertyType::Getter:
  12313      syntaxKind = FunctionSyntaxKind::Getter;
  12314      break;
  12315 
  12316    case PropertyType::Setter:
  12317      syntaxKind = FunctionSyntaxKind::Setter;
  12318      break;
  12319 
  12320    case PropertyType::Method:
  12321    case PropertyType::GeneratorMethod:
  12322    case PropertyType::AsyncMethod:
  12323    case PropertyType::AsyncGeneratorMethod:
  12324      syntaxKind = FunctionSyntaxKind::Method;
  12325      break;
  12326 
  12327    case PropertyType::Constructor:
  12328      syntaxKind = FunctionSyntaxKind::ClassConstructor;
  12329      break;
  12330 
  12331    case PropertyType::DerivedConstructor:
  12332      syntaxKind = FunctionSyntaxKind::DerivedClassConstructor;
  12333      break;
  12334 
  12335    default:
  12336      MOZ_CRASH("unexpected property type");
  12337  }
  12338 
  12339  GeneratorKind generatorKind = (propType == PropertyType::GeneratorMethod ||
  12340                                 propType == PropertyType::AsyncGeneratorMethod)
  12341                                    ? GeneratorKind::Generator
  12342                                    : GeneratorKind::NotGenerator;
  12343 
  12344  FunctionAsyncKind asyncKind = (propType == PropertyType::AsyncMethod ||
  12345                                 propType == PropertyType::AsyncGeneratorMethod)
  12346                                    ? FunctionAsyncKind::AsyncFunction
  12347                                    : FunctionAsyncKind::SyncFunction;
  12348 
  12349  YieldHandling yieldHandling = GetYieldHandling(generatorKind);
  12350 
  12351  FunctionNodeType funNode = MOZ_TRY(handler_.newFunction(syntaxKind, pos()));
  12352 
  12353  return functionDefinition(funNode, toStringStart, InAllowed, yieldHandling,
  12354                            funName, syntaxKind, generatorKind, asyncKind);
  12355 }
  12356 
  12357 template <class ParseHandler, typename Unit>
  12358 bool GeneralParser<ParseHandler, Unit>::tryNewTarget(
  12359    NewTargetNodeType* newTarget) {
  12360  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::New));
  12361 
  12362  *newTarget = null();
  12363 
  12364  NullaryNodeType newHolder;
  12365  MOZ_TRY_VAR_OR_RETURN(newHolder, handler_.newPosHolder(pos()), false);
  12366 
  12367  uint32_t begin = pos().begin;
  12368 
  12369  // |new| expects to look for an operand, so we will honor that.
  12370  TokenKind next;
  12371  if (!tokenStream.getToken(&next, TokenStream::SlashIsRegExp)) {
  12372    return false;
  12373  }
  12374 
  12375  // Don't unget the token, since lookahead cannot handle someone calling
  12376  // getToken() with a different modifier. Callers should inspect
  12377  // currentToken().
  12378  if (next != TokenKind::Dot) {
  12379    return true;
  12380  }
  12381 
  12382  if (!tokenStream.getToken(&next)) {
  12383    return false;
  12384  }
  12385  if (next != TokenKind::Target) {
  12386    error(JSMSG_UNEXPECTED_TOKEN, "target", TokenKindToDesc(next));
  12387    return false;
  12388  }
  12389 
  12390  if (!pc_->sc()->allowNewTarget()) {
  12391    errorAt(begin, JSMSG_BAD_NEWTARGET);
  12392    return false;
  12393  }
  12394 
  12395  NullaryNodeType targetHolder;
  12396  MOZ_TRY_VAR_OR_RETURN(targetHolder, handler_.newPosHolder(pos()), false);
  12397 
  12398  NameNodeType newTargetName;
  12399  MOZ_TRY_VAR_OR_RETURN(newTargetName, newNewTargetName(), false);
  12400 
  12401  MOZ_TRY_VAR_OR_RETURN(
  12402      *newTarget, handler_.newNewTarget(newHolder, targetHolder, newTargetName),
  12403      false);
  12404 
  12405  return true;
  12406 }
  12407 
  12408 template <class ParseHandler, typename Unit>
  12409 typename ParseHandler::BinaryNodeResult
  12410 GeneralParser<ParseHandler, Unit>::importExpr(YieldHandling yieldHandling,
  12411                                              bool allowCallSyntax) {
  12412  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import));
  12413 
  12414  NullaryNodeType importHolder = MOZ_TRY(handler_.newPosHolder(pos()));
  12415 
  12416  TokenKind next;
  12417  if (!tokenStream.getToken(&next)) {
  12418    return errorResult();
  12419  }
  12420 
  12421  if (next == TokenKind::Dot) {
  12422    if (!tokenStream.getToken(&next)) {
  12423      return errorResult();
  12424    }
  12425    if (next != TokenKind::Meta) {
  12426      error(JSMSG_UNEXPECTED_TOKEN, "meta", TokenKindToDesc(next));
  12427      return errorResult();
  12428    }
  12429 
  12430    if (parseGoal() != ParseGoal::Module) {
  12431      errorAt(pos().begin, JSMSG_IMPORT_META_OUTSIDE_MODULE);
  12432      return errorResult();
  12433    }
  12434 
  12435    NullaryNodeType metaHolder = MOZ_TRY(handler_.newPosHolder(pos()));
  12436 
  12437    return handler_.newImportMeta(importHolder, metaHolder);
  12438  }
  12439 
  12440  if (next == TokenKind::LeftParen && allowCallSyntax) {
  12441    Node arg =
  12442        MOZ_TRY(assignExpr(InAllowed, yieldHandling, TripledotProhibited));
  12443 
  12444    if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
  12445      return errorResult();
  12446    }
  12447 
  12448    Node optionalArg;
  12449    if (next == TokenKind::Comma) {
  12450      tokenStream.consumeKnownToken(TokenKind::Comma,
  12451                                    TokenStream::SlashIsRegExp);
  12452 
  12453      if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
  12454        return errorResult();
  12455      }
  12456 
  12457      if (next != TokenKind::RightParen) {
  12458        optionalArg =
  12459            MOZ_TRY(assignExpr(InAllowed, yieldHandling, TripledotProhibited));
  12460 
  12461        if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
  12462          return errorResult();
  12463        }
  12464 
  12465        if (next == TokenKind::Comma) {
  12466          tokenStream.consumeKnownToken(TokenKind::Comma,
  12467                                        TokenStream::SlashIsRegExp);
  12468        }
  12469      } else {
  12470        optionalArg =
  12471            MOZ_TRY(handler_.newPosHolder(TokenPos(pos().end, pos().end)));
  12472      }
  12473    } else {
  12474      optionalArg =
  12475          MOZ_TRY(handler_.newPosHolder(TokenPos(pos().end, pos().end)));
  12476    }
  12477 
  12478    if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_ARGS)) {
  12479      return errorResult();
  12480    }
  12481 
  12482    Node spec = MOZ_TRY(handler_.newCallImportSpec(arg, optionalArg));
  12483 
  12484    return handler_.newCallImport(importHolder, spec);
  12485  }
  12486 
  12487  error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(next));
  12488  return errorResult();
  12489 }
  12490 
  12491 template <class ParseHandler, typename Unit>
  12492 typename ParseHandler::NodeResult
  12493 GeneralParser<ParseHandler, Unit>::primaryExpr(
  12494    YieldHandling yieldHandling, TripledotHandling tripledotHandling,
  12495    TokenKind tt, PossibleError* possibleError, InvokedPrediction invoked) {
  12496  MOZ_ASSERT(anyChars.isCurrentTokenType(tt));
  12497  AutoCheckRecursionLimit recursion(this->fc_);
  12498  if (!recursion.check(this->fc_)) {
  12499    return errorResult();
  12500  }
  12501 
  12502  switch (tt) {
  12503    case TokenKind::Function:
  12504      return functionExpr(pos().begin, invoked,
  12505                          FunctionAsyncKind::SyncFunction);
  12506 
  12507    case TokenKind::Class:
  12508      return classDefinition(yieldHandling, ClassExpression, NameRequired);
  12509 
  12510    case TokenKind::LeftBracket:
  12511      return arrayInitializer(yieldHandling, possibleError);
  12512 
  12513    case TokenKind::LeftCurly:
  12514      return objectLiteral(yieldHandling, possibleError);
  12515 
  12516 #ifdef ENABLE_DECORATORS
  12517    case TokenKind::At:
  12518      return classDefinition(yieldHandling, ClassExpression, NameRequired);
  12519 #endif
  12520 
  12521    case TokenKind::LeftParen: {
  12522      TokenKind next;
  12523      if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
  12524        return errorResult();
  12525      }
  12526 
  12527      if (next == TokenKind::RightParen) {
  12528        // Not valid expression syntax, but this is valid in an arrow function
  12529        // with no params: `() => body`.
  12530        tokenStream.consumeKnownToken(TokenKind::RightParen,
  12531                                      TokenStream::SlashIsRegExp);
  12532 
  12533        if (!tokenStream.peekToken(&next)) {
  12534          return errorResult();
  12535        }
  12536        if (next != TokenKind::Arrow) {
  12537          error(JSMSG_UNEXPECTED_TOKEN, "expression",
  12538                TokenKindToDesc(TokenKind::RightParen));
  12539          return errorResult();
  12540        }
  12541 
  12542        // Now just return something that will allow parsing to continue.
  12543        // It doesn't matter what; when we reach the =>, we will rewind and
  12544        // reparse the whole arrow function. See Parser::assignExpr.
  12545        return handler_.newNullLiteral(pos());
  12546      }
  12547 
  12548      // Pass |possibleError| to support destructuring in arrow parameters.
  12549      Node expr = MOZ_TRY(exprInParens(InAllowed, yieldHandling,
  12550                                       TripledotAllowed, possibleError));
  12551      if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_IN_PAREN)) {
  12552        return errorResult();
  12553      }
  12554      return handler_.parenthesize(expr);
  12555    }
  12556 
  12557    case TokenKind::TemplateHead:
  12558      return templateLiteral(yieldHandling);
  12559 
  12560    case TokenKind::NoSubsTemplate:
  12561      return noSubstitutionUntaggedTemplate();
  12562 
  12563    case TokenKind::String:
  12564      return stringLiteral();
  12565 
  12566    default: {
  12567      if (!TokenKindIsPossibleIdentifier(tt)) {
  12568        error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
  12569        return errorResult();
  12570      }
  12571 
  12572      if (tt == TokenKind::Async) {
  12573        TokenKind nextSameLine = TokenKind::Eof;
  12574        if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
  12575          return errorResult();
  12576        }
  12577 
  12578        if (nextSameLine == TokenKind::Function) {
  12579          uint32_t toStringStart = pos().begin;
  12580          tokenStream.consumeKnownToken(TokenKind::Function);
  12581          return functionExpr(toStringStart, PredictUninvoked,
  12582                              FunctionAsyncKind::AsyncFunction);
  12583        }
  12584      }
  12585 
  12586      TaggedParserAtomIndex name = identifierReference(yieldHandling);
  12587      if (!name) {
  12588        return errorResult();
  12589      }
  12590 
  12591      return identifierReference(name);
  12592    }
  12593 
  12594    case TokenKind::RegExp:
  12595      return newRegExp();
  12596 
  12597    case TokenKind::Number:
  12598      return newNumber(anyChars.currentToken());
  12599 
  12600    case TokenKind::BigInt:
  12601      return newBigInt();
  12602 
  12603    case TokenKind::True:
  12604      return handler_.newBooleanLiteral(true, pos());
  12605    case TokenKind::False:
  12606      return handler_.newBooleanLiteral(false, pos());
  12607    case TokenKind::This: {
  12608      NameNodeType thisName = null();
  12609      if (pc_->sc()->hasFunctionThisBinding()) {
  12610        thisName = MOZ_TRY(newThisName());
  12611      }
  12612      return handler_.newThisLiteral(pos(), thisName);
  12613    }
  12614    case TokenKind::Null:
  12615      return handler_.newNullLiteral(pos());
  12616 
  12617    case TokenKind::TripleDot: {
  12618      // This isn't valid expression syntax, but it's valid in an arrow
  12619      // function as a trailing rest param: `(a, b, ...rest) => body`.  Check
  12620      // if it's directly under
  12621      // CoverParenthesizedExpressionAndArrowParameterList, and check for a
  12622      // name, closing parenthesis, and arrow, and allow it only if all are
  12623      // present.
  12624      if (tripledotHandling != TripledotAllowed) {
  12625        error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
  12626        return errorResult();
  12627      }
  12628 
  12629      TokenKind next;
  12630      if (!tokenStream.getToken(&next)) {
  12631        return errorResult();
  12632      }
  12633 
  12634      if (next == TokenKind::LeftBracket || next == TokenKind::LeftCurly) {
  12635        // Validate, but don't store the pattern right now. The whole arrow
  12636        // function is reparsed in functionFormalParametersAndBody().
  12637        MOZ_TRY(destructuringDeclaration(DeclarationKind::CoverArrowParameter,
  12638                                         yieldHandling, next));
  12639      } else {
  12640        // This doesn't check that the provided name is allowed, e.g. if
  12641        // the enclosing code is strict mode code, any of "let", "yield",
  12642        // or "arguments" should be prohibited.  Argument-parsing code
  12643        // handles that.
  12644        if (!TokenKindIsPossibleIdentifier(next)) {
  12645          error(JSMSG_UNEXPECTED_TOKEN, "rest argument name",
  12646                TokenKindToDesc(next));
  12647          return errorResult();
  12648        }
  12649      }
  12650 
  12651      if (!tokenStream.getToken(&next)) {
  12652        return errorResult();
  12653      }
  12654      if (next != TokenKind::RightParen) {
  12655        error(JSMSG_UNEXPECTED_TOKEN, "closing parenthesis",
  12656              TokenKindToDesc(next));
  12657        return errorResult();
  12658      }
  12659 
  12660      if (!tokenStream.peekToken(&next)) {
  12661        return errorResult();
  12662      }
  12663      if (next != TokenKind::Arrow) {
  12664        // Advance the scanner for proper error location reporting.
  12665        tokenStream.consumeKnownToken(next);
  12666        error(JSMSG_UNEXPECTED_TOKEN, "'=>' after argument list",
  12667              TokenKindToDesc(next));
  12668        return errorResult();
  12669      }
  12670 
  12671      anyChars.ungetToken();  // put back right paren
  12672 
  12673      // Return an arbitrary expression node. See case TokenKind::RightParen
  12674      // above.
  12675      return handler_.newNullLiteral(pos());
  12676    }
  12677  }
  12678 }
  12679 
  12680 template <class ParseHandler, typename Unit>
  12681 typename ParseHandler::NodeResult
  12682 GeneralParser<ParseHandler, Unit>::exprInParens(
  12683    InHandling inHandling, YieldHandling yieldHandling,
  12684    TripledotHandling tripledotHandling,
  12685    PossibleError* possibleError /* = nullptr */) {
  12686  MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftParen));
  12687  return expr(inHandling, yieldHandling, tripledotHandling, possibleError,
  12688              PredictInvoked);
  12689 }
  12690 
  12691 template class PerHandlerParser<FullParseHandler>;
  12692 template class PerHandlerParser<SyntaxParseHandler>;
  12693 template class GeneralParser<FullParseHandler, Utf8Unit>;
  12694 template class GeneralParser<SyntaxParseHandler, Utf8Unit>;
  12695 template class GeneralParser<FullParseHandler, char16_t>;
  12696 template class GeneralParser<SyntaxParseHandler, char16_t>;
  12697 template class Parser<FullParseHandler, Utf8Unit>;
  12698 template class Parser<SyntaxParseHandler, Utf8Unit>;
  12699 template class Parser<FullParseHandler, char16_t>;
  12700 template class Parser<SyntaxParseHandler, char16_t>;
  12701 
  12702 }  // namespace js::frontend