tor-browser

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

Parser.h (76904B)


      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 /* JS parser. */
      8 
      9 #ifndef frontend_Parser_h
     10 #define frontend_Parser_h
     11 
     12 /*
     13 * [SMDOC] JS Parser
     14 *
     15 * JS parsers capable of generating ASTs from source text.
     16 *
     17 * A parser embeds token stream information, then gets and matches tokens to
     18 * generate a syntax tree that, if desired, BytecodeEmitter will use to compile
     19 * bytecode.
     20 *
     21 * Like token streams (see the comment near the top of TokenStream.h), parser
     22 * classes are heavily templatized -- along the token stream's character-type
     23 * axis, and also along a full-parse/syntax-parse axis.  Certain limitations of
     24 * C++ (primarily the inability to partially specialize function templates),
     25 * plus the desire to minimize compiled code size in duplicate function
     26 * template instantiations wherever possible, mean that Parser exhibits much of
     27 * the same unholy template/inheritance complexity as token streams.
     28 *
     29 * == ParserSharedBase ==
     30 *
     31 * ParserSharedBase is the base class for both regular JS and BinAST parsing.
     32 * This class contains common fields and methods between both parsers. There is
     33 * currently no BinAST parser here so this can potentially be merged into the
     34 * ParserBase type below.
     35 *
     36 * == ParserBase → ParserSharedBase, ErrorReportMixin ==
     37 *
     38 * ParserBase is the base class for regular JS parser, shared by all regular JS
     39 * parsers of all character types and parse-handling behavior.  It stores
     40 * everything character- and handler-agnostic.
     41 *
     42 * ParserBase's most important field is the parser's token stream's
     43 * |TokenStreamAnyChars| component, for all tokenizing aspects that are
     44 * character-type-agnostic.  The character-type-sensitive components residing
     45 * in |TokenStreamSpecific| (see the comment near the top of TokenStream.h)
     46 * live elsewhere in this hierarchy.  These separate locations are the reason
     47 * for the |AnyCharsAccess| template parameter to |TokenStreamChars| and
     48 * |TokenStreamSpecific|.
     49 *
     50 * == PerHandlerParser<ParseHandler> → ParserBase ==
     51 *
     52 * Certain parsing behavior varies between full parsing and syntax-only parsing
     53 * but does not vary across source-text character types.  For example, the work
     54 * to "create an arguments object for a function" obviously varies between
     55 * syntax and full parsing but (because no source characters are examined) does
     56 * not vary by source text character type.  Such functionality is implemented
     57 * through functions in PerHandlerParser.
     58 *
     59 * Functionality only used by syntax parsing or full parsing doesn't live here:
     60 * it should be implemented in the appropriate Parser<ParseHandler> (described
     61 * further below).
     62 *
     63 * == GeneralParser<ParseHandler, Unit> → PerHandlerParser<ParseHandler> ==
     64 *
     65 * Most parsing behavior varies across the character-type axis (and possibly
     66 * along the full/syntax axis).  For example:
     67 *
     68 *   * Parsing ECMAScript's Expression production, implemented by
     69 *     GeneralParser::expr, varies in this manner: different types are used to
     70 *     represent nodes in full and syntax parsing (ParseNode* versus an enum),
     71 *     and reading the tokens comprising the expression requires inspecting
     72 *     individual characters (necessarily dependent upon character type).
     73 *   * Reporting an error or warning does not depend on the full/syntax parsing
     74 *     distinction.  But error reports and warnings include a line of context
     75 *     (or a slice of one), for pointing out where a mistake was made.
     76 *     Computing such line of context requires inspecting the source text to
     77 *     make that line/slice of context, which requires knowing the source text
     78 *     character type.
     79 *
     80 * Such functionality, implemented using identical function code across these
     81 * axes, should live in GeneralParser.
     82 *
     83 * GeneralParser's most important field is the parser's token stream's
     84 * |TokenStreamSpecific| component, for all aspects of tokenizing that (contra
     85 * |TokenStreamAnyChars| in ParserBase above) are character-type-sensitive.  As
     86 * noted above, this field's existence separate from that in ParserBase
     87 * motivates the |AnyCharsAccess| template parameters on various token stream
     88 * classes.
     89 *
     90 * Everything in PerHandlerParser *could* be folded into GeneralParser (below)
     91 * if desired.  We don't fold in this manner because all such functions would
     92 * be instantiated once per Unit -- but if exactly equivalent code would be
     93 * generated (because PerHandlerParser functions have no awareness of Unit),
     94 * it's risky to *depend* upon the compiler coalescing the instantiations into
     95 * one in the final binary.  PerHandlerParser guarantees no duplication.
     96 *
     97 * == Parser<ParseHandler, Unit> final → GeneralParser<ParseHandler, Unit> ==
     98 *
     99 * The final (pun intended) axis of complexity lies in Parser.
    100 *
    101 * Some functionality depends on character type, yet also is defined in
    102 * significantly different form in full and syntax parsing.  For example,
    103 * attempting to parse the source text of a module will do so in full parsing
    104 * but immediately fail in syntax parsing -- so the former is a mess'o'code
    105 * while the latter is effectively |return null();|.  Such functionality is
    106 * defined in Parser<SyntaxParseHandler or FullParseHandler, Unit> as
    107 * appropriate.
    108 *
    109 * There's a crucial distinction between GeneralParser and Parser, that
    110 * explains why both must exist (despite taking exactly the same template
    111 * parameters, and despite GeneralParser and Parser existing in a one-to-one
    112 * relationship).  GeneralParser is one unspecialized template class:
    113 *
    114 *   template<class ParseHandler, typename Unit>
    115 *   class GeneralParser : ...
    116 *   {
    117 *     ...parsing functions...
    118 *   };
    119 *
    120 * but Parser is one undefined template class with two separate
    121 * specializations:
    122 *
    123 *   // Declare, but do not define.
    124 *   template<class ParseHandler, typename Unit> class Parser;
    125 *
    126 *   // Define a syntax-parsing specialization.
    127 *   template<typename Unit>
    128 *   class Parser<SyntaxParseHandler, Unit> final
    129 *     : public GeneralParser<SyntaxParseHandler, Unit>
    130 *   {
    131 *     ...parsing functions...
    132 *   };
    133 *
    134 *   // Define a full-parsing specialization.
    135 *   template<typename Unit>
    136 *   class Parser<SyntaxParseHandler, Unit> final
    137 *     : public GeneralParser<SyntaxParseHandler, Unit>
    138 *   {
    139 *     ...parsing functions...
    140 *   };
    141 *
    142 * This odd distinction is necessary because C++ unfortunately doesn't allow
    143 * partial function specialization:
    144 *
    145 *   // BAD: You can only specialize a template function if you specify *every*
    146 *   //      template parameter, i.e. ParseHandler *and* Unit.
    147 *   template<typename Unit>
    148 *   void
    149 *   GeneralParser<SyntaxParseHandler, Unit>::foo() {}
    150 *
    151 * But if you specialize Parser *as a class*, then this is allowed:
    152 *
    153 *   template<typename Unit>
    154 *   void
    155 *   Parser<SyntaxParseHandler, Unit>::foo() {}
    156 *
    157 *   template<typename Unit>
    158 *   void
    159 *   Parser<FullParseHandler, Unit>::foo() {}
    160 *
    161 * because the only template parameter on the function is Unit -- and so all
    162 * template parameters *are* varying, not a strict subset of them.
    163 *
    164 * So -- any parsing functionality that is differently defined for different
    165 * ParseHandlers, *but* is defined textually identically for different Unit
    166 * (even if different code ends up generated for them by the compiler), should
    167 * reside in Parser.
    168 */
    169 
    170 #include "mozilla/Maybe.h"
    171 
    172 #include <type_traits>
    173 #include <utility>
    174 
    175 #include "frontend/CompilationStencil.h"  // CompilationState
    176 #include "frontend/ErrorReporter.h"
    177 #include "frontend/FullParseHandler.h"
    178 #include "frontend/FunctionSyntaxKind.h"  // FunctionSyntaxKind
    179 #include "frontend/IteratorKind.h"
    180 #include "frontend/NameAnalysisTypes.h"
    181 #include "frontend/ParseContext.h"
    182 #include "frontend/ParserAtom.h"  // ParserAtomsTable, TaggedParserAtomIndex
    183 #include "frontend/SharedContext.h"
    184 #include "frontend/SyntaxParseHandler.h"
    185 #include "frontend/TokenStream.h"
    186 #include "js/CharacterEncoding.h"     // JS::ConstUTF8CharsZ
    187 #include "js/friend/ErrorMessages.h"  // JSErrNum, JSMSG_*
    188 #include "vm/GeneratorAndAsyncKind.h"  // js::GeneratorKind, js::FunctionAsyncKind
    189 
    190 namespace js {
    191 
    192 class FrontendContext;
    193 struct ErrorMetadata;
    194 
    195 namespace frontend {
    196 
    197 template <class ParseHandler, typename Unit>
    198 class GeneralParser;
    199 
    200 class SourceParseContext : public ParseContext {
    201 public:
    202  template <typename ParseHandler, typename Unit>
    203  SourceParseContext(GeneralParser<ParseHandler, Unit>* prs, SharedContext* sc,
    204                     Directives* newDirectives)
    205      : ParseContext(prs->fc_, prs->pc_, sc, prs->tokenStream,
    206                     prs->compilationState_, newDirectives,
    207                     std::is_same_v<ParseHandler, FullParseHandler>) {}
    208 };
    209 
    210 enum VarContext { HoistVars, DontHoistVars };
    211 enum PropListType { ObjectLiteral, ClassBody, DerivedClassBody };
    212 enum class PropertyType {
    213  Normal,
    214  Shorthand,
    215  CoverInitializedName,
    216  Getter,
    217  Setter,
    218  Method,
    219  GeneratorMethod,
    220  AsyncMethod,
    221  AsyncGeneratorMethod,
    222  Constructor,
    223  DerivedConstructor,
    224  Field,
    225  FieldWithAccessor,
    226 };
    227 
    228 enum AwaitHandling : uint8_t {
    229  AwaitIsName,
    230  AwaitIsKeyword,
    231  AwaitIsModuleKeyword,
    232  AwaitIsDisallowed
    233 };
    234 
    235 template <class ParseHandler, typename Unit>
    236 class AutoAwaitIsKeyword;
    237 
    238 template <class ParseHandler, typename Unit>
    239 class AutoInParametersOfAsyncFunction;
    240 
    241 class MOZ_STACK_CLASS ParserSharedBase {
    242 public:
    243  enum class Kind { Parser };
    244 
    245  ParserSharedBase(FrontendContext* fc, CompilationState& compilationState,
    246                   Kind kind);
    247  ~ParserSharedBase();
    248 
    249 public:
    250  FrontendContext* fc_;
    251 
    252  LifoAlloc& alloc_;
    253 
    254  CompilationState& compilationState_;
    255 
    256  // innermost parse context (stack-allocated)
    257  ParseContext* pc_;
    258 
    259  // For tracking used names in this parsing session.
    260  UsedNameTracker& usedNames_;
    261 
    262 public:
    263  CompilationState& getCompilationState() { return compilationState_; }
    264 
    265  ParserAtomsTable& parserAtoms() { return compilationState_.parserAtoms; }
    266  const ParserAtomsTable& parserAtoms() const {
    267    return compilationState_.parserAtoms;
    268  }
    269 
    270  BigIntStencilVector& bigInts() { return compilationState_.bigIntData; }
    271  const BigIntStencilVector& bigInts() const {
    272    return compilationState_.bigIntData;
    273  }
    274 
    275  LifoAlloc& stencilAlloc() { return compilationState_.alloc; }
    276 
    277  const UsedNameTracker& usedNames() { return usedNames_; }
    278 
    279 #if defined(DEBUG) || defined(JS_JITSPEW)
    280  void dumpAtom(TaggedParserAtomIndex index) const;
    281 #endif
    282 };
    283 
    284 class MOZ_STACK_CLASS ParserBase : public ParserSharedBase,
    285                                   public ErrorReportMixin {
    286  using Base = ErrorReportMixin;
    287 
    288 public:
    289  TokenStreamAnyChars anyChars;
    290 
    291  ScriptSource* ss;
    292 
    293 protected:
    294 #if DEBUG
    295  /* Our fallible 'checkOptions' member function has been called. */
    296  bool checkOptionsCalled_ : 1;
    297 #endif
    298 
    299  /* Unexpected end of input, i.e. Eof not at top-level. */
    300  bool isUnexpectedEOF_ : 1;
    301 
    302  /* AwaitHandling */ uint8_t awaitHandling_ : 2;
    303 
    304  bool inParametersOfAsyncFunction_ : 1;
    305 
    306 public:
    307  JSAtom* liftParserAtomToJSAtom(TaggedParserAtomIndex index);
    308 
    309  bool awaitIsKeyword() const {
    310    return awaitHandling_ == AwaitIsKeyword ||
    311           awaitHandling_ == AwaitIsModuleKeyword;
    312  }
    313  bool awaitIsDisallowed() const { return awaitHandling_ == AwaitIsDisallowed; }
    314 
    315  bool inParametersOfAsyncFunction() const {
    316    return inParametersOfAsyncFunction_;
    317  }
    318 
    319  ParseGoal parseGoal() const {
    320    return pc_->sc()->hasModuleGoal() ? ParseGoal::Module : ParseGoal::Script;
    321  }
    322 
    323  template <class, typename>
    324  friend class AutoAwaitIsKeyword;
    325  template <class, typename>
    326  friend class AutoInParametersOfAsyncFunction;
    327 
    328  ParserBase(FrontendContext* fc, const JS::ReadOnlyCompileOptions& options,
    329             CompilationState& compilationState);
    330  ~ParserBase();
    331 
    332  bool checkOptions();
    333 
    334  JS::ConstUTF8CharsZ getFilename() const { return anyChars.getFilename(); }
    335  TokenPos pos() const { return anyChars.currentToken().pos; }
    336 
    337  // Determine whether |yield| is a valid name in the current context.
    338  bool yieldExpressionsSupported() const { return pc_->isGenerator(); }
    339 
    340  bool setLocalStrictMode(bool strict) {
    341    MOZ_ASSERT(anyChars.debugHasNoLookahead());
    342    return pc_->sc()->setLocalStrictMode(strict);
    343  }
    344 
    345 public:
    346  // Implement ErrorReportMixin.
    347 
    348  FrontendContext* getContext() const override { return fc_; }
    349 
    350  bool strictMode() const override { return pc_->sc()->strict(); }
    351 
    352  const JS::ReadOnlyCompileOptions& options() const override {
    353    return anyChars.options();
    354  }
    355 
    356  using Base::error;
    357  using Base::errorAt;
    358  using Base::errorNoOffset;
    359  using Base::errorWithNotes;
    360  using Base::errorWithNotesAt;
    361  using Base::errorWithNotesNoOffset;
    362  using Base::strictModeError;
    363  using Base::strictModeErrorAt;
    364  using Base::strictModeErrorNoOffset;
    365  using Base::strictModeErrorWithNotes;
    366  using Base::strictModeErrorWithNotesAt;
    367  using Base::strictModeErrorWithNotesNoOffset;
    368  using Base::warning;
    369  using Base::warningAt;
    370  using Base::warningNoOffset;
    371 
    372 public:
    373  bool isUnexpectedEOF() const { return isUnexpectedEOF_; }
    374 
    375  bool isValidStrictBinding(TaggedParserAtomIndex name);
    376 
    377  bool hasValidSimpleStrictParameterNames();
    378 
    379  // A Parser::Mark is the extension of the LifoAlloc::Mark to the entire
    380  // Parser's state. Note: clients must still take care that any ParseContext
    381  // that points into released ParseNodes is destroyed.
    382  class Mark {
    383    friend class ParserBase;
    384    LifoAlloc::Mark mark;
    385    CompilationState::CompilationStatePosition pos;
    386  };
    387  Mark mark() const {
    388    Mark m;
    389    m.mark = alloc_.mark();
    390    m.pos = compilationState_.getPosition();
    391    return m;
    392  }
    393  void release(Mark m) {
    394    alloc_.release(m.mark);
    395    compilationState_.rewind(m.pos);
    396  }
    397 
    398 public:
    399  mozilla::Maybe<GlobalScope::ParserData*> newGlobalScopeData(
    400      ParseContext::Scope& scope);
    401  mozilla::Maybe<ModuleScope::ParserData*> newModuleScopeData(
    402      ParseContext::Scope& scope);
    403  mozilla::Maybe<EvalScope::ParserData*> newEvalScopeData(
    404      ParseContext::Scope& scope);
    405  mozilla::Maybe<FunctionScope::ParserData*> newFunctionScopeData(
    406      ParseContext::Scope& scope, bool hasParameterExprs);
    407  mozilla::Maybe<VarScope::ParserData*> newVarScopeData(
    408      ParseContext::Scope& scope);
    409  mozilla::Maybe<LexicalScope::ParserData*> newLexicalScopeData(
    410      ParseContext::Scope& scope);
    411  mozilla::Maybe<ClassBodyScope::ParserData*> newClassBodyScopeData(
    412      ParseContext::Scope& scope);
    413 
    414 protected:
    415  enum InvokedPrediction { PredictUninvoked = false, PredictInvoked = true };
    416  enum ForInitLocation { InForInit, NotInForInit };
    417 
    418  // While on a |let| Name token, examine |next| (which must already be
    419  // gotten).  Indicate whether |next|, the next token already gotten with
    420  // modifier TokenStream::SlashIsDiv, continues a LexicalDeclaration.
    421  bool nextTokenContinuesLetDeclaration(TokenKind next);
    422 
    423  bool noteUsedNameInternal(TaggedParserAtomIndex name,
    424                            NameVisibility visibility,
    425                            mozilla::Maybe<TokenPos> tokenPosition);
    426 
    427  bool checkAndMarkSuperScope();
    428 
    429  bool leaveInnerFunction(ParseContext* outerpc);
    430 
    431  TaggedParserAtomIndex prefixAccessorName(PropertyType propType,
    432                                           TaggedParserAtomIndex propAtom);
    433 
    434  [[nodiscard]] bool setSourceMapInfo();
    435 
    436  void setFunctionEndFromCurrentToken(FunctionBox* funbox) const;
    437 };
    438 
    439 template <class ParseHandler>
    440 class MOZ_STACK_CLASS PerHandlerParser : public ParserBase {
    441  using Base = ParserBase;
    442 
    443 private:
    444  using Node = typename ParseHandler::Node;
    445  using NodeResult = typename ParseHandler::NodeResult;
    446 
    447 #define DECLARE_TYPE(typeName)                                  \
    448  using typeName##Type = typename ParseHandler::typeName##Type; \
    449  using typeName##Result = typename ParseHandler::typeName##Result;
    450  FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
    451 #undef DECLARE_TYPE
    452 
    453 protected:
    454  /* State specific to the kind of parse being performed. */
    455  ParseHandler handler_;
    456 
    457  // When ParseHandler is FullParseHandler:
    458  //
    459  //   If non-null, this field holds the syntax parser used to attempt lazy
    460  //   parsing of inner functions. If null, then lazy parsing is disabled.
    461  //
    462  // When ParseHandler is SyntaxParseHandler:
    463  //
    464  //   If non-null, this field must be a sentinel value signaling that the
    465  //   syntax parse was aborted. If null, then lazy parsing was aborted due
    466  //   to encountering unsupported language constructs.
    467  //
    468  // |internalSyntaxParser_| is really a |Parser<SyntaxParseHandler, Unit>*|
    469  // where |Unit| varies per |Parser<ParseHandler, Unit>|.  But this
    470  // template class doesn't know |Unit|, so we store a |void*| here and make
    471  // |GeneralParser<ParseHandler, Unit>::getSyntaxParser| impose the real type.
    472  void* internalSyntaxParser_;
    473 
    474 private:
    475  // NOTE: The argument ordering here is deliberately different from the
    476  //       public constructor so that typos calling the public constructor
    477  //       are less likely to select this overload.
    478  PerHandlerParser(FrontendContext* fc,
    479                   const JS::ReadOnlyCompileOptions& options,
    480                   CompilationState& compilationState,
    481                   void* internalSyntaxParser);
    482 
    483 protected:
    484  template <typename Unit>
    485  PerHandlerParser(FrontendContext* fc,
    486                   const JS::ReadOnlyCompileOptions& options,
    487                   CompilationState& compilationState,
    488                   GeneralParser<SyntaxParseHandler, Unit>* syntaxParser)
    489      : PerHandlerParser(fc, options, compilationState,
    490                         static_cast<void*>(syntaxParser)) {}
    491 
    492  static typename ParseHandler::NullNode null() { return ParseHandler::null(); }
    493 
    494  // The return value for the error case in the functions that returns
    495  // Result type.
    496  static constexpr typename ParseHandler::NodeErrorResult errorResult() {
    497    return ParseHandler::errorResult();
    498  }
    499 
    500  NameNodeResult stringLiteral();
    501 
    502  const char* nameIsArgumentsOrEval(Node node);
    503 
    504  bool noteDestructuredPositionalFormalParameter(FunctionNodeType funNode,
    505                                                 Node destruct);
    506 
    507  bool noteUsedName(
    508      TaggedParserAtomIndex name,
    509      NameVisibility visibility = NameVisibility::Public,
    510      mozilla::Maybe<TokenPos> tokenPosition = mozilla::Nothing()) {
    511    // If the we are delazifying, the BaseScript already has all the closed-over
    512    // info for bindings and there's no need to track used names.
    513    if (handler_.reuseClosedOverBindings()) {
    514      return true;
    515    }
    516 
    517    return ParserBase::noteUsedNameInternal(name, visibility, tokenPosition);
    518  }
    519 
    520  // Required on Scope exit.
    521  bool propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope);
    522 
    523  bool checkForUndefinedPrivateFields(EvalSharedContext* evalSc = nullptr);
    524 
    525  bool finishFunctionScopes(bool isStandaloneFunction);
    526  LexicalScopeNodeResult finishLexicalScope(
    527      ParseContext::Scope& scope, Node body,
    528      ScopeKind kind = ScopeKind::Lexical);
    529  ClassBodyScopeNodeResult finishClassBodyScope(ParseContext::Scope& scope,
    530                                                ListNodeType body);
    531  bool finishFunction(bool isStandaloneFunction = false);
    532 
    533  inline NameNodeResult newName(TaggedParserAtomIndex name);
    534  inline NameNodeResult newName(TaggedParserAtomIndex name, TokenPos pos);
    535 
    536  inline NameNodeResult newPrivateName(TaggedParserAtomIndex name);
    537 
    538  NameNodeResult newInternalDotName(TaggedParserAtomIndex name);
    539  NameNodeResult newThisName();
    540  NameNodeResult newNewTargetName();
    541  NameNodeResult newDotGeneratorName();
    542 
    543  NameNodeResult identifierReference(TaggedParserAtomIndex name);
    544  NameNodeResult privateNameReference(TaggedParserAtomIndex name);
    545 
    546  NodeResult noSubstitutionTaggedTemplate();
    547 
    548  inline bool processExport(Node node);
    549  inline bool processExportFrom(BinaryNodeType node);
    550  inline bool processImport(BinaryNodeType node);
    551 
    552  // If ParseHandler is SyntaxParseHandler:
    553  //   Do nothing.
    554  // If ParseHandler is FullParseHandler:
    555  //   Disable syntax parsing of all future inner functions during this
    556  //   full-parse.
    557  inline void disableSyntaxParser();
    558 
    559  // If ParseHandler is SyntaxParseHandler:
    560  //   Flag the current syntax parse as aborted due to unsupported language
    561  //   constructs and return false.  Aborting the current syntax parse does
    562  //   not disable attempts to syntax-parse future inner functions.
    563  // If ParseHandler is FullParseHandler:
    564  //    Disable syntax parsing of all future inner functions and return true.
    565  inline bool abortIfSyntaxParser();
    566 
    567  // If ParseHandler is SyntaxParseHandler:
    568  //   Return whether the last syntax parse was aborted due to unsupported
    569  //   language constructs.
    570  // If ParseHandler is FullParseHandler:
    571  //   Return false.
    572  inline bool hadAbortedSyntaxParse();
    573 
    574  // If ParseHandler is SyntaxParseHandler:
    575  //   Clear whether the last syntax parse was aborted.
    576  // If ParseHandler is FullParseHandler:
    577  //   Do nothing.
    578  inline void clearAbortedSyntaxParse();
    579 
    580 public:
    581  FunctionBox* newFunctionBox(FunctionNodeType funNode,
    582                              TaggedParserAtomIndex explicitName,
    583                              FunctionFlags flags, uint32_t toStringStart,
    584                              Directives directives,
    585                              GeneratorKind generatorKind,
    586                              FunctionAsyncKind asyncKind);
    587 
    588  FunctionBox* newFunctionBox(FunctionNodeType funNode,
    589                              const ScriptStencil& cachedScriptData,
    590                              const ScriptStencilExtra& cachedScriptExtra);
    591 
    592 public:
    593  // ErrorReportMixin.
    594 
    595  using Base::error;
    596  using Base::errorAt;
    597  using Base::errorNoOffset;
    598  using Base::errorWithNotes;
    599  using Base::errorWithNotesAt;
    600  using Base::errorWithNotesNoOffset;
    601  using Base::strictModeError;
    602  using Base::strictModeErrorAt;
    603  using Base::strictModeErrorNoOffset;
    604  using Base::strictModeErrorWithNotes;
    605  using Base::strictModeErrorWithNotesAt;
    606  using Base::strictModeErrorWithNotesNoOffset;
    607  using Base::warning;
    608  using Base::warningAt;
    609  using Base::warningNoOffset;
    610 };
    611 
    612 #define ABORTED_SYNTAX_PARSE_SENTINEL reinterpret_cast<void*>(0x1)
    613 
    614 template <>
    615 inline void PerHandlerParser<SyntaxParseHandler>::disableSyntaxParser() {}
    616 
    617 template <>
    618 inline bool PerHandlerParser<SyntaxParseHandler>::abortIfSyntaxParser() {
    619  internalSyntaxParser_ = ABORTED_SYNTAX_PARSE_SENTINEL;
    620  return false;
    621 }
    622 
    623 template <>
    624 inline bool PerHandlerParser<SyntaxParseHandler>::hadAbortedSyntaxParse() {
    625  return internalSyntaxParser_ == ABORTED_SYNTAX_PARSE_SENTINEL;
    626 }
    627 
    628 template <>
    629 inline void PerHandlerParser<SyntaxParseHandler>::clearAbortedSyntaxParse() {
    630  internalSyntaxParser_ = nullptr;
    631 }
    632 
    633 #undef ABORTED_SYNTAX_PARSE_SENTINEL
    634 
    635 // Disable syntax parsing of all future inner functions during this
    636 // full-parse.
    637 template <>
    638 inline void PerHandlerParser<FullParseHandler>::disableSyntaxParser() {
    639  internalSyntaxParser_ = nullptr;
    640 }
    641 
    642 template <>
    643 inline bool PerHandlerParser<FullParseHandler>::abortIfSyntaxParser() {
    644  disableSyntaxParser();
    645  return true;
    646 }
    647 
    648 template <>
    649 inline bool PerHandlerParser<FullParseHandler>::hadAbortedSyntaxParse() {
    650  return false;
    651 }
    652 
    653 template <>
    654 inline void PerHandlerParser<FullParseHandler>::clearAbortedSyntaxParse() {}
    655 
    656 template <class Parser>
    657 class ParserAnyCharsAccess {
    658 public:
    659  using TokenStreamSpecific = typename Parser::TokenStream;
    660  using GeneralTokenStreamChars =
    661      typename TokenStreamSpecific::GeneralCharsBase;
    662 
    663  static inline TokenStreamAnyChars& anyChars(GeneralTokenStreamChars* ts);
    664  static inline const TokenStreamAnyChars& anyChars(
    665      const GeneralTokenStreamChars* ts);
    666 };
    667 
    668 // Specify a value for an ES6 grammar parametrization.  We have no enum for
    669 // [Return] because its behavior is almost exactly equivalent to checking
    670 // whether we're in a function box -- easier and simpler than passing an extra
    671 // parameter everywhere.
    672 enum YieldHandling { YieldIsName, YieldIsKeyword };
    673 enum InHandling { InAllowed, InProhibited };
    674 enum DefaultHandling { NameRequired, AllowDefaultName };
    675 enum TripledotHandling { TripledotAllowed, TripledotProhibited };
    676 
    677 // For Ergonomic brand checks.
    678 enum PrivateNameHandling { PrivateNameProhibited, PrivateNameAllowed };
    679 
    680 template <class ParseHandler, typename Unit>
    681 class Parser;
    682 
    683 template <class ParseHandler, typename Unit>
    684 class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
    685 public:
    686  using TokenStream =
    687      TokenStreamSpecific<Unit, ParserAnyCharsAccess<GeneralParser>>;
    688 
    689 private:
    690  using Base = PerHandlerParser<ParseHandler>;
    691  using FinalParser = Parser<ParseHandler, Unit>;
    692  using Node = typename ParseHandler::Node;
    693  using NodeResult = typename ParseHandler::NodeResult;
    694 
    695 #define DECLARE_TYPE(typeName)                                  \
    696  using typeName##Type = typename ParseHandler::typeName##Type; \
    697  using typeName##Result = typename ParseHandler::typeName##Result;
    698  FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
    699 #undef DECLARE_TYPE
    700 
    701  using typename Base::InvokedPrediction;
    702  using SyntaxParser = Parser<SyntaxParseHandler, Unit>;
    703 
    704 protected:
    705  using Modifier = TokenStreamShared::Modifier;
    706  using Position = typename TokenStream::Position;
    707 
    708  using Base::PredictInvoked;
    709  using Base::PredictUninvoked;
    710 
    711  using Base::alloc_;
    712  using Base::awaitIsDisallowed;
    713  using Base::awaitIsKeyword;
    714  using Base::inParametersOfAsyncFunction;
    715  using Base::parseGoal;
    716 #if DEBUG
    717  using Base::checkOptionsCalled_;
    718 #endif
    719  using Base::checkForUndefinedPrivateFields;
    720  using Base::errorResult;
    721  using Base::finishClassBodyScope;
    722  using Base::finishFunctionScopes;
    723  using Base::finishLexicalScope;
    724  using Base::getFilename;
    725  using Base::hasValidSimpleStrictParameterNames;
    726  using Base::isUnexpectedEOF_;
    727  using Base::nameIsArgumentsOrEval;
    728  using Base::newDotGeneratorName;
    729  using Base::newFunctionBox;
    730  using Base::newName;
    731  using Base::null;
    732  using Base::options;
    733  using Base::pos;
    734  using Base::propagateFreeNamesAndMarkClosedOverBindings;
    735  using Base::setLocalStrictMode;
    736  using Base::stringLiteral;
    737  using Base::yieldExpressionsSupported;
    738 
    739  using Base::abortIfSyntaxParser;
    740  using Base::clearAbortedSyntaxParse;
    741  using Base::disableSyntaxParser;
    742  using Base::hadAbortedSyntaxParse;
    743 
    744 public:
    745  // Implement ErrorReportMixin.
    746 
    747  [[nodiscard]] bool computeErrorMetadata(
    748      ErrorMetadata* err,
    749      const ErrorReportMixin::ErrorOffset& offset) const override;
    750 
    751  using Base::error;
    752  using Base::errorAt;
    753  using Base::errorNoOffset;
    754  using Base::errorWithNotes;
    755  using Base::errorWithNotesAt;
    756  using Base::errorWithNotesNoOffset;
    757  using Base::strictModeError;
    758  using Base::strictModeErrorAt;
    759  using Base::strictModeErrorNoOffset;
    760  using Base::strictModeErrorWithNotes;
    761  using Base::strictModeErrorWithNotesAt;
    762  using Base::strictModeErrorWithNotesNoOffset;
    763  using Base::warning;
    764  using Base::warningAt;
    765  using Base::warningNoOffset;
    766 
    767 public:
    768  using Base::anyChars;
    769  using Base::fc_;
    770  using Base::handler_;
    771  using Base::noteUsedName;
    772  using Base::pc_;
    773  using Base::usedNames_;
    774 
    775 private:
    776  using Base::checkAndMarkSuperScope;
    777  using Base::finishFunction;
    778  using Base::identifierReference;
    779  using Base::leaveInnerFunction;
    780  using Base::newInternalDotName;
    781  using Base::newNewTargetName;
    782  using Base::newThisName;
    783  using Base::nextTokenContinuesLetDeclaration;
    784  using Base::noSubstitutionTaggedTemplate;
    785  using Base::noteDestructuredPositionalFormalParameter;
    786  using Base::prefixAccessorName;
    787  using Base::privateNameReference;
    788  using Base::processExport;
    789  using Base::processExportFrom;
    790  using Base::processImport;
    791  using Base::setFunctionEndFromCurrentToken;
    792 
    793 private:
    794  inline FinalParser* asFinalParser();
    795  inline const FinalParser* asFinalParser() const;
    796 
    797  /*
    798   * A class for temporarily stashing errors while parsing continues.
    799   *
    800   * The ability to stash an error is useful for handling situations where we
    801   * aren't able to verify that an error has occurred until later in the parse.
    802   * For instance | ({x=1}) | is always parsed as an object literal with
    803   * a SyntaxError, however, in the case where it is followed by '=>' we rewind
    804   * and reparse it as a valid arrow function. Here a PossibleError would be
    805   * set to 'pending' when the initial SyntaxError was encountered then
    806   * 'resolved' just before rewinding the parser.
    807   *
    808   * There are currently two kinds of PossibleErrors: Expression and
    809   * Destructuring errors. Expression errors are used to mark a possible
    810   * syntax error when a grammar production is used in an expression context.
    811   * For example in |{x = 1}|, we mark the CoverInitializedName |x = 1| as a
    812   * possible expression error, because CoverInitializedName productions
    813   * are disallowed when an actual ObjectLiteral is expected.
    814   * Destructuring errors are used to record possible syntax errors in
    815   * destructuring contexts. For example in |[...rest, ] = []|, we initially
    816   * mark the trailing comma after the spread expression as a possible
    817   * destructuring error, because the ArrayAssignmentPattern grammar
    818   * production doesn't allow a trailing comma after the rest element.
    819   *
    820   * When using PossibleError one should set a pending error at the location
    821   * where an error occurs. From that point, the error may be resolved
    822   * (invalidated) or left until the PossibleError is checked.
    823   *
    824   * Ex:
    825   *   PossibleError possibleError(*this);
    826   *   possibleError.setPendingExpressionErrorAt(pos, JSMSG_BAD_PROP_ID);
    827   *   // A JSMSG_BAD_PROP_ID ParseError is reported, returns false.
    828   *   if (!possibleError.checkForExpressionError()) {
    829   *       return false; // we reach this point with a pending exception
    830   *   }
    831   *
    832   *   PossibleError possibleError(*this);
    833   *   possibleError.setPendingExpressionErrorAt(pos, JSMSG_BAD_PROP_ID);
    834   *   // Returns true, no error is reported.
    835   *   if (!possibleError.checkForDestructuringError()) {
    836   *       return false; // not reached, no pending exception
    837   *   }
    838   *
    839   *   PossibleError possibleError(*this);
    840   *   // Returns true, no error is reported.
    841   *   if (!possibleError.checkForExpressionError()) {
    842   *       return false; // not reached, no pending exception
    843   *   }
    844   */
    845  class MOZ_STACK_CLASS PossibleError {
    846   private:
    847    enum class ErrorKind { Expression, Destructuring, DestructuringWarning };
    848 
    849    enum class ErrorState { None, Pending };
    850 
    851    struct Error {
    852      ErrorState state_ = ErrorState::None;
    853 
    854      // Error reporting fields.
    855      uint32_t offset_;
    856      unsigned errorNumber_;
    857    };
    858 
    859    GeneralParser<ParseHandler, Unit>& parser_;
    860    Error exprError_;
    861    Error destructuringError_;
    862    Error destructuringWarning_;
    863 
    864    // Returns the error report.
    865    Error& error(ErrorKind kind);
    866 
    867    // Return true if an error is pending without reporting.
    868    bool hasError(ErrorKind kind);
    869 
    870    // Resolve any pending error.
    871    void setResolved(ErrorKind kind);
    872 
    873    // Set a pending error. Only a single error may be set per instance and
    874    // error kind.
    875    void setPending(ErrorKind kind, const TokenPos& pos, unsigned errorNumber);
    876 
    877    // If there is a pending error, report it and return false, otherwise
    878    // return true.
    879    [[nodiscard]] bool checkForError(ErrorKind kind);
    880 
    881    // Transfer an existing error to another instance.
    882    void transferErrorTo(ErrorKind kind, PossibleError* other);
    883 
    884   public:
    885    explicit PossibleError(GeneralParser<ParseHandler, Unit>& parser);
    886 
    887    // Return true if a pending destructuring error is present.
    888    bool hasPendingDestructuringError();
    889 
    890    // Set a pending destructuring error. Only a single error may be set
    891    // per instance, i.e. subsequent calls to this method are ignored and
    892    // won't overwrite the existing pending error.
    893    void setPendingDestructuringErrorAt(const TokenPos& pos,
    894                                        unsigned errorNumber);
    895 
    896    // Set a pending destructuring warning. Only a single warning may be
    897    // set per instance, i.e. subsequent calls to this method are ignored
    898    // and won't overwrite the existing pending warning.
    899    void setPendingDestructuringWarningAt(const TokenPos& pos,
    900                                          unsigned errorNumber);
    901 
    902    // Set a pending expression error. Only a single error may be set per
    903    // instance, i.e. subsequent calls to this method are ignored and won't
    904    // overwrite the existing pending error.
    905    void setPendingExpressionErrorAt(const TokenPos& pos, unsigned errorNumber);
    906 
    907    // If there is a pending destructuring error or warning, report it and
    908    // return false, otherwise return true. Clears any pending expression
    909    // error.
    910    [[nodiscard]] bool checkForDestructuringErrorOrWarning();
    911 
    912    // If there is a pending expression error, report it and return false,
    913    // otherwise return true. Clears any pending destructuring error or
    914    // warning.
    915    [[nodiscard]] bool checkForExpressionError();
    916 
    917    // Pass pending errors between possible error instances. This is useful
    918    // for extending the lifetime of a pending error beyond the scope of
    919    // the PossibleError where it was initially set (keeping in mind that
    920    // PossibleError is a MOZ_STACK_CLASS).
    921    void transferErrorsTo(PossibleError* other);
    922  };
    923 
    924 protected:
    925  SyntaxParser* getSyntaxParser() const {
    926    return reinterpret_cast<SyntaxParser*>(Base::internalSyntaxParser_);
    927  }
    928 
    929 public:
    930  TokenStream tokenStream;
    931 
    932 public:
    933  GeneralParser(FrontendContext* fc, const JS::ReadOnlyCompileOptions& options,
    934                const Unit* units, size_t length,
    935                CompilationState& compilationState, SyntaxParser* syntaxParser);
    936 
    937  inline void setAwaitHandling(AwaitHandling awaitHandling);
    938  inline void setInParametersOfAsyncFunction(bool inParameters);
    939 
    940  /*
    941   * Parse a top-level JS script.
    942   */
    943  ListNodeResult parse();
    944 
    945 private:
    946  /*
    947   * Gets the next token and checks if it matches to the given `condition`.
    948   * If it matches, returns true.
    949   * If it doesn't match, calls `errorReport` to report the error, and
    950   * returns false.
    951   * If other error happens, it returns false but `errorReport` may not be
    952   * called and other error will be thrown in that case.
    953   *
    954   * In any case, the already gotten token is not ungotten.
    955   *
    956   * The signature of `condition` is [...](TokenKind actual) -> bool, and
    957   * the signature of `errorReport` is [...](TokenKind actual).
    958   */
    959  template <typename ConditionT, typename ErrorReportT>
    960  [[nodiscard]] bool mustMatchTokenInternal(ConditionT condition,
    961                                            ErrorReportT errorReport);
    962 
    963 public:
    964  /*
    965   * The following mustMatchToken variants follow the behavior and parameter
    966   * types of mustMatchTokenInternal above.
    967   *
    968   * If modifier is omitted, `SlashIsDiv` is used.
    969   * If TokenKind is passed instead of `condition`, it checks if the next
    970   * token is the passed token.
    971   * If error number is passed instead of `errorReport`, it reports an
    972   * error with the passed errorNumber.
    973   */
    974  [[nodiscard]] bool mustMatchToken(TokenKind expected, JSErrNum errorNumber) {
    975    return mustMatchTokenInternal(
    976        [expected](TokenKind actual) { return actual == expected; },
    977        [this, errorNumber](TokenKind) { this->error(errorNumber); });
    978  }
    979 
    980  template <typename ConditionT>
    981  [[nodiscard]] bool mustMatchToken(ConditionT condition,
    982                                    JSErrNum errorNumber) {
    983    return mustMatchTokenInternal(condition, [this, errorNumber](TokenKind) {
    984      this->error(errorNumber);
    985    });
    986  }
    987 
    988  template <typename ErrorReportT>
    989  [[nodiscard]] bool mustMatchToken(TokenKind expected,
    990                                    ErrorReportT errorReport) {
    991    return mustMatchTokenInternal(
    992        [expected](TokenKind actual) { return actual == expected; },
    993        errorReport);
    994  }
    995 
    996 private:
    997  NameNodeResult noSubstitutionUntaggedTemplate();
    998  ListNodeResult templateLiteral(YieldHandling yieldHandling);
    999  bool taggedTemplate(YieldHandling yieldHandling, ListNodeType tagArgsList,
   1000                      TokenKind tt);
   1001  bool appendToCallSiteObj(CallSiteNodeType callSiteObj);
   1002  bool addExprAndGetNextTemplStrToken(YieldHandling yieldHandling,
   1003                                      ListNodeType nodeList, TokenKind* ttp);
   1004 
   1005  inline bool trySyntaxParseInnerFunction(
   1006      FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
   1007      FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
   1008      YieldHandling yieldHandling, FunctionSyntaxKind kind,
   1009      GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
   1010      Directives inheritedDirectives, Directives* newDirectives);
   1011 
   1012  inline bool skipLazyInnerFunction(FunctionNodeType funNode,
   1013                                    uint32_t toStringStart, bool tryAnnexB);
   1014 
   1015  void setFunctionStartAtPosition(FunctionBox* funbox, TokenPos pos) const;
   1016  void setFunctionStartAtCurrentToken(FunctionBox* funbox) const;
   1017 
   1018 public:
   1019  /* Public entry points for parsing. */
   1020  NodeResult statementListItem(YieldHandling yieldHandling,
   1021                               bool canHaveDirectives = false);
   1022 
   1023  // Parse an inner function given an enclosing ParseContext and a
   1024  // FunctionBox for the inner function.
   1025  [[nodiscard]] FunctionNodeResult innerFunctionForFunctionBox(
   1026      FunctionNodeType funNode, ParseContext* outerpc, FunctionBox* funbox,
   1027      InHandling inHandling, YieldHandling yieldHandling,
   1028      FunctionSyntaxKind kind, Directives* newDirectives);
   1029 
   1030  // Parse a function's formal parameters and its body assuming its function
   1031  // ParseContext is already on the stack.
   1032  bool functionFormalParametersAndBody(
   1033      InHandling inHandling, YieldHandling yieldHandling,
   1034      FunctionNodeType* funNode, FunctionSyntaxKind kind,
   1035      const mozilla::Maybe<uint32_t>& parameterListEnd = mozilla::Nothing(),
   1036      bool isStandaloneFunction = false);
   1037 
   1038 private:
   1039  /*
   1040   * JS parsers, from lowest to highest precedence.
   1041   *
   1042   * Each parser must be called during the dynamic scope of a ParseContext
   1043   * object, pointed to by this->pc_.
   1044   *
   1045   * Each returns a parse node tree or null on error.
   1046   */
   1047  FunctionNodeResult functionStmt(
   1048      uint32_t toStringStart, YieldHandling yieldHandling,
   1049      DefaultHandling defaultHandling,
   1050      FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction);
   1051  FunctionNodeResult functionExpr(uint32_t toStringStart,
   1052                                  InvokedPrediction invoked,
   1053                                  FunctionAsyncKind asyncKind);
   1054 
   1055  NodeResult statement(YieldHandling yieldHandling);
   1056  bool maybeParseDirective(ListNodeType list, Node pn, bool* cont);
   1057 
   1058  LexicalScopeNodeResult blockStatement(
   1059      YieldHandling yieldHandling,
   1060      unsigned errorNumber = JSMSG_CURLY_IN_COMPOUND);
   1061  BinaryNodeResult doWhileStatement(YieldHandling yieldHandling);
   1062  BinaryNodeResult whileStatement(YieldHandling yieldHandling);
   1063 
   1064  NodeResult forStatement(YieldHandling yieldHandling);
   1065  bool forHeadStart(YieldHandling yieldHandling, IteratorKind iterKind,
   1066                    ParseNodeKind* forHeadKind, Node* forInitialPart,
   1067                    mozilla::Maybe<ParseContext::Scope>& forLetImpliedScope,
   1068                    Node* forInOrOfExpression);
   1069  NodeResult expressionAfterForInOrOf(ParseNodeKind forHeadKind,
   1070                                      YieldHandling yieldHandling);
   1071 
   1072  SwitchStatementResult switchStatement(YieldHandling yieldHandling);
   1073  ContinueStatementResult continueStatement(YieldHandling yieldHandling);
   1074  BreakStatementResult breakStatement(YieldHandling yieldHandling);
   1075  UnaryNodeResult returnStatement(YieldHandling yieldHandling);
   1076  BinaryNodeResult withStatement(YieldHandling yieldHandling);
   1077  UnaryNodeResult throwStatement(YieldHandling yieldHandling);
   1078  TernaryNodeResult tryStatement(YieldHandling yieldHandling);
   1079  LexicalScopeNodeResult catchBlockStatement(
   1080      YieldHandling yieldHandling, ParseContext::Scope& catchParamScope);
   1081  DebuggerStatementResult debuggerStatement();
   1082 
   1083  DeclarationListNodeResult variableStatement(YieldHandling yieldHandling);
   1084 
   1085  LabeledStatementResult labeledStatement(YieldHandling yieldHandling);
   1086  NodeResult labeledItem(YieldHandling yieldHandling);
   1087 
   1088  TernaryNodeResult ifStatement(YieldHandling yieldHandling);
   1089  NodeResult consequentOrAlternative(YieldHandling yieldHandling);
   1090 
   1091  DeclarationListNodeResult lexicalDeclaration(YieldHandling yieldHandling,
   1092                                               DeclarationKind kind);
   1093 
   1094  NameNodeResult moduleExportName();
   1095 
   1096  bool withClause(ListNodeType attributesSet);
   1097 
   1098  BinaryNodeResult importDeclaration();
   1099  NodeResult importDeclarationOrImportExpr(YieldHandling yieldHandling);
   1100  bool namedImports(ListNodeType importSpecSet);
   1101  bool namespaceImport(ListNodeType importSpecSet);
   1102 
   1103  TaggedParserAtomIndex importedBinding() {
   1104    return bindingIdentifier(YieldIsName);
   1105  }
   1106 
   1107  BinaryNodeResult exportFrom(uint32_t begin, Node specList);
   1108  BinaryNodeResult exportBatch(uint32_t begin);
   1109  inline bool checkLocalExportNames(ListNodeType node);
   1110  NodeResult exportClause(uint32_t begin);
   1111  UnaryNodeResult exportFunctionDeclaration(
   1112      uint32_t begin, uint32_t toStringStart,
   1113      FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction);
   1114  UnaryNodeResult exportVariableStatement(uint32_t begin);
   1115  UnaryNodeResult exportClassDeclaration(uint32_t begin);
   1116  UnaryNodeResult exportLexicalDeclaration(uint32_t begin,
   1117                                           DeclarationKind kind);
   1118  BinaryNodeResult exportDefaultFunctionDeclaration(
   1119      uint32_t begin, uint32_t toStringStart,
   1120      FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction);
   1121  BinaryNodeResult exportDefaultClassDeclaration(uint32_t begin);
   1122  BinaryNodeResult exportDefaultAssignExpr(uint32_t begin);
   1123  BinaryNodeResult exportDefault(uint32_t begin);
   1124  NodeResult exportDeclaration();
   1125 
   1126  UnaryNodeResult expressionStatement(
   1127      YieldHandling yieldHandling,
   1128      InvokedPrediction invoked = PredictUninvoked);
   1129 
   1130  // Declaration parsing.  The main entrypoint is Parser::declarationList,
   1131  // with sub-functionality split out into the remaining methods.
   1132 
   1133  // |blockScope| may be non-null only when |kind| corresponds to a lexical
   1134  // declaration (that is, ParseNodeKind::LetDecl or ParseNodeKind::ConstDecl).
   1135  //
   1136  // The for* parameters, for normal declarations, should be null/ignored.
   1137  // They should be non-null only when Parser::forHeadStart parses a
   1138  // declaration at the start of a for-loop head.
   1139  //
   1140  // In this case, on success |*forHeadKind| is ParseNodeKind::ForHead,
   1141  // ParseNodeKind::ForIn, or ParseNodeKind::ForOf, corresponding to the three
   1142  // for-loop kinds.  The precise value indicates what was parsed.
   1143  //
   1144  // If parsing recognized a for(;;) loop, the next token is the ';' within
   1145  // the loop-head that separates the init/test parts.
   1146  //
   1147  // Otherwise, for for-in/of loops, the next token is the ')' ending the
   1148  // loop-head.  Additionally, the expression that the loop iterates over was
   1149  // parsed into |*forInOrOfExpression|.
   1150  DeclarationListNodeResult declarationList(
   1151      YieldHandling yieldHandling, ParseNodeKind kind,
   1152      ParseNodeKind* forHeadKind = nullptr,
   1153      Node* forInOrOfExpression = nullptr);
   1154 
   1155  // The items in a declaration list are either patterns or names, with or
   1156  // without initializers.  These two methods parse a single pattern/name and
   1157  // any associated initializer -- and if parsing an |initialDeclaration|
   1158  // will, if parsing in a for-loop head (as specified by |forHeadKind| being
   1159  // non-null), consume additional tokens up to the closing ')' in a
   1160  // for-in/of loop head, returning the iterated expression in
   1161  // |*forInOrOfExpression|.  (An "initial declaration" is the first
   1162  // declaration in a declaration list: |a| but not |b| in |var a, b|, |{c}|
   1163  // but not |d| in |let {c} = 3, d|.)
   1164  NodeResult declarationPattern(DeclarationKind declKind, TokenKind tt,
   1165                                bool initialDeclaration,
   1166                                YieldHandling yieldHandling,
   1167                                ParseNodeKind* forHeadKind,
   1168                                Node* forInOrOfExpression);
   1169  NodeResult declarationName(DeclarationKind declKind, TokenKind tt,
   1170                             bool initialDeclaration,
   1171                             YieldHandling yieldHandling,
   1172                             ParseNodeKind* forHeadKind,
   1173                             Node* forInOrOfExpression);
   1174 
   1175  // Having parsed a name (not found in a destructuring pattern) declared by
   1176  // a declaration, with the current token being the '=' separating the name
   1177  // from its initializer, parse and bind that initializer -- and possibly
   1178  // consume trailing in/of and subsequent expression, if so directed by
   1179  // |forHeadKind|.
   1180  AssignmentNodeResult initializerInNameDeclaration(NameNodeType binding,
   1181                                                    DeclarationKind declKind,
   1182                                                    bool initialDeclaration,
   1183                                                    YieldHandling yieldHandling,
   1184                                                    ParseNodeKind* forHeadKind,
   1185                                                    Node* forInOrOfExpression);
   1186 
   1187  NodeResult expr(InHandling inHandling, YieldHandling yieldHandling,
   1188                  TripledotHandling tripledotHandling,
   1189                  PossibleError* possibleError = nullptr,
   1190                  InvokedPrediction invoked = PredictUninvoked);
   1191  NodeResult assignExpr(InHandling inHandling, YieldHandling yieldHandling,
   1192                        TripledotHandling tripledotHandling,
   1193                        PossibleError* possibleError = nullptr,
   1194                        InvokedPrediction invoked = PredictUninvoked);
   1195  NodeResult assignExprWithoutYieldOrAwait(YieldHandling yieldHandling);
   1196  UnaryNodeResult yieldExpression(InHandling inHandling);
   1197  NodeResult condExpr(InHandling inHandling, YieldHandling yieldHandling,
   1198                      TripledotHandling tripledotHandling,
   1199                      PossibleError* possibleError, InvokedPrediction invoked);
   1200  NodeResult orExpr(InHandling inHandling, YieldHandling yieldHandling,
   1201                    TripledotHandling tripledotHandling,
   1202                    PossibleError* possibleError, InvokedPrediction invoked);
   1203  NodeResult unaryExpr(YieldHandling yieldHandling,
   1204                       TripledotHandling tripledotHandling,
   1205                       PossibleError* possibleError = nullptr,
   1206                       InvokedPrediction invoked = PredictUninvoked,
   1207                       PrivateNameHandling privateNameHandling =
   1208                           PrivateNameHandling::PrivateNameProhibited);
   1209  NodeResult optionalExpr(YieldHandling yieldHandling,
   1210                          TripledotHandling tripledotHandling, TokenKind tt,
   1211                          PossibleError* possibleError = nullptr,
   1212                          InvokedPrediction invoked = PredictUninvoked);
   1213  NodeResult memberExpr(YieldHandling yieldHandling,
   1214                        TripledotHandling tripledotHandling, TokenKind tt,
   1215                        bool allowCallSyntax, PossibleError* possibleError,
   1216                        InvokedPrediction invoked);
   1217  NodeResult decoratorExpr(YieldHandling yieldHandling, TokenKind tt);
   1218  NodeResult primaryExpr(YieldHandling yieldHandling,
   1219                         TripledotHandling tripledotHandling, TokenKind tt,
   1220                         PossibleError* possibleError,
   1221                         InvokedPrediction invoked);
   1222  NodeResult exprInParens(InHandling inHandling, YieldHandling yieldHandling,
   1223                          TripledotHandling tripledotHandling,
   1224                          PossibleError* possibleError = nullptr);
   1225 
   1226  bool tryNewTarget(NewTargetNodeType* newTarget);
   1227 
   1228  BinaryNodeResult importExpr(YieldHandling yieldHandling,
   1229                              bool allowCallSyntax);
   1230 
   1231  FunctionNodeResult methodDefinition(uint32_t toStringStart,
   1232                                      PropertyType propType,
   1233                                      TaggedParserAtomIndex funName);
   1234 
   1235  /*
   1236   * Additional JS parsers.
   1237   */
   1238  bool functionArguments(YieldHandling yieldHandling, FunctionSyntaxKind kind,
   1239                         FunctionNodeType funNode);
   1240 
   1241  FunctionNodeResult functionDefinition(
   1242      FunctionNodeType funNode, uint32_t toStringStart, InHandling inHandling,
   1243      YieldHandling yieldHandling, TaggedParserAtomIndex name,
   1244      FunctionSyntaxKind kind, GeneratorKind generatorKind,
   1245      FunctionAsyncKind asyncKind, bool tryAnnexB = false);
   1246 
   1247  // Parse a function body.  Pass StatementListBody if the body is a list of
   1248  // statements; pass ExpressionBody if the body is a single expression.
   1249  //
   1250  // Don't include opening LeftCurly token when invoking.
   1251  enum FunctionBodyType { StatementListBody, ExpressionBody };
   1252  LexicalScopeNodeResult functionBody(InHandling inHandling,
   1253                                      YieldHandling yieldHandling,
   1254                                      FunctionSyntaxKind kind,
   1255                                      FunctionBodyType type);
   1256 
   1257  UnaryNodeResult unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind,
   1258                              uint32_t begin);
   1259 
   1260  NodeResult condition(InHandling inHandling, YieldHandling yieldHandling);
   1261 
   1262  ListNodeResult argumentList(YieldHandling yieldHandling, bool* isSpread,
   1263                              PossibleError* possibleError = nullptr);
   1264  NodeResult destructuringDeclaration(DeclarationKind kind,
   1265                                      YieldHandling yieldHandling,
   1266                                      TokenKind tt);
   1267  NodeResult destructuringDeclarationWithoutYieldOrAwait(
   1268      DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt);
   1269 
   1270  inline bool checkExportedName(TaggedParserAtomIndex exportName);
   1271  inline bool checkExportedNamesForArrayBinding(ListNodeType array);
   1272  inline bool checkExportedNamesForObjectBinding(ListNodeType obj);
   1273  inline bool checkExportedNamesForDeclaration(Node node);
   1274  inline bool checkExportedNamesForDeclarationList(
   1275      DeclarationListNodeType node);
   1276  inline bool checkExportedNameForFunction(FunctionNodeType funNode);
   1277  inline bool checkExportedNameForClass(ClassNodeType classNode);
   1278  inline bool checkExportedNameForClause(NameNodeType nameNode);
   1279 
   1280  enum ClassContext { ClassStatement, ClassExpression };
   1281  ClassNodeResult classDefinition(YieldHandling yieldHandling,
   1282                                  ClassContext classContext,
   1283                                  DefaultHandling defaultHandling);
   1284 
   1285  struct ClassInitializedMembers {
   1286 #ifdef ENABLE_DECORATORS
   1287    // Whether a non-static field has decorators or not.
   1288    bool hasInstanceDecorators = false;
   1289 #endif
   1290 
   1291    // The number of instance class fields.
   1292    size_t instanceFields = 0;
   1293 
   1294    // The number of instance class fields with computed property names.
   1295    size_t instanceFieldKeys = 0;
   1296 
   1297    // The number of static class fields.
   1298    size_t staticFields = 0;
   1299 
   1300    // The number of static blocks
   1301    size_t staticBlocks = 0;
   1302 
   1303    // The number of static class fields with computed property names.
   1304    size_t staticFieldKeys = 0;
   1305 
   1306    // The number of instance class private methods.
   1307    size_t privateMethods = 0;
   1308 
   1309    // The number of instance class private accessors.
   1310    size_t privateAccessors = 0;
   1311 
   1312    bool hasPrivateBrand() const {
   1313      return privateMethods > 0 || privateAccessors > 0;
   1314    }
   1315  };
   1316 #ifdef ENABLE_DECORATORS
   1317  ListNodeResult decoratorList(YieldHandling yieldHandling);
   1318 #endif
   1319  [[nodiscard]] bool classMember(
   1320      YieldHandling yieldHandling,
   1321      const ParseContext::ClassStatement& classStmt,
   1322      TaggedParserAtomIndex className, uint32_t classStartOffset,
   1323      HasHeritage hasHeritage, ClassInitializedMembers& classInitializedMembers,
   1324      ListNodeType& classMembers, bool* done);
   1325  [[nodiscard]] bool finishClassConstructor(
   1326      const ParseContext::ClassStatement& classStmt,
   1327      TaggedParserAtomIndex className, HasHeritage hasHeritage,
   1328      uint32_t classStartOffset, uint32_t classEndOffset,
   1329      const ClassInitializedMembers& classInitializedMembers,
   1330      ListNodeType& classMembers);
   1331 
   1332  FunctionNodeResult privateMethodInitializer(
   1333      TokenPos propNamePos, TaggedParserAtomIndex propAtom,
   1334      TaggedParserAtomIndex storedMethodAtom);
   1335  FunctionNodeResult fieldInitializerOpt(
   1336      TokenPos propNamePos, Node name, TaggedParserAtomIndex atom,
   1337      ClassInitializedMembers& classInitializedMembers, bool isStatic,
   1338      HasHeritage hasHeritage);
   1339 
   1340  FunctionNodeResult synthesizePrivateMethodInitializer(
   1341      TaggedParserAtomIndex propAtom, AccessorType accessorType,
   1342      TokenPos propNamePos);
   1343 
   1344 #ifdef ENABLE_DECORATORS
   1345  FunctionNodeResult synthesizeAddInitializerFunction(
   1346      TaggedParserAtomIndex initializers, YieldHandling yieldHandling);
   1347 
   1348  ClassMethodResult synthesizeAccessor(
   1349      Node propName, TokenPos propNamePos, TaggedParserAtomIndex propAtom,
   1350      TaggedParserAtomIndex privateStateNameAtom, bool isStatic,
   1351      FunctionSyntaxKind syntaxKind,
   1352      ClassInitializedMembers& classInitializedMembers);
   1353 
   1354  FunctionNodeResult synthesizeAccessorBody(TaggedParserAtomIndex funNameAtom,
   1355                                            TokenPos propNamePos,
   1356                                            TaggedParserAtomIndex propNameAtom,
   1357                                            FunctionSyntaxKind syntaxKind);
   1358 #endif
   1359 
   1360  FunctionNodeResult staticClassBlock(
   1361      ClassInitializedMembers& classInitializedMembers);
   1362 
   1363  FunctionNodeResult synthesizeConstructor(TaggedParserAtomIndex className,
   1364                                           TokenPos synthesizedBodyPos,
   1365                                           HasHeritage hasHeritage);
   1366 
   1367 protected:
   1368  bool synthesizeConstructorBody(TokenPos synthesizedBodyPos,
   1369                                 HasHeritage hasHeritage,
   1370                                 FunctionNodeType funNode, FunctionBox* funbox);
   1371 
   1372 private:
   1373  bool checkBindingIdentifier(TaggedParserAtomIndex ident, uint32_t offset,
   1374                              YieldHandling yieldHandling,
   1375                              TokenKind hint = TokenKind::Limit);
   1376 
   1377  TaggedParserAtomIndex labelOrIdentifierReference(YieldHandling yieldHandling);
   1378 
   1379  TaggedParserAtomIndex labelIdentifier(YieldHandling yieldHandling) {
   1380    return labelOrIdentifierReference(yieldHandling);
   1381  }
   1382 
   1383  TaggedParserAtomIndex identifierReference(YieldHandling yieldHandling) {
   1384    return labelOrIdentifierReference(yieldHandling);
   1385  }
   1386 
   1387  bool matchLabel(YieldHandling yieldHandling, TaggedParserAtomIndex* labelOut);
   1388 
   1389  // Indicate if the next token (tokenized with SlashIsRegExp) is |in| or |of|.
   1390  // If so, consume it.
   1391  bool matchInOrOf(bool* isForInp, bool* isForOfp);
   1392 
   1393 private:
   1394  bool checkIncDecOperand(Node operand, uint32_t operandOffset);
   1395  bool checkStrictAssignment(Node lhs);
   1396 
   1397  void reportMissingClosing(unsigned errorNumber, unsigned noteNumber,
   1398                            uint32_t openedPos);
   1399 
   1400  void reportRedeclarationHelper(TaggedParserAtomIndex& name,
   1401                                 DeclarationKind& prevKind, TokenPos& pos,
   1402                                 uint32_t& prevPos, const unsigned& errorNumber,
   1403                                 const unsigned& noteErrorNumber);
   1404 
   1405  void reportRedeclaration(TaggedParserAtomIndex name, DeclarationKind prevKind,
   1406                           TokenPos pos, uint32_t prevPos);
   1407 
   1408  void reportMismatchedPlacement(TaggedParserAtomIndex name,
   1409                                 DeclarationKind prevKind, TokenPos pos,
   1410                                 uint32_t prevPos);
   1411 
   1412  bool notePositionalFormalParameter(FunctionNodeType funNode,
   1413                                     TaggedParserAtomIndex name,
   1414                                     uint32_t beginPos,
   1415                                     bool disallowDuplicateParams,
   1416                                     bool* duplicatedParam);
   1417 
   1418  enum PropertyNameContext {
   1419    PropertyNameInLiteral,
   1420    PropertyNameInPattern,
   1421    PropertyNameInClass,
   1422  };
   1423  NodeResult propertyName(YieldHandling yieldHandling,
   1424                          PropertyNameContext propertyNameContext,
   1425                          const mozilla::Maybe<DeclarationKind>& maybeDecl,
   1426                          ListNodeType propList,
   1427                          TaggedParserAtomIndex* propAtomOut);
   1428  NodeResult propertyOrMethodName(
   1429      YieldHandling yieldHandling, PropertyNameContext propertyNameContext,
   1430      const mozilla::Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
   1431      PropertyType* propType, TaggedParserAtomIndex* propAtomOut);
   1432  UnaryNodeResult computedPropertyName(
   1433      YieldHandling yieldHandling,
   1434      const mozilla::Maybe<DeclarationKind>& maybeDecl,
   1435      PropertyNameContext propertyNameContext, ListNodeType literal);
   1436  ListNodeResult arrayInitializer(YieldHandling yieldHandling,
   1437                                  PossibleError* possibleError);
   1438  inline RegExpLiteralResult newRegExp();
   1439 
   1440  ListNodeResult objectLiteral(YieldHandling yieldHandling,
   1441                               PossibleError* possibleError);
   1442 
   1443  BinaryNodeResult bindingInitializer(Node lhs, DeclarationKind kind,
   1444                                      YieldHandling yieldHandling);
   1445  NameNodeResult bindingIdentifier(DeclarationKind kind,
   1446                                   YieldHandling yieldHandling);
   1447  NodeResult bindingIdentifierOrPattern(DeclarationKind kind,
   1448                                        YieldHandling yieldHandling,
   1449                                        TokenKind tt);
   1450  ListNodeResult objectBindingPattern(DeclarationKind kind,
   1451                                      YieldHandling yieldHandling);
   1452  ListNodeResult arrayBindingPattern(DeclarationKind kind,
   1453                                     YieldHandling yieldHandling);
   1454 
   1455  enum class TargetBehavior {
   1456    PermitAssignmentPattern,
   1457    ForbidAssignmentPattern
   1458  };
   1459  bool checkDestructuringAssignmentTarget(
   1460      Node expr, TokenPos exprPos, PossibleError* exprPossibleError,
   1461      PossibleError* possibleError,
   1462      TargetBehavior behavior = TargetBehavior::PermitAssignmentPattern);
   1463  void checkDestructuringAssignmentName(NameNodeType name, TokenPos namePos,
   1464                                        PossibleError* possibleError);
   1465  bool checkDestructuringAssignmentElement(Node expr, TokenPos exprPos,
   1466                                           PossibleError* exprPossibleError,
   1467                                           PossibleError* possibleError);
   1468 
   1469  NumericLiteralResult newNumber(const Token& tok) {
   1470    return handler_.newNumber(tok.number(), tok.decimalPoint(), tok.pos);
   1471  }
   1472 
   1473  inline BigIntLiteralResult newBigInt();
   1474 
   1475  enum class OptionalKind {
   1476    NonOptional = 0,
   1477    Optional,
   1478  };
   1479  NodeResult memberPropertyAccess(
   1480      Node lhs, OptionalKind optionalKind = OptionalKind::NonOptional);
   1481  NodeResult memberPrivateAccess(
   1482      Node lhs, OptionalKind optionalKind = OptionalKind::NonOptional);
   1483  NodeResult memberElemAccess(
   1484      Node lhs, YieldHandling yieldHandling,
   1485      OptionalKind optionalKind = OptionalKind::NonOptional);
   1486  NodeResult memberSuperCall(Node lhs, YieldHandling yieldHandling);
   1487  NodeResult memberCall(TokenKind tt, Node lhs, YieldHandling yieldHandling,
   1488                        PossibleError* possibleError,
   1489                        OptionalKind optionalKind = OptionalKind::NonOptional);
   1490 
   1491 protected:
   1492  // Match the current token against the BindingIdentifier production with
   1493  // the given Yield parameter.  If there is no match, report a syntax
   1494  // error.
   1495  TaggedParserAtomIndex bindingIdentifier(YieldHandling yieldHandling);
   1496 
   1497  bool checkLabelOrIdentifierReference(TaggedParserAtomIndex ident,
   1498                                       uint32_t offset,
   1499                                       YieldHandling yieldHandling,
   1500                                       TokenKind hint = TokenKind::Limit);
   1501 
   1502  ListNodeResult statementList(YieldHandling yieldHandling);
   1503 
   1504  [[nodiscard]] FunctionNodeResult innerFunction(
   1505      FunctionNodeType funNode, ParseContext* outerpc,
   1506      TaggedParserAtomIndex explicitName, FunctionFlags flags,
   1507      uint32_t toStringStart, InHandling inHandling,
   1508      YieldHandling yieldHandling, FunctionSyntaxKind kind,
   1509      GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
   1510      Directives inheritedDirectives, Directives* newDirectives);
   1511 
   1512  // Implements Automatic Semicolon Insertion.
   1513  //
   1514  // Use this to match `;` in contexts where ASI is allowed. Call this after
   1515  // ruling out all other possibilities except `;`, by peeking ahead if
   1516  // necessary.
   1517  //
   1518  // Unlike most optional Modifiers, this method's `modifier` argument defaults
   1519  // to SlashIsRegExp, since that's by far the most common case: usually an
   1520  // optional semicolon is at the end of a statement or declaration, and the
   1521  // next token could be a RegExp literal beginning a new ExpressionStatement.
   1522  bool matchOrInsertSemicolon(Modifier modifier = TokenStream::SlashIsRegExp);
   1523 
   1524  bool noteDeclaredName(TaggedParserAtomIndex name, DeclarationKind kind,
   1525                        TokenPos pos, ClosedOver isClosedOver = ClosedOver::No);
   1526 
   1527  bool noteDeclaredPrivateName(Node nameNode, TaggedParserAtomIndex name,
   1528                               PropertyType propType, FieldPlacement placement,
   1529                               TokenPos pos);
   1530 
   1531 private:
   1532  inline bool asmJS(TokenPos directivePos, ListNodeType list);
   1533 };
   1534 
   1535 template <typename Unit>
   1536 class MOZ_STACK_CLASS Parser<SyntaxParseHandler, Unit> final
   1537    : public GeneralParser<SyntaxParseHandler, Unit> {
   1538  using Base = GeneralParser<SyntaxParseHandler, Unit>;
   1539  using Node = SyntaxParseHandler::Node;
   1540  using NodeResult = typename SyntaxParseHandler::NodeResult;
   1541 
   1542 #define DECLARE_TYPE(typeName)                               \
   1543  using typeName##Type = SyntaxParseHandler::typeName##Type; \
   1544  using typeName##Result = SyntaxParseHandler::typeName##Result;
   1545  FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
   1546 #undef DECLARE_TYPE
   1547 
   1548  using SyntaxParser = Parser<SyntaxParseHandler, Unit>;
   1549 
   1550  // Numerous Base::* functions have bodies like
   1551  //
   1552  //   return asFinalParser()->func(...);
   1553  //
   1554  // and must be able to call functions here.  Add a friendship relationship
   1555  // so functions here can be hidden when appropriate.
   1556  friend class GeneralParser<SyntaxParseHandler, Unit>;
   1557 
   1558 public:
   1559  using Base::Base;
   1560 
   1561  // Inherited types, listed here to have non-dependent names.
   1562  using typename Base::Modifier;
   1563  using typename Base::Position;
   1564  using typename Base::TokenStream;
   1565 
   1566  // Inherited functions, listed here to have non-dependent names.
   1567 
   1568 public:
   1569  using Base::anyChars;
   1570  using Base::clearAbortedSyntaxParse;
   1571  using Base::hadAbortedSyntaxParse;
   1572  using Base::innerFunctionForFunctionBox;
   1573  using Base::tokenStream;
   1574 
   1575 public:
   1576  // ErrorReportMixin.
   1577 
   1578  using Base::error;
   1579  using Base::errorAt;
   1580  using Base::errorNoOffset;
   1581  using Base::errorWithNotes;
   1582  using Base::errorWithNotesAt;
   1583  using Base::errorWithNotesNoOffset;
   1584  using Base::strictModeError;
   1585  using Base::strictModeErrorAt;
   1586  using Base::strictModeErrorNoOffset;
   1587  using Base::strictModeErrorWithNotes;
   1588  using Base::strictModeErrorWithNotesAt;
   1589  using Base::strictModeErrorWithNotesNoOffset;
   1590  using Base::warning;
   1591  using Base::warningAt;
   1592  using Base::warningNoOffset;
   1593 
   1594 private:
   1595  using Base::alloc_;
   1596 #if DEBUG
   1597  using Base::checkOptionsCalled_;
   1598 #endif
   1599  using Base::checkForUndefinedPrivateFields;
   1600  using Base::errorResult;
   1601  using Base::finishFunctionScopes;
   1602  using Base::functionFormalParametersAndBody;
   1603  using Base::handler_;
   1604  using Base::innerFunction;
   1605  using Base::matchOrInsertSemicolon;
   1606  using Base::mustMatchToken;
   1607  using Base::newFunctionBox;
   1608  using Base::newLexicalScopeData;
   1609  using Base::newModuleScopeData;
   1610  using Base::newName;
   1611  using Base::noteDeclaredName;
   1612  using Base::null;
   1613  using Base::options;
   1614  using Base::pc_;
   1615  using Base::pos;
   1616  using Base::propagateFreeNamesAndMarkClosedOverBindings;
   1617  using Base::ss;
   1618  using Base::statementList;
   1619  using Base::stringLiteral;
   1620  using Base::usedNames_;
   1621 
   1622 private:
   1623  using Base::abortIfSyntaxParser;
   1624  using Base::disableSyntaxParser;
   1625 
   1626 public:
   1627  // Functions with multiple overloads of different visibility.  We can't
   1628  // |using| the whole thing into existence because of the visibility
   1629  // distinction, so we instead must manually delegate the required overload.
   1630 
   1631  TaggedParserAtomIndex bindingIdentifier(YieldHandling yieldHandling) {
   1632    return Base::bindingIdentifier(yieldHandling);
   1633  }
   1634 
   1635  // Functions present in both Parser<ParseHandler, Unit> specializations.
   1636 
   1637  inline void setAwaitHandling(AwaitHandling awaitHandling);
   1638  inline void setInParametersOfAsyncFunction(bool inParameters);
   1639 
   1640  RegExpLiteralResult newRegExp();
   1641  BigIntLiteralResult newBigInt();
   1642 
   1643  // Parse a module.
   1644  ModuleNodeResult moduleBody(ModuleSharedContext* modulesc);
   1645 
   1646  inline bool checkLocalExportNames(ListNodeType node);
   1647  inline bool checkExportedName(TaggedParserAtomIndex exportName);
   1648  inline bool checkExportedNamesForArrayBinding(ListNodeType array);
   1649  inline bool checkExportedNamesForObjectBinding(ListNodeType obj);
   1650  inline bool checkExportedNamesForDeclaration(Node node);
   1651  inline bool checkExportedNamesForDeclarationList(
   1652      DeclarationListNodeType node);
   1653  inline bool checkExportedNameForFunction(FunctionNodeType funNode);
   1654  inline bool checkExportedNameForClass(ClassNodeType classNode);
   1655  inline bool checkExportedNameForClause(NameNodeType nameNode);
   1656 
   1657  bool trySyntaxParseInnerFunction(
   1658      FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
   1659      FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
   1660      YieldHandling yieldHandling, FunctionSyntaxKind kind,
   1661      GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
   1662      Directives inheritedDirectives, Directives* newDirectives);
   1663 
   1664  bool skipLazyInnerFunction(FunctionNodeType funNode, uint32_t toStringStart,
   1665                             bool tryAnnexB);
   1666 
   1667  bool asmJS(TokenPos directivePos, ListNodeType list);
   1668 
   1669  // Functions present only in Parser<SyntaxParseHandler, Unit>.
   1670 };
   1671 
   1672 template <typename Unit>
   1673 class MOZ_STACK_CLASS Parser<FullParseHandler, Unit> final
   1674    : public GeneralParser<FullParseHandler, Unit> {
   1675  using Base = GeneralParser<FullParseHandler, Unit>;
   1676  using Node = FullParseHandler::Node;
   1677  using NodeResult = typename FullParseHandler::NodeResult;
   1678 
   1679 #define DECLARE_TYPE(typeName)                             \
   1680  using typeName##Type = FullParseHandler::typeName##Type; \
   1681  using typeName##Result = FullParseHandler::typeName##Result;
   1682  FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
   1683 #undef DECLARE_TYPE
   1684 
   1685  using SyntaxParser = Parser<SyntaxParseHandler, Unit>;
   1686 
   1687  // Numerous Base::* functions have bodies like
   1688  //
   1689  //   return asFinalParser()->func(...);
   1690  //
   1691  // and must be able to call functions here.  Add a friendship relationship
   1692  // so functions here can be hidden when appropriate.
   1693  friend class GeneralParser<FullParseHandler, Unit>;
   1694 
   1695 public:
   1696  using Base::Base;
   1697 
   1698  // Inherited types, listed here to have non-dependent names.
   1699  using typename Base::Modifier;
   1700  using typename Base::Position;
   1701  using typename Base::TokenStream;
   1702 
   1703  // Inherited functions, listed here to have non-dependent names.
   1704 
   1705 public:
   1706  using Base::anyChars;
   1707  using Base::clearAbortedSyntaxParse;
   1708  using Base::functionFormalParametersAndBody;
   1709  using Base::hadAbortedSyntaxParse;
   1710  using Base::handler_;
   1711  using Base::newFunctionBox;
   1712  using Base::options;
   1713  using Base::pc_;
   1714  using Base::pos;
   1715  using Base::ss;
   1716  using Base::tokenStream;
   1717 
   1718 public:
   1719  // ErrorReportMixin.
   1720 
   1721  using Base::error;
   1722  using Base::errorAt;
   1723  using Base::errorNoOffset;
   1724  using Base::errorWithNotes;
   1725  using Base::errorWithNotesAt;
   1726  using Base::errorWithNotesNoOffset;
   1727  using Base::strictModeError;
   1728  using Base::strictModeErrorAt;
   1729  using Base::strictModeErrorNoOffset;
   1730  using Base::strictModeErrorWithNotes;
   1731  using Base::strictModeErrorWithNotesAt;
   1732  using Base::strictModeErrorWithNotesNoOffset;
   1733  using Base::warning;
   1734  using Base::warningAt;
   1735  using Base::warningNoOffset;
   1736 
   1737 private:
   1738  using Base::alloc_;
   1739  using Base::checkLabelOrIdentifierReference;
   1740 #if DEBUG
   1741  using Base::checkOptionsCalled_;
   1742 #endif
   1743  using Base::checkForUndefinedPrivateFields;
   1744  using Base::errorResult;
   1745  using Base::fc_;
   1746  using Base::finishClassBodyScope;
   1747  using Base::finishFunctionScopes;
   1748  using Base::finishLexicalScope;
   1749  using Base::innerFunction;
   1750  using Base::innerFunctionForFunctionBox;
   1751  using Base::matchOrInsertSemicolon;
   1752  using Base::mustMatchToken;
   1753  using Base::newEvalScopeData;
   1754  using Base::newFunctionScopeData;
   1755  using Base::newGlobalScopeData;
   1756  using Base::newLexicalScopeData;
   1757  using Base::newModuleScopeData;
   1758  using Base::newName;
   1759  using Base::newVarScopeData;
   1760  using Base::noteDeclaredName;
   1761  using Base::noteUsedName;
   1762  using Base::null;
   1763  using Base::propagateFreeNamesAndMarkClosedOverBindings;
   1764  using Base::statementList;
   1765  using Base::stringLiteral;
   1766  using Base::usedNames_;
   1767 
   1768  using Base::abortIfSyntaxParser;
   1769  using Base::disableSyntaxParser;
   1770  using Base::getSyntaxParser;
   1771 
   1772 public:
   1773  // Functions with multiple overloads of different visibility.  We can't
   1774  // |using| the whole thing into existence because of the visibility
   1775  // distinction, so we instead must manually delegate the required overload.
   1776 
   1777  TaggedParserAtomIndex bindingIdentifier(YieldHandling yieldHandling) {
   1778    return Base::bindingIdentifier(yieldHandling);
   1779  }
   1780 
   1781  // Functions present in both Parser<ParseHandler, Unit> specializations.
   1782 
   1783  friend class AutoAwaitIsKeyword<SyntaxParseHandler, Unit>;
   1784  inline void setAwaitHandling(AwaitHandling awaitHandling);
   1785 
   1786  friend class AutoInParametersOfAsyncFunction<SyntaxParseHandler, Unit>;
   1787  inline void setInParametersOfAsyncFunction(bool inParameters);
   1788 
   1789  RegExpLiteralResult newRegExp();
   1790  BigIntLiteralResult newBigInt();
   1791 
   1792  // Parse a module.
   1793  ModuleNodeResult moduleBody(ModuleSharedContext* modulesc);
   1794 
   1795  bool checkLocalExportNames(ListNodeType node);
   1796  bool checkExportedName(TaggedParserAtomIndex exportName);
   1797  bool checkExportedNamesForArrayBinding(ListNodeType array);
   1798  bool checkExportedNamesForObjectBinding(ListNodeType obj);
   1799  bool checkExportedNamesForDeclaration(Node node);
   1800  bool checkExportedNamesForDeclarationList(DeclarationListNodeType node);
   1801  bool checkExportedNameForFunction(FunctionNodeType funNode);
   1802  bool checkExportedNameForClass(ClassNodeType classNode);
   1803  inline bool checkExportedNameForClause(NameNodeType nameNode);
   1804 
   1805  bool trySyntaxParseInnerFunction(
   1806      FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
   1807      FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
   1808      YieldHandling yieldHandling, FunctionSyntaxKind kind,
   1809      GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
   1810      Directives inheritedDirectives, Directives* newDirectives);
   1811 
   1812  [[nodiscard]] bool advancePastSyntaxParsedFunction(
   1813      SyntaxParser* syntaxParser);
   1814 
   1815  bool skipLazyInnerFunction(FunctionNodeType funNode, uint32_t toStringStart,
   1816                             bool tryAnnexB);
   1817 
   1818  // Functions present only in Parser<FullParseHandler, Unit>.
   1819 
   1820  // Parse the body of an eval.
   1821  //
   1822  // Eval scripts are distinguished from global scripts in that in ES6, per
   1823  // 18.2.1.1 steps 9 and 10, all eval scripts are executed under a fresh
   1824  // lexical scope.
   1825  LexicalScopeNodeResult evalBody(EvalSharedContext* evalsc);
   1826 
   1827  // Parse a function, given only its arguments and body. Used for lazily
   1828  // parsed functions.
   1829  FunctionNodeResult standaloneLazyFunction(CompilationInput& input,
   1830                                            uint32_t toStringStart, bool strict,
   1831                                            GeneratorKind generatorKind,
   1832                                            FunctionAsyncKind asyncKind);
   1833 
   1834  // Parse a function, used for the Function, GeneratorFunction, and
   1835  // AsyncFunction constructors.
   1836  FunctionNodeResult standaloneFunction(
   1837      const mozilla::Maybe<uint32_t>& parameterListEnd,
   1838      FunctionSyntaxKind syntaxKind, GeneratorKind generatorKind,
   1839      FunctionAsyncKind asyncKind, Directives inheritedDirectives,
   1840      Directives* newDirectives);
   1841 
   1842  bool checkStatementsEOF();
   1843 
   1844  // Parse the body of a global script.
   1845  ListNodeResult globalBody(GlobalSharedContext* globalsc);
   1846 
   1847  bool checkLocalExportName(TaggedParserAtomIndex ident, uint32_t offset) {
   1848    return checkLabelOrIdentifierReference(ident, offset, YieldIsName);
   1849  }
   1850 
   1851  bool asmJS(TokenPos directivePos, ListNodeType list);
   1852 };
   1853 
   1854 template <class Parser>
   1855 /* static */ inline const TokenStreamAnyChars&
   1856 ParserAnyCharsAccess<Parser>::anyChars(const GeneralTokenStreamChars* ts) {
   1857  // The structure we're walking through looks like this:
   1858  //
   1859  //   struct ParserBase
   1860  //   {
   1861  //       ...;
   1862  //       TokenStreamAnyChars anyChars;
   1863  //       ...;
   1864  //   };
   1865  //   struct Parser : <class that ultimately inherits from ParserBase>
   1866  //   {
   1867  //       ...;
   1868  //       TokenStreamSpecific tokenStream;
   1869  //       ...;
   1870  //   };
   1871  //
   1872  // We're passed a GeneralTokenStreamChars* (this being a base class of
   1873  // Parser::tokenStream).  We cast that pointer to a TokenStreamSpecific*,
   1874  // then translate that to the enclosing Parser*, then return the |anyChars|
   1875  // member within.
   1876 
   1877  static_assert(std::is_base_of_v<GeneralTokenStreamChars, TokenStreamSpecific>,
   1878                "the static_cast<> below assumes a base-class relationship");
   1879  const auto* tss = static_cast<const TokenStreamSpecific*>(ts);
   1880 
   1881  auto tssAddr = reinterpret_cast<uintptr_t>(tss);
   1882 
   1883  using ActualTokenStreamType = decltype(std::declval<Parser>().tokenStream);
   1884  static_assert(std::is_same_v<ActualTokenStreamType, TokenStreamSpecific>,
   1885                "Parser::tokenStream must have type TokenStreamSpecific");
   1886 
   1887  uintptr_t parserAddr = tssAddr - offsetof(Parser, tokenStream);
   1888 
   1889  return reinterpret_cast<const Parser*>(parserAddr)->anyChars;
   1890 }
   1891 
   1892 template <class Parser>
   1893 /* static */ inline TokenStreamAnyChars& ParserAnyCharsAccess<Parser>::anyChars(
   1894    GeneralTokenStreamChars* ts) {
   1895  const TokenStreamAnyChars& anyCharsConst =
   1896      anyChars(const_cast<const GeneralTokenStreamChars*>(ts));
   1897 
   1898  return const_cast<TokenStreamAnyChars&>(anyCharsConst);
   1899 }
   1900 
   1901 template <class ParseHandler, typename Unit>
   1902 class MOZ_STACK_CLASS AutoAwaitIsKeyword {
   1903  using GeneralParser = frontend::GeneralParser<ParseHandler, Unit>;
   1904 
   1905 private:
   1906  GeneralParser* parser_;
   1907  AwaitHandling oldAwaitHandling_;
   1908 
   1909 public:
   1910  AutoAwaitIsKeyword(GeneralParser* parser, AwaitHandling awaitHandling) {
   1911    parser_ = parser;
   1912    oldAwaitHandling_ = static_cast<AwaitHandling>(parser_->awaitHandling_);
   1913 
   1914    // 'await' is always a keyword in module contexts, so we don't modify
   1915    // the state when the original handling is AwaitIsModuleKeyword.
   1916    if (oldAwaitHandling_ != AwaitIsModuleKeyword) {
   1917      parser_->setAwaitHandling(awaitHandling);
   1918    }
   1919  }
   1920 
   1921  ~AutoAwaitIsKeyword() { parser_->setAwaitHandling(oldAwaitHandling_); }
   1922 };
   1923 
   1924 template <class ParseHandler, typename Unit>
   1925 class MOZ_STACK_CLASS AutoInParametersOfAsyncFunction {
   1926  using GeneralParser = frontend::GeneralParser<ParseHandler, Unit>;
   1927 
   1928 private:
   1929  GeneralParser* parser_;
   1930  bool oldInParametersOfAsyncFunction_;
   1931 
   1932 public:
   1933  AutoInParametersOfAsyncFunction(GeneralParser* parser, bool inParameters) {
   1934    parser_ = parser;
   1935    oldInParametersOfAsyncFunction_ = parser_->inParametersOfAsyncFunction_;
   1936    parser_->setInParametersOfAsyncFunction(inParameters);
   1937  }
   1938 
   1939  ~AutoInParametersOfAsyncFunction() {
   1940    parser_->setInParametersOfAsyncFunction(oldInParametersOfAsyncFunction_);
   1941  }
   1942 };
   1943 
   1944 GlobalScope::ParserData* NewEmptyGlobalScopeData(FrontendContext* fc,
   1945                                                 LifoAlloc& alloc,
   1946                                                 uint32_t numBindings);
   1947 
   1948 VarScope::ParserData* NewEmptyVarScopeData(FrontendContext* fc,
   1949                                           LifoAlloc& alloc,
   1950                                           uint32_t numBindings);
   1951 
   1952 LexicalScope::ParserData* NewEmptyLexicalScopeData(FrontendContext* fc,
   1953                                                   LifoAlloc& alloc,
   1954                                                   uint32_t numBindings);
   1955 
   1956 FunctionScope::ParserData* NewEmptyFunctionScopeData(FrontendContext* fc,
   1957                                                     LifoAlloc& alloc,
   1958                                                     uint32_t numBindings);
   1959 
   1960 bool FunctionScopeHasClosedOverBindings(ParseContext* pc);
   1961 bool LexicalScopeHasClosedOverBindings(ParseContext* pc,
   1962                                       ParseContext::Scope& scope);
   1963 
   1964 } /* namespace frontend */
   1965 } /* namespace js */
   1966 
   1967 #endif /* frontend_Parser_h */