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