Bug 1865597 - Add error checking when initializing parallel marking and disable on...
[gecko.git] / js / src / frontend / Parser.h
blob99e6717b644ec378fb9d6f0026f245b721228f26
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/. */
7 /* JS parser. */
9 #ifndef frontend_Parser_h
10 #define frontend_Parser_h
13 * [SMDOC] JS Parser
15 * JS parsers capable of generating ASTs from source text.
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.
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.
29 * == ParserSharedBase ==
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.
36 * == ParserBase → ParserSharedBase, ErrorReportMixin ==
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.
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|.
50 * == PerHandlerParser<ParseHandler> → ParserBase ==
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.
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).
63 * == GeneralParser<ParseHandler, Unit> → PerHandlerParser<ParseHandler> ==
65 * Most parsing behavior varies across the character-type axis (and possibly
66 * along the full/syntax axis). For example:
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.
80 * Such functionality, implemented using identical function code across these
81 * axes, should live in GeneralParser.
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.
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.
97 * == Parser<ParseHandler, Unit> final → GeneralParser<ParseHandler, Unit> ==
99 * The final (pun intended) axis of complexity lies in Parser.
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.
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:
114 * template<class ParseHandler, typename Unit>
115 * class GeneralParser : ...
117 * ...parsing functions...
118 * };
120 * but Parser is one undefined template class with two separate
121 * specializations:
123 * // Declare, but do not define.
124 * template<class ParseHandler, typename Unit> class Parser;
126 * // Define a syntax-parsing specialization.
127 * template<typename Unit>
128 * class Parser<SyntaxParseHandler, Unit> final
129 * : public GeneralParser<SyntaxParseHandler, Unit>
131 * ...parsing functions...
132 * };
134 * // Define a full-parsing specialization.
135 * template<typename Unit>
136 * class Parser<SyntaxParseHandler, Unit> final
137 * : public GeneralParser<SyntaxParseHandler, Unit>
139 * ...parsing functions...
140 * };
142 * This odd distinction is necessary because C++ unfortunately doesn't allow
143 * partial function specialization:
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() {}
151 * But if you specialize Parser *as a class*, then this is allowed:
153 * template<typename Unit>
154 * void
155 * Parser<SyntaxParseHandler, Unit>::foo() {}
157 * template<typename Unit>
158 * void
159 * Parser<FullParseHandler, Unit>::foo() {}
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.
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.
170 #include "mozilla/Maybe.h"
172 #include <type_traits>
173 #include <utility>
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
190 namespace js {
192 class FrontendContext;
193 struct ErrorMetadata;
195 namespace frontend {
197 template <class ParseHandler, typename Unit>
198 class GeneralParser;
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>) {}
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,
228 enum AwaitHandling : uint8_t {
229 AwaitIsName,
230 AwaitIsKeyword,
231 AwaitIsModuleKeyword,
232 AwaitIsDisallowed
235 template <class ParseHandler, typename Unit>
236 class AutoAwaitIsKeyword;
238 template <class ParseHandler, typename Unit>
239 class AutoInParametersOfAsyncFunction;
241 class MOZ_STACK_CLASS ParserSharedBase {
242 public:
243 enum class Kind { Parser };
245 ParserSharedBase(FrontendContext* fc, CompilationState& compilationState,
246 Kind kind);
247 ~ParserSharedBase();
249 public:
250 FrontendContext* fc_;
252 LifoAlloc& alloc_;
254 CompilationState& compilationState_;
256 // innermost parse context (stack-allocated)
257 ParseContext* pc_;
259 // For tracking used names in this parsing session.
260 UsedNameTracker& usedNames_;
262 public:
263 CompilationState& getCompilationState() { return compilationState_; }
265 ParserAtomsTable& parserAtoms() { return compilationState_.parserAtoms; }
266 const ParserAtomsTable& parserAtoms() const {
267 return compilationState_.parserAtoms;
270 LifoAlloc& stencilAlloc() { return compilationState_.alloc; }
272 const UsedNameTracker& usedNames() { return usedNames_; }
274 #if defined(DEBUG) || defined(JS_JITSPEW)
275 void dumpAtom(TaggedParserAtomIndex index) const;
276 #endif
279 class MOZ_STACK_CLASS ParserBase : public ParserSharedBase,
280 public ErrorReportMixin {
281 using Base = ErrorReportMixin;
283 public:
284 TokenStreamAnyChars anyChars;
286 ScriptSource* ss;
288 // Perform constant-folding; must be true when interfacing with the emitter.
289 const bool foldConstants_ : 1;
291 protected:
292 #if DEBUG
293 /* Our fallible 'checkOptions' member function has been called. */
294 bool checkOptionsCalled_ : 1;
295 #endif
297 /* Unexpected end of input, i.e. Eof not at top-level. */
298 bool isUnexpectedEOF_ : 1;
300 /* AwaitHandling */ uint8_t awaitHandling_ : 2;
302 bool inParametersOfAsyncFunction_ : 1;
304 public:
305 JSAtom* liftParserAtomToJSAtom(TaggedParserAtomIndex index);
307 bool awaitIsKeyword() const {
308 return awaitHandling_ == AwaitIsKeyword ||
309 awaitHandling_ == AwaitIsModuleKeyword;
311 bool awaitIsDisallowed() const { return awaitHandling_ == AwaitIsDisallowed; }
313 bool inParametersOfAsyncFunction() const {
314 return inParametersOfAsyncFunction_;
317 ParseGoal parseGoal() const {
318 return pc_->sc()->hasModuleGoal() ? ParseGoal::Module : ParseGoal::Script;
321 template <class, typename>
322 friend class AutoAwaitIsKeyword;
323 template <class, typename>
324 friend class AutoInParametersOfAsyncFunction;
326 ParserBase(FrontendContext* fc, const JS::ReadOnlyCompileOptions& options,
327 bool foldConstants, CompilationState& compilationState);
328 ~ParserBase();
330 bool checkOptions();
332 JS::ConstUTF8CharsZ getFilename() const { return anyChars.getFilename(); }
333 TokenPos pos() const { return anyChars.currentToken().pos; }
335 // Determine whether |yield| is a valid name in the current context.
336 bool yieldExpressionsSupported() const { return pc_->isGenerator(); }
338 bool setLocalStrictMode(bool strict) {
339 MOZ_ASSERT(anyChars.debugHasNoLookahead());
340 return pc_->sc()->setLocalStrictMode(strict);
343 public:
344 // Implement ErrorReportMixin.
346 FrontendContext* getContext() const override { return fc_; }
348 bool strictMode() const override { return pc_->sc()->strict(); }
350 const JS::ReadOnlyCompileOptions& options() const override {
351 return anyChars.options();
354 using Base::error;
355 using Base::errorAt;
356 using Base::errorNoOffset;
357 using Base::errorWithNotes;
358 using Base::errorWithNotesAt;
359 using Base::errorWithNotesNoOffset;
360 using Base::strictModeError;
361 using Base::strictModeErrorAt;
362 using Base::strictModeErrorNoOffset;
363 using Base::strictModeErrorWithNotes;
364 using Base::strictModeErrorWithNotesAt;
365 using Base::strictModeErrorWithNotesNoOffset;
366 using Base::warning;
367 using Base::warningAt;
368 using Base::warningNoOffset;
370 public:
371 bool isUnexpectedEOF() const { return isUnexpectedEOF_; }
373 bool isValidStrictBinding(TaggedParserAtomIndex name);
375 bool hasValidSimpleStrictParameterNames();
377 // A Parser::Mark is the extension of the LifoAlloc::Mark to the entire
378 // Parser's state. Note: clients must still take care that any ParseContext
379 // that points into released ParseNodes is destroyed.
380 class Mark {
381 friend class ParserBase;
382 LifoAlloc::Mark mark;
383 CompilationState::CompilationStatePosition pos;
385 Mark mark() const {
386 Mark m;
387 m.mark = alloc_.mark();
388 m.pos = compilationState_.getPosition();
389 return m;
391 void release(Mark m) {
392 alloc_.release(m.mark);
393 compilationState_.rewind(m.pos);
396 public:
397 mozilla::Maybe<GlobalScope::ParserData*> newGlobalScopeData(
398 ParseContext::Scope& scope);
399 mozilla::Maybe<ModuleScope::ParserData*> newModuleScopeData(
400 ParseContext::Scope& scope);
401 mozilla::Maybe<EvalScope::ParserData*> newEvalScopeData(
402 ParseContext::Scope& scope);
403 mozilla::Maybe<FunctionScope::ParserData*> newFunctionScopeData(
404 ParseContext::Scope& scope, bool hasParameterExprs);
405 mozilla::Maybe<VarScope::ParserData*> newVarScopeData(
406 ParseContext::Scope& scope);
407 mozilla::Maybe<LexicalScope::ParserData*> newLexicalScopeData(
408 ParseContext::Scope& scope);
409 mozilla::Maybe<ClassBodyScope::ParserData*> newClassBodyScopeData(
410 ParseContext::Scope& scope);
412 protected:
413 enum InvokedPrediction { PredictUninvoked = false, PredictInvoked = true };
414 enum ForInitLocation { InForInit, NotInForInit };
416 // While on a |let| Name token, examine |next| (which must already be
417 // gotten). Indicate whether |next|, the next token already gotten with
418 // modifier TokenStream::SlashIsDiv, continues a LexicalDeclaration.
419 bool nextTokenContinuesLetDeclaration(TokenKind next);
421 bool noteUsedNameInternal(TaggedParserAtomIndex name,
422 NameVisibility visibility,
423 mozilla::Maybe<TokenPos> tokenPosition);
425 bool checkAndMarkSuperScope();
427 bool leaveInnerFunction(ParseContext* outerpc);
429 TaggedParserAtomIndex prefixAccessorName(PropertyType propType,
430 TaggedParserAtomIndex propAtom);
432 [[nodiscard]] bool setSourceMapInfo();
434 void setFunctionEndFromCurrentToken(FunctionBox* funbox) const;
437 template <class ParseHandler>
438 class MOZ_STACK_CLASS PerHandlerParser : public ParserBase {
439 using Base = ParserBase;
441 private:
442 using Node = typename ParseHandler::Node;
443 using NodeResult = typename ParseHandler::NodeResult;
445 #define DECLARE_TYPE(typeName) \
446 using typeName##Type = typename ParseHandler::typeName##Type; \
447 using typeName##Result = typename ParseHandler::typeName##Result;
448 FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
449 #undef DECLARE_TYPE
451 protected:
452 /* State specific to the kind of parse being performed. */
453 ParseHandler handler_;
455 // When ParseHandler is FullParseHandler:
457 // If non-null, this field holds the syntax parser used to attempt lazy
458 // parsing of inner functions. If null, then lazy parsing is disabled.
460 // When ParseHandler is SyntaxParseHandler:
462 // If non-null, this field must be a sentinel value signaling that the
463 // syntax parse was aborted. If null, then lazy parsing was aborted due
464 // to encountering unsupported language constructs.
466 // |internalSyntaxParser_| is really a |Parser<SyntaxParseHandler, Unit>*|
467 // where |Unit| varies per |Parser<ParseHandler, Unit>|. But this
468 // template class doesn't know |Unit|, so we store a |void*| here and make
469 // |GeneralParser<ParseHandler, Unit>::getSyntaxParser| impose the real type.
470 void* internalSyntaxParser_;
472 private:
473 // NOTE: The argument ordering here is deliberately different from the
474 // public constructor so that typos calling the public constructor
475 // are less likely to select this overload.
476 PerHandlerParser(FrontendContext* fc,
477 const JS::ReadOnlyCompileOptions& options,
478 bool foldConstants, CompilationState& compilationState,
479 void* internalSyntaxParser);
481 protected:
482 template <typename Unit>
483 PerHandlerParser(FrontendContext* fc,
484 const JS::ReadOnlyCompileOptions& options,
485 bool foldConstants, CompilationState& compilationState,
486 GeneralParser<SyntaxParseHandler, Unit>* syntaxParser)
487 : PerHandlerParser(fc, options, foldConstants, compilationState,
488 static_cast<void*>(syntaxParser)) {}
490 static typename ParseHandler::NullNode null() { return ParseHandler::null(); }
492 // The return value for the error case in the functions that returns
493 // Result type.
494 static constexpr typename ParseHandler::NodeErrorResult errorResult() {
495 return ParseHandler::errorResult();
498 NameNodeResult stringLiteral();
500 const char* nameIsArgumentsOrEval(Node node);
502 bool noteDestructuredPositionalFormalParameter(FunctionNodeType funNode,
503 Node destruct);
505 bool noteUsedName(
506 TaggedParserAtomIndex name,
507 NameVisibility visibility = NameVisibility::Public,
508 mozilla::Maybe<TokenPos> tokenPosition = mozilla::Nothing()) {
509 // If the we are delazifying, the BaseScript already has all the closed-over
510 // info for bindings and there's no need to track used names.
511 if (handler_.reuseClosedOverBindings()) {
512 return true;
515 return ParserBase::noteUsedNameInternal(name, visibility, tokenPosition);
518 // Required on Scope exit.
519 bool propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope);
521 bool checkForUndefinedPrivateFields(EvalSharedContext* evalSc = nullptr);
523 bool finishFunctionScopes(bool isStandaloneFunction);
524 LexicalScopeNodeResult finishLexicalScope(
525 ParseContext::Scope& scope, Node body,
526 ScopeKind kind = ScopeKind::Lexical);
527 ClassBodyScopeNodeResult finishClassBodyScope(ParseContext::Scope& scope,
528 ListNodeType body);
529 bool finishFunction(bool isStandaloneFunction = false);
531 inline NameNodeResult newName(TaggedParserAtomIndex name);
532 inline NameNodeResult newName(TaggedParserAtomIndex name, TokenPos pos);
534 inline NameNodeResult newPrivateName(TaggedParserAtomIndex name);
536 NameNodeResult newInternalDotName(TaggedParserAtomIndex name);
537 NameNodeResult newThisName();
538 NameNodeResult newNewTargetName();
539 NameNodeResult newDotGeneratorName();
541 NameNodeResult identifierReference(TaggedParserAtomIndex name);
542 NameNodeResult privateNameReference(TaggedParserAtomIndex name);
544 NodeResult noSubstitutionTaggedTemplate();
546 inline bool processExport(Node node);
547 inline bool processExportFrom(BinaryNodeType node);
548 inline bool processImport(BinaryNodeType node);
550 // If ParseHandler is SyntaxParseHandler:
551 // Do nothing.
552 // If ParseHandler is FullParseHandler:
553 // Disable syntax parsing of all future inner functions during this
554 // full-parse.
555 inline void disableSyntaxParser();
557 // If ParseHandler is SyntaxParseHandler:
558 // Flag the current syntax parse as aborted due to unsupported language
559 // constructs and return false. Aborting the current syntax parse does
560 // not disable attempts to syntax-parse future inner functions.
561 // If ParseHandler is FullParseHandler:
562 // Disable syntax parsing of all future inner functions and return true.
563 inline bool abortIfSyntaxParser();
565 // If ParseHandler is SyntaxParseHandler:
566 // Return whether the last syntax parse was aborted due to unsupported
567 // language constructs.
568 // If ParseHandler is FullParseHandler:
569 // Return false.
570 inline bool hadAbortedSyntaxParse();
572 // If ParseHandler is SyntaxParseHandler:
573 // Clear whether the last syntax parse was aborted.
574 // If ParseHandler is FullParseHandler:
575 // Do nothing.
576 inline void clearAbortedSyntaxParse();
578 public:
579 FunctionBox* newFunctionBox(FunctionNodeType funNode,
580 TaggedParserAtomIndex explicitName,
581 FunctionFlags flags, uint32_t toStringStart,
582 Directives directives,
583 GeneratorKind generatorKind,
584 FunctionAsyncKind asyncKind);
586 FunctionBox* newFunctionBox(FunctionNodeType funNode,
587 const ScriptStencil& cachedScriptData,
588 const ScriptStencilExtra& cachedScriptExtra);
590 public:
591 // ErrorReportMixin.
593 using Base::error;
594 using Base::errorAt;
595 using Base::errorNoOffset;
596 using Base::errorWithNotes;
597 using Base::errorWithNotesAt;
598 using Base::errorWithNotesNoOffset;
599 using Base::strictModeError;
600 using Base::strictModeErrorAt;
601 using Base::strictModeErrorNoOffset;
602 using Base::strictModeErrorWithNotes;
603 using Base::strictModeErrorWithNotesAt;
604 using Base::strictModeErrorWithNotesNoOffset;
605 using Base::warning;
606 using Base::warningAt;
607 using Base::warningNoOffset;
610 #define ABORTED_SYNTAX_PARSE_SENTINEL reinterpret_cast<void*>(0x1)
612 template <>
613 inline void PerHandlerParser<SyntaxParseHandler>::disableSyntaxParser() {}
615 template <>
616 inline bool PerHandlerParser<SyntaxParseHandler>::abortIfSyntaxParser() {
617 internalSyntaxParser_ = ABORTED_SYNTAX_PARSE_SENTINEL;
618 return false;
621 template <>
622 inline bool PerHandlerParser<SyntaxParseHandler>::hadAbortedSyntaxParse() {
623 return internalSyntaxParser_ == ABORTED_SYNTAX_PARSE_SENTINEL;
626 template <>
627 inline void PerHandlerParser<SyntaxParseHandler>::clearAbortedSyntaxParse() {
628 internalSyntaxParser_ = nullptr;
631 #undef ABORTED_SYNTAX_PARSE_SENTINEL
633 // Disable syntax parsing of all future inner functions during this
634 // full-parse.
635 template <>
636 inline void PerHandlerParser<FullParseHandler>::disableSyntaxParser() {
637 internalSyntaxParser_ = nullptr;
640 template <>
641 inline bool PerHandlerParser<FullParseHandler>::abortIfSyntaxParser() {
642 disableSyntaxParser();
643 return true;
646 template <>
647 inline bool PerHandlerParser<FullParseHandler>::hadAbortedSyntaxParse() {
648 return false;
651 template <>
652 inline void PerHandlerParser<FullParseHandler>::clearAbortedSyntaxParse() {}
654 template <class Parser>
655 class ParserAnyCharsAccess {
656 public:
657 using TokenStreamSpecific = typename Parser::TokenStream;
658 using GeneralTokenStreamChars =
659 typename TokenStreamSpecific::GeneralCharsBase;
661 static inline TokenStreamAnyChars& anyChars(GeneralTokenStreamChars* ts);
662 static inline const TokenStreamAnyChars& anyChars(
663 const GeneralTokenStreamChars* ts);
666 // Specify a value for an ES6 grammar parametrization. We have no enum for
667 // [Return] because its behavior is almost exactly equivalent to checking
668 // whether we're in a function box -- easier and simpler than passing an extra
669 // parameter everywhere.
670 enum YieldHandling { YieldIsName, YieldIsKeyword };
671 enum InHandling { InAllowed, InProhibited };
672 enum DefaultHandling { NameRequired, AllowDefaultName };
673 enum TripledotHandling { TripledotAllowed, TripledotProhibited };
675 // For Ergonomic brand checks.
676 enum PrivateNameHandling { PrivateNameProhibited, PrivateNameAllowed };
678 template <class ParseHandler, typename Unit>
679 class Parser;
681 template <class ParseHandler, typename Unit>
682 class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
683 public:
684 using TokenStream =
685 TokenStreamSpecific<Unit, ParserAnyCharsAccess<GeneralParser>>;
687 private:
688 using Base = PerHandlerParser<ParseHandler>;
689 using FinalParser = Parser<ParseHandler, Unit>;
690 using Node = typename ParseHandler::Node;
691 using NodeResult = typename ParseHandler::NodeResult;
693 #define DECLARE_TYPE(typeName) \
694 using typeName##Type = typename ParseHandler::typeName##Type; \
695 using typeName##Result = typename ParseHandler::typeName##Result;
696 FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
697 #undef DECLARE_TYPE
699 using typename Base::InvokedPrediction;
700 using SyntaxParser = Parser<SyntaxParseHandler, Unit>;
702 protected:
703 using Modifier = TokenStreamShared::Modifier;
704 using Position = typename TokenStream::Position;
706 using Base::PredictInvoked;
707 using Base::PredictUninvoked;
709 using Base::alloc_;
710 using Base::awaitIsDisallowed;
711 using Base::awaitIsKeyword;
712 using Base::inParametersOfAsyncFunction;
713 using Base::parseGoal;
714 #if DEBUG
715 using Base::checkOptionsCalled_;
716 #endif
717 using Base::checkForUndefinedPrivateFields;
718 using Base::errorResult;
719 using Base::finishClassBodyScope;
720 using Base::finishFunctionScopes;
721 using Base::finishLexicalScope;
722 using Base::foldConstants_;
723 using Base::getFilename;
724 using Base::hasValidSimpleStrictParameterNames;
725 using Base::isUnexpectedEOF_;
726 using Base::nameIsArgumentsOrEval;
727 using Base::newDotGeneratorName;
728 using Base::newFunctionBox;
729 using Base::newName;
730 using Base::null;
731 using Base::options;
732 using Base::pos;
733 using Base::propagateFreeNamesAndMarkClosedOverBindings;
734 using Base::setLocalStrictMode;
735 using Base::stringLiteral;
736 using Base::yieldExpressionsSupported;
738 using Base::abortIfSyntaxParser;
739 using Base::clearAbortedSyntaxParse;
740 using Base::disableSyntaxParser;
741 using Base::hadAbortedSyntaxParse;
743 public:
744 // Implement ErrorReportMixin.
746 [[nodiscard]] bool computeErrorMetadata(
747 ErrorMetadata* err,
748 const ErrorReportMixin::ErrorOffset& offset) const override;
750 using Base::error;
751 using Base::errorAt;
752 using Base::errorNoOffset;
753 using Base::errorWithNotes;
754 using Base::errorWithNotesAt;
755 using Base::errorWithNotesNoOffset;
756 using Base::strictModeError;
757 using Base::strictModeErrorAt;
758 using Base::strictModeErrorNoOffset;
759 using Base::strictModeErrorWithNotes;
760 using Base::strictModeErrorWithNotesAt;
761 using Base::strictModeErrorWithNotesNoOffset;
762 using Base::warning;
763 using Base::warningAt;
764 using Base::warningNoOffset;
766 public:
767 using Base::anyChars;
768 using Base::fc_;
769 using Base::handler_;
770 using Base::noteUsedName;
771 using Base::pc_;
772 using Base::usedNames_;
774 private:
775 using Base::checkAndMarkSuperScope;
776 using Base::finishFunction;
777 using Base::identifierReference;
778 using Base::leaveInnerFunction;
779 using Base::newInternalDotName;
780 using Base::newNewTargetName;
781 using Base::newThisName;
782 using Base::nextTokenContinuesLetDeclaration;
783 using Base::noSubstitutionTaggedTemplate;
784 using Base::noteDestructuredPositionalFormalParameter;
785 using Base::prefixAccessorName;
786 using Base::privateNameReference;
787 using Base::processExport;
788 using Base::processExportFrom;
789 using Base::processImport;
790 using Base::setFunctionEndFromCurrentToken;
792 private:
793 inline FinalParser* asFinalParser();
794 inline const FinalParser* asFinalParser() const;
797 * A class for temporarily stashing errors while parsing continues.
799 * The ability to stash an error is useful for handling situations where we
800 * aren't able to verify that an error has occurred until later in the parse.
801 * For instance | ({x=1}) | is always parsed as an object literal with
802 * a SyntaxError, however, in the case where it is followed by '=>' we rewind
803 * and reparse it as a valid arrow function. Here a PossibleError would be
804 * set to 'pending' when the initial SyntaxError was encountered then
805 * 'resolved' just before rewinding the parser.
807 * There are currently two kinds of PossibleErrors: Expression and
808 * Destructuring errors. Expression errors are used to mark a possible
809 * syntax error when a grammar production is used in an expression context.
810 * For example in |{x = 1}|, we mark the CoverInitializedName |x = 1| as a
811 * possible expression error, because CoverInitializedName productions
812 * are disallowed when an actual ObjectLiteral is expected.
813 * Destructuring errors are used to record possible syntax errors in
814 * destructuring contexts. For example in |[...rest, ] = []|, we initially
815 * mark the trailing comma after the spread expression as a possible
816 * destructuring error, because the ArrayAssignmentPattern grammar
817 * production doesn't allow a trailing comma after the rest element.
819 * When using PossibleError one should set a pending error at the location
820 * where an error occurs. From that point, the error may be resolved
821 * (invalidated) or left until the PossibleError is checked.
823 * Ex:
824 * PossibleError possibleError(*this);
825 * possibleError.setPendingExpressionErrorAt(pos, JSMSG_BAD_PROP_ID);
826 * // A JSMSG_BAD_PROP_ID ParseError is reported, returns false.
827 * if (!possibleError.checkForExpressionError()) {
828 * return false; // we reach this point with a pending exception
831 * PossibleError possibleError(*this);
832 * possibleError.setPendingExpressionErrorAt(pos, JSMSG_BAD_PROP_ID);
833 * // Returns true, no error is reported.
834 * if (!possibleError.checkForDestructuringError()) {
835 * return false; // not reached, no pending exception
838 * PossibleError possibleError(*this);
839 * // Returns true, no error is reported.
840 * if (!possibleError.checkForExpressionError()) {
841 * return false; // not reached, no pending exception
844 class MOZ_STACK_CLASS PossibleError {
845 private:
846 enum class ErrorKind { Expression, Destructuring, DestructuringWarning };
848 enum class ErrorState { None, Pending };
850 struct Error {
851 ErrorState state_ = ErrorState::None;
853 // Error reporting fields.
854 uint32_t offset_;
855 unsigned errorNumber_;
858 GeneralParser<ParseHandler, Unit>& parser_;
859 Error exprError_;
860 Error destructuringError_;
861 Error destructuringWarning_;
863 // Returns the error report.
864 Error& error(ErrorKind kind);
866 // Return true if an error is pending without reporting.
867 bool hasError(ErrorKind kind);
869 // Resolve any pending error.
870 void setResolved(ErrorKind kind);
872 // Set a pending error. Only a single error may be set per instance and
873 // error kind.
874 void setPending(ErrorKind kind, const TokenPos& pos, unsigned errorNumber);
876 // If there is a pending error, report it and return false, otherwise
877 // return true.
878 [[nodiscard]] bool checkForError(ErrorKind kind);
880 // Transfer an existing error to another instance.
881 void transferErrorTo(ErrorKind kind, PossibleError* other);
883 public:
884 explicit PossibleError(GeneralParser<ParseHandler, Unit>& parser);
886 // Return true if a pending destructuring error is present.
887 bool hasPendingDestructuringError();
889 // Set a pending destructuring error. Only a single error may be set
890 // per instance, i.e. subsequent calls to this method are ignored and
891 // won't overwrite the existing pending error.
892 void setPendingDestructuringErrorAt(const TokenPos& pos,
893 unsigned errorNumber);
895 // Set a pending destructuring warning. Only a single warning may be
896 // set per instance, i.e. subsequent calls to this method are ignored
897 // and won't overwrite the existing pending warning.
898 void setPendingDestructuringWarningAt(const TokenPos& pos,
899 unsigned errorNumber);
901 // Set a pending expression error. Only a single error may be set per
902 // instance, i.e. subsequent calls to this method are ignored and won't
903 // overwrite the existing pending error.
904 void setPendingExpressionErrorAt(const TokenPos& pos, unsigned errorNumber);
906 // If there is a pending destructuring error or warning, report it and
907 // return false, otherwise return true. Clears any pending expression
908 // error.
909 [[nodiscard]] bool checkForDestructuringErrorOrWarning();
911 // If there is a pending expression error, report it and return false,
912 // otherwise return true. Clears any pending destructuring error or
913 // warning.
914 [[nodiscard]] bool checkForExpressionError();
916 // Pass pending errors between possible error instances. This is useful
917 // for extending the lifetime of a pending error beyond the scope of
918 // the PossibleError where it was initially set (keeping in mind that
919 // PossibleError is a MOZ_STACK_CLASS).
920 void transferErrorsTo(PossibleError* other);
923 protected:
924 SyntaxParser* getSyntaxParser() const {
925 return reinterpret_cast<SyntaxParser*>(Base::internalSyntaxParser_);
928 public:
929 TokenStream tokenStream;
931 public:
932 GeneralParser(FrontendContext* fc, const JS::ReadOnlyCompileOptions& options,
933 const Unit* units, size_t length, bool foldConstants,
934 CompilationState& compilationState, SyntaxParser* syntaxParser);
936 inline void setAwaitHandling(AwaitHandling awaitHandling);
937 inline void setInParametersOfAsyncFunction(bool inParameters);
940 * Parse a top-level JS script.
942 ListNodeResult parse();
944 private:
946 * Gets the next token and checks if it matches to the given `condition`.
947 * If it matches, returns true.
948 * If it doesn't match, calls `errorReport` to report the error, and
949 * returns false.
950 * If other error happens, it returns false but `errorReport` may not be
951 * called and other error will be thrown in that case.
953 * In any case, the already gotten token is not ungotten.
955 * The signature of `condition` is [...](TokenKind actual) -> bool, and
956 * the signature of `errorReport` is [...](TokenKind actual).
958 template <typename ConditionT, typename ErrorReportT>
959 [[nodiscard]] bool mustMatchTokenInternal(ConditionT condition,
960 ErrorReportT errorReport);
962 public:
964 * The following mustMatchToken variants follow the behavior and parameter
965 * types of mustMatchTokenInternal above.
967 * If modifier is omitted, `SlashIsDiv` is used.
968 * If TokenKind is passed instead of `condition`, it checks if the next
969 * token is the passed token.
970 * If error number is passed instead of `errorReport`, it reports an
971 * error with the passed errorNumber.
973 [[nodiscard]] bool mustMatchToken(TokenKind expected, JSErrNum errorNumber) {
974 return mustMatchTokenInternal(
975 [expected](TokenKind actual) { return actual == expected; },
976 [this, errorNumber](TokenKind) { this->error(errorNumber); });
979 template <typename ConditionT>
980 [[nodiscard]] bool mustMatchToken(ConditionT condition,
981 JSErrNum errorNumber) {
982 return mustMatchTokenInternal(condition, [this, errorNumber](TokenKind) {
983 this->error(errorNumber);
987 template <typename ErrorReportT>
988 [[nodiscard]] bool mustMatchToken(TokenKind expected,
989 ErrorReportT errorReport) {
990 return mustMatchTokenInternal(
991 [expected](TokenKind actual) { return actual == expected; },
992 errorReport);
995 private:
996 NameNodeResult noSubstitutionUntaggedTemplate();
997 ListNodeResult templateLiteral(YieldHandling yieldHandling);
998 bool taggedTemplate(YieldHandling yieldHandling, ListNodeType tagArgsList,
999 TokenKind tt);
1000 bool appendToCallSiteObj(CallSiteNodeType callSiteObj);
1001 bool addExprAndGetNextTemplStrToken(YieldHandling yieldHandling,
1002 ListNodeType nodeList, TokenKind* ttp);
1004 inline bool trySyntaxParseInnerFunction(
1005 FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
1006 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
1007 YieldHandling yieldHandling, FunctionSyntaxKind kind,
1008 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
1009 Directives inheritedDirectives, Directives* newDirectives);
1011 inline bool skipLazyInnerFunction(FunctionNodeType funNode,
1012 uint32_t toStringStart, bool tryAnnexB);
1014 void setFunctionStartAtPosition(FunctionBox* funbox, TokenPos pos) const;
1015 void setFunctionStartAtCurrentToken(FunctionBox* funbox) const;
1017 public:
1018 /* Public entry points for parsing. */
1019 NodeResult statementListItem(YieldHandling yieldHandling,
1020 bool canHaveDirectives = false);
1022 // Parse an inner function given an enclosing ParseContext and a
1023 // FunctionBox for the inner function.
1024 [[nodiscard]] FunctionNodeResult innerFunctionForFunctionBox(
1025 FunctionNodeType funNode, ParseContext* outerpc, FunctionBox* funbox,
1026 InHandling inHandling, YieldHandling yieldHandling,
1027 FunctionSyntaxKind kind, Directives* newDirectives);
1029 // Parse a function's formal parameters and its body assuming its function
1030 // ParseContext is already on the stack.
1031 bool functionFormalParametersAndBody(
1032 InHandling inHandling, YieldHandling yieldHandling,
1033 FunctionNodeType* funNode, FunctionSyntaxKind kind,
1034 const mozilla::Maybe<uint32_t>& parameterListEnd = mozilla::Nothing(),
1035 bool isStandaloneFunction = false);
1037 private:
1039 * JS parsers, from lowest to highest precedence.
1041 * Each parser must be called during the dynamic scope of a ParseContext
1042 * object, pointed to by this->pc_.
1044 * Each returns a parse node tree or null on error.
1046 FunctionNodeResult functionStmt(
1047 uint32_t toStringStart, YieldHandling yieldHandling,
1048 DefaultHandling defaultHandling,
1049 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction);
1050 FunctionNodeResult functionExpr(uint32_t toStringStart,
1051 InvokedPrediction invoked,
1052 FunctionAsyncKind asyncKind);
1054 NodeResult statement(YieldHandling yieldHandling);
1055 bool maybeParseDirective(ListNodeType list, Node pn, bool* cont);
1057 LexicalScopeNodeResult blockStatement(
1058 YieldHandling yieldHandling,
1059 unsigned errorNumber = JSMSG_CURLY_IN_COMPOUND);
1060 BinaryNodeResult doWhileStatement(YieldHandling yieldHandling);
1061 BinaryNodeResult whileStatement(YieldHandling yieldHandling);
1063 NodeResult forStatement(YieldHandling yieldHandling);
1064 bool forHeadStart(YieldHandling yieldHandling, IteratorKind iterKind,
1065 ParseNodeKind* forHeadKind, Node* forInitialPart,
1066 mozilla::Maybe<ParseContext::Scope>& forLetImpliedScope,
1067 Node* forInOrOfExpression);
1068 NodeResult expressionAfterForInOrOf(ParseNodeKind forHeadKind,
1069 YieldHandling yieldHandling);
1071 SwitchStatementResult switchStatement(YieldHandling yieldHandling);
1072 ContinueStatementResult continueStatement(YieldHandling yieldHandling);
1073 BreakStatementResult breakStatement(YieldHandling yieldHandling);
1074 UnaryNodeResult returnStatement(YieldHandling yieldHandling);
1075 BinaryNodeResult withStatement(YieldHandling yieldHandling);
1076 UnaryNodeResult throwStatement(YieldHandling yieldHandling);
1077 TernaryNodeResult tryStatement(YieldHandling yieldHandling);
1078 LexicalScopeNodeResult catchBlockStatement(
1079 YieldHandling yieldHandling, ParseContext::Scope& catchParamScope);
1080 DebuggerStatementResult debuggerStatement();
1082 DeclarationListNodeResult variableStatement(YieldHandling yieldHandling);
1084 LabeledStatementResult labeledStatement(YieldHandling yieldHandling);
1085 NodeResult labeledItem(YieldHandling yieldHandling);
1087 TernaryNodeResult ifStatement(YieldHandling yieldHandling);
1088 NodeResult consequentOrAlternative(YieldHandling yieldHandling);
1090 DeclarationListNodeResult lexicalDeclaration(YieldHandling yieldHandling,
1091 DeclarationKind kind);
1093 NameNodeResult moduleExportName();
1095 bool assertClause(ListNodeType assertionsSet);
1097 BinaryNodeResult importDeclaration();
1098 NodeResult importDeclarationOrImportExpr(YieldHandling yieldHandling);
1099 bool namedImports(ListNodeType importSpecSet);
1100 bool namespaceImport(ListNodeType importSpecSet);
1102 TaggedParserAtomIndex importedBinding() {
1103 return bindingIdentifier(YieldIsName);
1106 BinaryNodeResult exportFrom(uint32_t begin, Node specList);
1107 BinaryNodeResult exportBatch(uint32_t begin);
1108 inline bool checkLocalExportNames(ListNodeType node);
1109 NodeResult exportClause(uint32_t begin);
1110 UnaryNodeResult exportFunctionDeclaration(
1111 uint32_t begin, uint32_t toStringStart,
1112 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction);
1113 UnaryNodeResult exportVariableStatement(uint32_t begin);
1114 UnaryNodeResult exportClassDeclaration(uint32_t begin);
1115 UnaryNodeResult exportLexicalDeclaration(uint32_t begin,
1116 DeclarationKind kind);
1117 BinaryNodeResult exportDefaultFunctionDeclaration(
1118 uint32_t begin, uint32_t toStringStart,
1119 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction);
1120 BinaryNodeResult exportDefaultClassDeclaration(uint32_t begin);
1121 BinaryNodeResult exportDefaultAssignExpr(uint32_t begin);
1122 BinaryNodeResult exportDefault(uint32_t begin);
1123 NodeResult exportDeclaration();
1125 UnaryNodeResult expressionStatement(
1126 YieldHandling yieldHandling,
1127 InvokedPrediction invoked = PredictUninvoked);
1129 // Declaration parsing. The main entrypoint is Parser::declarationList,
1130 // with sub-functionality split out into the remaining methods.
1132 // |blockScope| may be non-null only when |kind| corresponds to a lexical
1133 // declaration (that is, ParseNodeKind::LetDecl or ParseNodeKind::ConstDecl).
1135 // The for* parameters, for normal declarations, should be null/ignored.
1136 // They should be non-null only when Parser::forHeadStart parses a
1137 // declaration at the start of a for-loop head.
1139 // In this case, on success |*forHeadKind| is ParseNodeKind::ForHead,
1140 // ParseNodeKind::ForIn, or ParseNodeKind::ForOf, corresponding to the three
1141 // for-loop kinds. The precise value indicates what was parsed.
1143 // If parsing recognized a for(;;) loop, the next token is the ';' within
1144 // the loop-head that separates the init/test parts.
1146 // Otherwise, for for-in/of loops, the next token is the ')' ending the
1147 // loop-head. Additionally, the expression that the loop iterates over was
1148 // parsed into |*forInOrOfExpression|.
1149 DeclarationListNodeResult declarationList(
1150 YieldHandling yieldHandling, ParseNodeKind kind,
1151 ParseNodeKind* forHeadKind = nullptr,
1152 Node* forInOrOfExpression = nullptr);
1154 // The items in a declaration list are either patterns or names, with or
1155 // without initializers. These two methods parse a single pattern/name and
1156 // any associated initializer -- and if parsing an |initialDeclaration|
1157 // will, if parsing in a for-loop head (as specified by |forHeadKind| being
1158 // non-null), consume additional tokens up to the closing ')' in a
1159 // for-in/of loop head, returning the iterated expression in
1160 // |*forInOrOfExpression|. (An "initial declaration" is the first
1161 // declaration in a declaration list: |a| but not |b| in |var a, b|, |{c}|
1162 // but not |d| in |let {c} = 3, d|.)
1163 NodeResult declarationPattern(DeclarationKind declKind, TokenKind tt,
1164 bool initialDeclaration,
1165 YieldHandling yieldHandling,
1166 ParseNodeKind* forHeadKind,
1167 Node* forInOrOfExpression);
1168 NodeResult declarationName(DeclarationKind declKind, TokenKind tt,
1169 bool initialDeclaration,
1170 YieldHandling yieldHandling,
1171 ParseNodeKind* forHeadKind,
1172 Node* forInOrOfExpression);
1174 // Having parsed a name (not found in a destructuring pattern) declared by
1175 // a declaration, with the current token being the '=' separating the name
1176 // from its initializer, parse and bind that initializer -- and possibly
1177 // consume trailing in/of and subsequent expression, if so directed by
1178 // |forHeadKind|.
1179 AssignmentNodeResult initializerInNameDeclaration(NameNodeType binding,
1180 DeclarationKind declKind,
1181 bool initialDeclaration,
1182 YieldHandling yieldHandling,
1183 ParseNodeKind* forHeadKind,
1184 Node* forInOrOfExpression);
1186 NodeResult expr(InHandling inHandling, YieldHandling yieldHandling,
1187 TripledotHandling tripledotHandling,
1188 PossibleError* possibleError = nullptr,
1189 InvokedPrediction invoked = PredictUninvoked);
1190 NodeResult assignExpr(InHandling inHandling, YieldHandling yieldHandling,
1191 TripledotHandling tripledotHandling,
1192 PossibleError* possibleError = nullptr,
1193 InvokedPrediction invoked = PredictUninvoked);
1194 NodeResult assignExprWithoutYieldOrAwait(YieldHandling yieldHandling);
1195 UnaryNodeResult yieldExpression(InHandling inHandling);
1196 NodeResult condExpr(InHandling inHandling, YieldHandling yieldHandling,
1197 TripledotHandling tripledotHandling,
1198 PossibleError* possibleError, InvokedPrediction invoked);
1199 NodeResult orExpr(InHandling inHandling, YieldHandling yieldHandling,
1200 TripledotHandling tripledotHandling,
1201 PossibleError* possibleError, InvokedPrediction invoked);
1202 NodeResult unaryExpr(YieldHandling yieldHandling,
1203 TripledotHandling tripledotHandling,
1204 PossibleError* possibleError = nullptr,
1205 InvokedPrediction invoked = PredictUninvoked,
1206 PrivateNameHandling privateNameHandling =
1207 PrivateNameHandling::PrivateNameProhibited);
1208 NodeResult optionalExpr(YieldHandling yieldHandling,
1209 TripledotHandling tripledotHandling, TokenKind tt,
1210 PossibleError* possibleError = nullptr,
1211 InvokedPrediction invoked = PredictUninvoked);
1212 NodeResult memberExpr(YieldHandling yieldHandling,
1213 TripledotHandling tripledotHandling, TokenKind tt,
1214 bool allowCallSyntax, PossibleError* possibleError,
1215 InvokedPrediction invoked);
1216 NodeResult decoratorExpr(YieldHandling yieldHandling, TokenKind tt);
1217 NodeResult primaryExpr(YieldHandling yieldHandling,
1218 TripledotHandling tripledotHandling, TokenKind tt,
1219 PossibleError* possibleError,
1220 InvokedPrediction invoked);
1221 NodeResult exprInParens(InHandling inHandling, YieldHandling yieldHandling,
1222 TripledotHandling tripledotHandling,
1223 PossibleError* possibleError = nullptr);
1225 bool tryNewTarget(NewTargetNodeType* newTarget);
1227 BinaryNodeResult importExpr(YieldHandling yieldHandling,
1228 bool allowCallSyntax);
1230 FunctionNodeResult methodDefinition(uint32_t toStringStart,
1231 PropertyType propType,
1232 TaggedParserAtomIndex funName);
1235 * Additional JS parsers.
1237 bool functionArguments(YieldHandling yieldHandling, FunctionSyntaxKind kind,
1238 FunctionNodeType funNode);
1240 FunctionNodeResult functionDefinition(
1241 FunctionNodeType funNode, uint32_t toStringStart, InHandling inHandling,
1242 YieldHandling yieldHandling, TaggedParserAtomIndex name,
1243 FunctionSyntaxKind kind, GeneratorKind generatorKind,
1244 FunctionAsyncKind asyncKind, bool tryAnnexB = false);
1246 // Parse a function body. Pass StatementListBody if the body is a list of
1247 // statements; pass ExpressionBody if the body is a single expression.
1249 // Don't include opening LeftCurly token when invoking.
1250 enum FunctionBodyType { StatementListBody, ExpressionBody };
1251 LexicalScopeNodeResult functionBody(InHandling inHandling,
1252 YieldHandling yieldHandling,
1253 FunctionSyntaxKind kind,
1254 FunctionBodyType type);
1256 UnaryNodeResult unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind,
1257 uint32_t begin);
1259 NodeResult condition(InHandling inHandling, YieldHandling yieldHandling);
1261 ListNodeResult argumentList(YieldHandling yieldHandling, bool* isSpread,
1262 PossibleError* possibleError = nullptr);
1263 NodeResult destructuringDeclaration(DeclarationKind kind,
1264 YieldHandling yieldHandling,
1265 TokenKind tt);
1266 NodeResult destructuringDeclarationWithoutYieldOrAwait(
1267 DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt);
1269 inline bool checkExportedName(TaggedParserAtomIndex exportName);
1270 inline bool checkExportedNamesForArrayBinding(ListNodeType array);
1271 inline bool checkExportedNamesForObjectBinding(ListNodeType obj);
1272 inline bool checkExportedNamesForDeclaration(Node node);
1273 inline bool checkExportedNamesForDeclarationList(
1274 DeclarationListNodeType node);
1275 inline bool checkExportedNameForFunction(FunctionNodeType funNode);
1276 inline bool checkExportedNameForClass(ClassNodeType classNode);
1277 inline bool checkExportedNameForClause(NameNodeType nameNode);
1279 enum ClassContext { ClassStatement, ClassExpression };
1280 ClassNodeResult classDefinition(YieldHandling yieldHandling,
1281 ClassContext classContext,
1282 DefaultHandling defaultHandling);
1284 struct ClassInitializedMembers {
1285 // The number of instance class fields.
1286 size_t instanceFields = 0;
1288 // The number of instance class fields with computed property names.
1289 size_t instanceFieldKeys = 0;
1291 // The number of static class fields.
1292 size_t staticFields = 0;
1294 // The number of static blocks
1295 size_t staticBlocks = 0;
1297 // The number of static class fields with computed property names.
1298 size_t staticFieldKeys = 0;
1300 // The number of instance class private methods.
1301 size_t privateMethods = 0;
1303 // The number of instance class private accessors.
1304 size_t privateAccessors = 0;
1306 bool hasPrivateBrand() const {
1307 return privateMethods > 0 || privateAccessors > 0;
1310 #ifdef ENABLE_DECORATORS
1311 ListNodeResult decoratorList(YieldHandling yieldHandling);
1312 #endif
1313 [[nodiscard]] bool classMember(
1314 YieldHandling yieldHandling,
1315 const ParseContext::ClassStatement& classStmt,
1316 TaggedParserAtomIndex className, uint32_t classStartOffset,
1317 HasHeritage hasHeritage, ClassInitializedMembers& classInitializedMembers,
1318 ListNodeType& classMembers, bool* done);
1319 [[nodiscard]] bool finishClassConstructor(
1320 const ParseContext::ClassStatement& classStmt,
1321 TaggedParserAtomIndex className, HasHeritage hasHeritage,
1322 uint32_t classStartOffset, uint32_t classEndOffset,
1323 const ClassInitializedMembers& classInitializedMembers,
1324 ListNodeType& classMembers);
1326 FunctionNodeResult privateMethodInitializer(
1327 TokenPos propNamePos, TaggedParserAtomIndex propAtom,
1328 TaggedParserAtomIndex storedMethodAtom);
1329 FunctionNodeResult fieldInitializerOpt(
1330 TokenPos propNamePos, Node name, TaggedParserAtomIndex atom,
1331 ClassInitializedMembers& classInitializedMembers, bool isStatic,
1332 HasHeritage hasHeritage);
1334 FunctionNodeResult synthesizePrivateMethodInitializer(
1335 TaggedParserAtomIndex propAtom, AccessorType accessorType,
1336 TokenPos propNamePos);
1338 #ifdef ENABLE_DECORATORS
1339 ClassMethodResult synthesizeAccessor(
1340 Node propName, TokenPos propNamePos, TaggedParserAtomIndex propAtom,
1341 TaggedParserAtomIndex privateStateNameAtom, bool isStatic,
1342 FunctionSyntaxKind syntaxKind,
1343 ClassInitializedMembers& classInitializedMembers);
1345 FunctionNodeResult synthesizeAccessorBody(TaggedParserAtomIndex funNameAtom,
1346 TokenPos propNamePos,
1347 TaggedParserAtomIndex propNameAtom,
1348 FunctionSyntaxKind syntaxKind);
1349 #endif
1351 FunctionNodeResult staticClassBlock(
1352 ClassInitializedMembers& classInitializedMembers);
1354 FunctionNodeResult synthesizeConstructor(TaggedParserAtomIndex className,
1355 TokenPos synthesizedBodyPos,
1356 HasHeritage hasHeritage);
1358 protected:
1359 bool synthesizeConstructorBody(TokenPos synthesizedBodyPos,
1360 HasHeritage hasHeritage,
1361 FunctionNodeType funNode, FunctionBox* funbox);
1363 private:
1364 bool checkBindingIdentifier(TaggedParserAtomIndex ident, uint32_t offset,
1365 YieldHandling yieldHandling,
1366 TokenKind hint = TokenKind::Limit);
1368 TaggedParserAtomIndex labelOrIdentifierReference(YieldHandling yieldHandling);
1370 TaggedParserAtomIndex labelIdentifier(YieldHandling yieldHandling) {
1371 return labelOrIdentifierReference(yieldHandling);
1374 TaggedParserAtomIndex identifierReference(YieldHandling yieldHandling) {
1375 return labelOrIdentifierReference(yieldHandling);
1378 bool matchLabel(YieldHandling yieldHandling, TaggedParserAtomIndex* labelOut);
1380 // Indicate if the next token (tokenized with SlashIsRegExp) is |in| or |of|.
1381 // If so, consume it.
1382 bool matchInOrOf(bool* isForInp, bool* isForOfp);
1384 private:
1385 bool checkIncDecOperand(Node operand, uint32_t operandOffset);
1386 bool checkStrictAssignment(Node lhs);
1388 void reportMissingClosing(unsigned errorNumber, unsigned noteNumber,
1389 uint32_t openedPos);
1391 void reportRedeclarationHelper(TaggedParserAtomIndex& name,
1392 DeclarationKind& prevKind, TokenPos& pos,
1393 uint32_t& prevPos, const unsigned& errorNumber,
1394 const unsigned& noteErrorNumber);
1396 void reportRedeclaration(TaggedParserAtomIndex name, DeclarationKind prevKind,
1397 TokenPos pos, uint32_t prevPos);
1399 void reportMismatchedPlacement(TaggedParserAtomIndex name,
1400 DeclarationKind prevKind, TokenPos pos,
1401 uint32_t prevPos);
1403 bool notePositionalFormalParameter(FunctionNodeType funNode,
1404 TaggedParserAtomIndex name,
1405 uint32_t beginPos,
1406 bool disallowDuplicateParams,
1407 bool* duplicatedParam);
1409 enum PropertyNameContext {
1410 PropertyNameInLiteral,
1411 PropertyNameInPattern,
1412 PropertyNameInClass,
1413 #ifdef ENABLE_RECORD_TUPLE
1414 PropertyNameInRecord
1415 #endif
1417 NodeResult propertyName(YieldHandling yieldHandling,
1418 PropertyNameContext propertyNameContext,
1419 const mozilla::Maybe<DeclarationKind>& maybeDecl,
1420 ListNodeType propList,
1421 TaggedParserAtomIndex* propAtomOut);
1422 NodeResult propertyOrMethodName(
1423 YieldHandling yieldHandling, PropertyNameContext propertyNameContext,
1424 const mozilla::Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
1425 PropertyType* propType, TaggedParserAtomIndex* propAtomOut);
1426 UnaryNodeResult computedPropertyName(
1427 YieldHandling yieldHandling,
1428 const mozilla::Maybe<DeclarationKind>& maybeDecl,
1429 PropertyNameContext propertyNameContext, ListNodeType literal);
1430 ListNodeResult arrayInitializer(YieldHandling yieldHandling,
1431 PossibleError* possibleError);
1432 inline RegExpLiteralResult newRegExp();
1434 ListNodeResult objectLiteral(YieldHandling yieldHandling,
1435 PossibleError* possibleError);
1437 #ifdef ENABLE_RECORD_TUPLE
1438 ListNodeResult recordLiteral(YieldHandling yieldHandling);
1439 ListNodeResult tupleLiteral(YieldHandling yieldHandling);
1440 #endif
1442 BinaryNodeResult bindingInitializer(Node lhs, DeclarationKind kind,
1443 YieldHandling yieldHandling);
1444 NameNodeResult bindingIdentifier(DeclarationKind kind,
1445 YieldHandling yieldHandling);
1446 NodeResult bindingIdentifierOrPattern(DeclarationKind kind,
1447 YieldHandling yieldHandling,
1448 TokenKind tt);
1449 ListNodeResult objectBindingPattern(DeclarationKind kind,
1450 YieldHandling yieldHandling);
1451 ListNodeResult arrayBindingPattern(DeclarationKind kind,
1452 YieldHandling yieldHandling);
1454 enum class TargetBehavior {
1455 PermitAssignmentPattern,
1456 ForbidAssignmentPattern
1458 bool checkDestructuringAssignmentTarget(
1459 Node expr, TokenPos exprPos, PossibleError* exprPossibleError,
1460 PossibleError* possibleError,
1461 TargetBehavior behavior = TargetBehavior::PermitAssignmentPattern);
1462 void checkDestructuringAssignmentName(NameNodeType name, TokenPos namePos,
1463 PossibleError* possibleError);
1464 bool checkDestructuringAssignmentElement(Node expr, TokenPos exprPos,
1465 PossibleError* exprPossibleError,
1466 PossibleError* possibleError);
1468 NumericLiteralResult newNumber(const Token& tok) {
1469 return handler_.newNumber(tok.number(), tok.decimalPoint(), tok.pos);
1472 inline BigIntLiteralResult newBigInt();
1474 enum class OptionalKind {
1475 NonOptional = 0,
1476 Optional,
1478 NodeResult memberPropertyAccess(
1479 Node lhs, OptionalKind optionalKind = OptionalKind::NonOptional);
1480 NodeResult memberPrivateAccess(
1481 Node lhs, OptionalKind optionalKind = OptionalKind::NonOptional);
1482 NodeResult memberElemAccess(
1483 Node lhs, YieldHandling yieldHandling,
1484 OptionalKind optionalKind = OptionalKind::NonOptional);
1485 NodeResult memberSuperCall(Node lhs, YieldHandling yieldHandling);
1486 NodeResult memberCall(TokenKind tt, Node lhs, YieldHandling yieldHandling,
1487 PossibleError* possibleError,
1488 OptionalKind optionalKind = OptionalKind::NonOptional);
1490 protected:
1491 // Match the current token against the BindingIdentifier production with
1492 // the given Yield parameter. If there is no match, report a syntax
1493 // error.
1494 TaggedParserAtomIndex bindingIdentifier(YieldHandling yieldHandling);
1496 bool checkLabelOrIdentifierReference(TaggedParserAtomIndex ident,
1497 uint32_t offset,
1498 YieldHandling yieldHandling,
1499 TokenKind hint = TokenKind::Limit);
1501 ListNodeResult statementList(YieldHandling yieldHandling);
1503 [[nodiscard]] FunctionNodeResult innerFunction(
1504 FunctionNodeType funNode, ParseContext* outerpc,
1505 TaggedParserAtomIndex explicitName, FunctionFlags flags,
1506 uint32_t toStringStart, InHandling inHandling,
1507 YieldHandling yieldHandling, FunctionSyntaxKind kind,
1508 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
1509 Directives inheritedDirectives, Directives* newDirectives);
1511 // Implements Automatic Semicolon Insertion.
1513 // Use this to match `;` in contexts where ASI is allowed. Call this after
1514 // ruling out all other possibilities except `;`, by peeking ahead if
1515 // necessary.
1517 // Unlike most optional Modifiers, this method's `modifier` argument defaults
1518 // to SlashIsRegExp, since that's by far the most common case: usually an
1519 // optional semicolon is at the end of a statement or declaration, and the
1520 // next token could be a RegExp literal beginning a new ExpressionStatement.
1521 bool matchOrInsertSemicolon(Modifier modifier = TokenStream::SlashIsRegExp);
1523 bool noteDeclaredName(TaggedParserAtomIndex name, DeclarationKind kind,
1524 TokenPos pos, ClosedOver isClosedOver = ClosedOver::No);
1526 bool noteDeclaredPrivateName(Node nameNode, TaggedParserAtomIndex name,
1527 PropertyType propType, FieldPlacement placement,
1528 TokenPos pos);
1530 private:
1531 inline bool asmJS(ListNodeType list);
1534 template <typename Unit>
1535 class MOZ_STACK_CLASS Parser<SyntaxParseHandler, Unit> final
1536 : public GeneralParser<SyntaxParseHandler, Unit> {
1537 using Base = GeneralParser<SyntaxParseHandler, Unit>;
1538 using Node = SyntaxParseHandler::Node;
1539 using NodeResult = typename SyntaxParseHandler::NodeResult;
1541 #define DECLARE_TYPE(typeName) \
1542 using typeName##Type = SyntaxParseHandler::typeName##Type; \
1543 using typeName##Result = SyntaxParseHandler::typeName##Result;
1544 FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
1545 #undef DECLARE_TYPE
1547 using SyntaxParser = Parser<SyntaxParseHandler, Unit>;
1549 // Numerous Base::* functions have bodies like
1551 // return asFinalParser()->func(...);
1553 // and must be able to call functions here. Add a friendship relationship
1554 // so functions here can be hidden when appropriate.
1555 friend class GeneralParser<SyntaxParseHandler, Unit>;
1557 public:
1558 using Base::Base;
1560 // Inherited types, listed here to have non-dependent names.
1561 using typename Base::Modifier;
1562 using typename Base::Position;
1563 using typename Base::TokenStream;
1565 // Inherited functions, listed here to have non-dependent names.
1567 public:
1568 using Base::anyChars;
1569 using Base::clearAbortedSyntaxParse;
1570 using Base::hadAbortedSyntaxParse;
1571 using Base::innerFunctionForFunctionBox;
1572 using Base::tokenStream;
1574 public:
1575 // ErrorReportMixin.
1577 using Base::error;
1578 using Base::errorAt;
1579 using Base::errorNoOffset;
1580 using Base::errorWithNotes;
1581 using Base::errorWithNotesAt;
1582 using Base::errorWithNotesNoOffset;
1583 using Base::strictModeError;
1584 using Base::strictModeErrorAt;
1585 using Base::strictModeErrorNoOffset;
1586 using Base::strictModeErrorWithNotes;
1587 using Base::strictModeErrorWithNotesAt;
1588 using Base::strictModeErrorWithNotesNoOffset;
1589 using Base::warning;
1590 using Base::warningAt;
1591 using Base::warningNoOffset;
1593 private:
1594 using Base::alloc_;
1595 #if DEBUG
1596 using Base::checkOptionsCalled_;
1597 #endif
1598 using Base::checkForUndefinedPrivateFields;
1599 using Base::errorResult;
1600 using Base::finishFunctionScopes;
1601 using Base::functionFormalParametersAndBody;
1602 using Base::handler_;
1603 using Base::innerFunction;
1604 using Base::matchOrInsertSemicolon;
1605 using Base::mustMatchToken;
1606 using Base::newFunctionBox;
1607 using Base::newLexicalScopeData;
1608 using Base::newModuleScopeData;
1609 using Base::newName;
1610 using Base::noteDeclaredName;
1611 using Base::null;
1612 using Base::options;
1613 using Base::pc_;
1614 using Base::pos;
1615 using Base::propagateFreeNamesAndMarkClosedOverBindings;
1616 using Base::ss;
1617 using Base::statementList;
1618 using Base::stringLiteral;
1619 using Base::usedNames_;
1621 private:
1622 using Base::abortIfSyntaxParser;
1623 using Base::disableSyntaxParser;
1625 public:
1626 // Functions with multiple overloads of different visibility. We can't
1627 // |using| the whole thing into existence because of the visibility
1628 // distinction, so we instead must manually delegate the required overload.
1630 TaggedParserAtomIndex bindingIdentifier(YieldHandling yieldHandling) {
1631 return Base::bindingIdentifier(yieldHandling);
1634 // Functions present in both Parser<ParseHandler, Unit> specializations.
1636 inline void setAwaitHandling(AwaitHandling awaitHandling);
1637 inline void setInParametersOfAsyncFunction(bool inParameters);
1639 RegExpLiteralResult newRegExp();
1640 BigIntLiteralResult newBigInt();
1642 // Parse a module.
1643 ModuleNodeResult moduleBody(ModuleSharedContext* modulesc);
1645 inline bool checkLocalExportNames(ListNodeType node);
1646 inline bool checkExportedName(TaggedParserAtomIndex exportName);
1647 inline bool checkExportedNamesForArrayBinding(ListNodeType array);
1648 inline bool checkExportedNamesForObjectBinding(ListNodeType obj);
1649 inline bool checkExportedNamesForDeclaration(Node node);
1650 inline bool checkExportedNamesForDeclarationList(
1651 DeclarationListNodeType node);
1652 inline bool checkExportedNameForFunction(FunctionNodeType funNode);
1653 inline bool checkExportedNameForClass(ClassNodeType classNode);
1654 inline bool checkExportedNameForClause(NameNodeType nameNode);
1656 bool trySyntaxParseInnerFunction(
1657 FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
1658 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
1659 YieldHandling yieldHandling, FunctionSyntaxKind kind,
1660 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
1661 Directives inheritedDirectives, Directives* newDirectives);
1663 bool skipLazyInnerFunction(FunctionNodeType funNode, uint32_t toStringStart,
1664 bool tryAnnexB);
1666 bool asmJS(ListNodeType list);
1668 // Functions present only in Parser<SyntaxParseHandler, Unit>.
1671 template <typename Unit>
1672 class MOZ_STACK_CLASS Parser<FullParseHandler, Unit> final
1673 : public GeneralParser<FullParseHandler, Unit> {
1674 using Base = GeneralParser<FullParseHandler, Unit>;
1675 using Node = FullParseHandler::Node;
1676 using NodeResult = typename FullParseHandler::NodeResult;
1678 #define DECLARE_TYPE(typeName) \
1679 using typeName##Type = FullParseHandler::typeName##Type; \
1680 using typeName##Result = FullParseHandler::typeName##Result;
1681 FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
1682 #undef DECLARE_TYPE
1684 using SyntaxParser = Parser<SyntaxParseHandler, Unit>;
1686 // Numerous Base::* functions have bodies like
1688 // return asFinalParser()->func(...);
1690 // and must be able to call functions here. Add a friendship relationship
1691 // so functions here can be hidden when appropriate.
1692 friend class GeneralParser<FullParseHandler, Unit>;
1694 public:
1695 using Base::Base;
1697 // Inherited types, listed here to have non-dependent names.
1698 using typename Base::Modifier;
1699 using typename Base::Position;
1700 using typename Base::TokenStream;
1702 // Inherited functions, listed here to have non-dependent names.
1704 public:
1705 using Base::anyChars;
1706 using Base::clearAbortedSyntaxParse;
1707 using Base::functionFormalParametersAndBody;
1708 using Base::hadAbortedSyntaxParse;
1709 using Base::handler_;
1710 using Base::newFunctionBox;
1711 using Base::options;
1712 using Base::pc_;
1713 using Base::pos;
1714 using Base::ss;
1715 using Base::tokenStream;
1717 public:
1718 // ErrorReportMixin.
1720 using Base::error;
1721 using Base::errorAt;
1722 using Base::errorNoOffset;
1723 using Base::errorWithNotes;
1724 using Base::errorWithNotesAt;
1725 using Base::errorWithNotesNoOffset;
1726 using Base::strictModeError;
1727 using Base::strictModeErrorAt;
1728 using Base::strictModeErrorNoOffset;
1729 using Base::strictModeErrorWithNotes;
1730 using Base::strictModeErrorWithNotesAt;
1731 using Base::strictModeErrorWithNotesNoOffset;
1732 using Base::warning;
1733 using Base::warningAt;
1734 using Base::warningNoOffset;
1736 private:
1737 using Base::alloc_;
1738 using Base::checkLabelOrIdentifierReference;
1739 #if DEBUG
1740 using Base::checkOptionsCalled_;
1741 #endif
1742 using Base::checkForUndefinedPrivateFields;
1743 using Base::errorResult;
1744 using Base::fc_;
1745 using Base::finishClassBodyScope;
1746 using Base::finishFunctionScopes;
1747 using Base::finishLexicalScope;
1748 using Base::innerFunction;
1749 using Base::innerFunctionForFunctionBox;
1750 using Base::matchOrInsertSemicolon;
1751 using Base::mustMatchToken;
1752 using Base::newEvalScopeData;
1753 using Base::newFunctionScopeData;
1754 using Base::newGlobalScopeData;
1755 using Base::newLexicalScopeData;
1756 using Base::newModuleScopeData;
1757 using Base::newName;
1758 using Base::newVarScopeData;
1759 using Base::noteDeclaredName;
1760 using Base::noteUsedName;
1761 using Base::null;
1762 using Base::propagateFreeNamesAndMarkClosedOverBindings;
1763 using Base::statementList;
1764 using Base::stringLiteral;
1765 using Base::usedNames_;
1767 using Base::abortIfSyntaxParser;
1768 using Base::disableSyntaxParser;
1769 using Base::getSyntaxParser;
1771 public:
1772 // Functions with multiple overloads of different visibility. We can't
1773 // |using| the whole thing into existence because of the visibility
1774 // distinction, so we instead must manually delegate the required overload.
1776 TaggedParserAtomIndex bindingIdentifier(YieldHandling yieldHandling) {
1777 return Base::bindingIdentifier(yieldHandling);
1780 // Functions present in both Parser<ParseHandler, Unit> specializations.
1782 friend class AutoAwaitIsKeyword<SyntaxParseHandler, Unit>;
1783 inline void setAwaitHandling(AwaitHandling awaitHandling);
1785 friend class AutoInParametersOfAsyncFunction<SyntaxParseHandler, Unit>;
1786 inline void setInParametersOfAsyncFunction(bool inParameters);
1788 RegExpLiteralResult newRegExp();
1789 BigIntLiteralResult newBigInt();
1791 // Parse a module.
1792 ModuleNodeResult moduleBody(ModuleSharedContext* modulesc);
1794 bool checkLocalExportNames(ListNodeType node);
1795 bool checkExportedName(TaggedParserAtomIndex exportName);
1796 bool checkExportedNamesForArrayBinding(ListNodeType array);
1797 bool checkExportedNamesForObjectBinding(ListNodeType obj);
1798 bool checkExportedNamesForDeclaration(Node node);
1799 bool checkExportedNamesForDeclarationList(DeclarationListNodeType node);
1800 bool checkExportedNameForFunction(FunctionNodeType funNode);
1801 bool checkExportedNameForClass(ClassNodeType classNode);
1802 inline bool checkExportedNameForClause(NameNodeType nameNode);
1804 bool trySyntaxParseInnerFunction(
1805 FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
1806 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
1807 YieldHandling yieldHandling, FunctionSyntaxKind kind,
1808 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
1809 Directives inheritedDirectives, Directives* newDirectives);
1811 [[nodiscard]] bool advancePastSyntaxParsedFunction(
1812 SyntaxParser* syntaxParser);
1814 bool skipLazyInnerFunction(FunctionNodeType funNode, uint32_t toStringStart,
1815 bool tryAnnexB);
1817 // Functions present only in Parser<FullParseHandler, Unit>.
1819 // Parse the body of an eval.
1821 // Eval scripts are distinguished from global scripts in that in ES6, per
1822 // 18.2.1.1 steps 9 and 10, all eval scripts are executed under a fresh
1823 // lexical scope.
1824 LexicalScopeNodeResult evalBody(EvalSharedContext* evalsc);
1826 // Parse a function, given only its arguments and body. Used for lazily
1827 // parsed functions.
1828 FunctionNodeResult standaloneLazyFunction(CompilationInput& input,
1829 uint32_t toStringStart, bool strict,
1830 GeneratorKind generatorKind,
1831 FunctionAsyncKind asyncKind);
1833 // Parse a function, used for the Function, GeneratorFunction, and
1834 // AsyncFunction constructors.
1835 FunctionNodeResult standaloneFunction(
1836 const mozilla::Maybe<uint32_t>& parameterListEnd,
1837 FunctionSyntaxKind syntaxKind, GeneratorKind generatorKind,
1838 FunctionAsyncKind asyncKind, Directives inheritedDirectives,
1839 Directives* newDirectives);
1841 bool checkStatementsEOF();
1843 // Parse the body of a global script.
1844 ListNodeResult globalBody(GlobalSharedContext* globalsc);
1846 bool checkLocalExportName(TaggedParserAtomIndex ident, uint32_t offset) {
1847 return checkLabelOrIdentifierReference(ident, offset, YieldIsName);
1850 bool asmJS(ListNodeType list);
1853 template <class Parser>
1854 /* static */ inline const TokenStreamAnyChars&
1855 ParserAnyCharsAccess<Parser>::anyChars(const GeneralTokenStreamChars* ts) {
1856 // The structure we're walking through looks like this:
1858 // struct ParserBase
1859 // {
1860 // ...;
1861 // TokenStreamAnyChars anyChars;
1862 // ...;
1863 // };
1864 // struct Parser : <class that ultimately inherits from ParserBase>
1865 // {
1866 // ...;
1867 // TokenStreamSpecific tokenStream;
1868 // ...;
1869 // };
1871 // We're passed a GeneralTokenStreamChars* (this being a base class of
1872 // Parser::tokenStream). We cast that pointer to a TokenStreamSpecific*,
1873 // then translate that to the enclosing Parser*, then return the |anyChars|
1874 // member within.
1876 static_assert(std::is_base_of_v<GeneralTokenStreamChars, TokenStreamSpecific>,
1877 "the static_cast<> below assumes a base-class relationship");
1878 const auto* tss = static_cast<const TokenStreamSpecific*>(ts);
1880 auto tssAddr = reinterpret_cast<uintptr_t>(tss);
1882 using ActualTokenStreamType = decltype(std::declval<Parser>().tokenStream);
1883 static_assert(std::is_same_v<ActualTokenStreamType, TokenStreamSpecific>,
1884 "Parser::tokenStream must have type TokenStreamSpecific");
1886 uintptr_t parserAddr = tssAddr - offsetof(Parser, tokenStream);
1888 return reinterpret_cast<const Parser*>(parserAddr)->anyChars;
1891 template <class Parser>
1892 /* static */ inline TokenStreamAnyChars& ParserAnyCharsAccess<Parser>::anyChars(
1893 GeneralTokenStreamChars* ts) {
1894 const TokenStreamAnyChars& anyCharsConst =
1895 anyChars(const_cast<const GeneralTokenStreamChars*>(ts));
1897 return const_cast<TokenStreamAnyChars&>(anyCharsConst);
1900 template <class ParseHandler, typename Unit>
1901 class MOZ_STACK_CLASS AutoAwaitIsKeyword {
1902 using GeneralParser = frontend::GeneralParser<ParseHandler, Unit>;
1904 private:
1905 GeneralParser* parser_;
1906 AwaitHandling oldAwaitHandling_;
1908 public:
1909 AutoAwaitIsKeyword(GeneralParser* parser, AwaitHandling awaitHandling) {
1910 parser_ = parser;
1911 oldAwaitHandling_ = static_cast<AwaitHandling>(parser_->awaitHandling_);
1913 // 'await' is always a keyword in module contexts, so we don't modify
1914 // the state when the original handling is AwaitIsModuleKeyword.
1915 if (oldAwaitHandling_ != AwaitIsModuleKeyword) {
1916 parser_->setAwaitHandling(awaitHandling);
1920 ~AutoAwaitIsKeyword() { parser_->setAwaitHandling(oldAwaitHandling_); }
1923 template <class ParseHandler, typename Unit>
1924 class MOZ_STACK_CLASS AutoInParametersOfAsyncFunction {
1925 using GeneralParser = frontend::GeneralParser<ParseHandler, Unit>;
1927 private:
1928 GeneralParser* parser_;
1929 bool oldInParametersOfAsyncFunction_;
1931 public:
1932 AutoInParametersOfAsyncFunction(GeneralParser* parser, bool inParameters) {
1933 parser_ = parser;
1934 oldInParametersOfAsyncFunction_ = parser_->inParametersOfAsyncFunction_;
1935 parser_->setInParametersOfAsyncFunction(inParameters);
1938 ~AutoInParametersOfAsyncFunction() {
1939 parser_->setInParametersOfAsyncFunction(oldInParametersOfAsyncFunction_);
1943 GlobalScope::ParserData* NewEmptyGlobalScopeData(FrontendContext* fc,
1944 LifoAlloc& alloc,
1945 uint32_t numBindings);
1947 VarScope::ParserData* NewEmptyVarScopeData(FrontendContext* fc,
1948 LifoAlloc& alloc,
1949 uint32_t numBindings);
1951 LexicalScope::ParserData* NewEmptyLexicalScopeData(FrontendContext* fc,
1952 LifoAlloc& alloc,
1953 uint32_t numBindings);
1955 FunctionScope::ParserData* NewEmptyFunctionScopeData(FrontendContext* fc,
1956 LifoAlloc& alloc,
1957 uint32_t numBindings);
1959 bool FunctionScopeHasClosedOverBindings(ParseContext* pc);
1960 bool LexicalScopeHasClosedOverBindings(ParseContext* pc,
1961 ParseContext::Scope& scope);
1963 } /* namespace frontend */
1964 } /* namespace js */
1966 #endif /* frontend_Parser_h */