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