LCOV - code coverage report
Current view: top level - js/src/frontend - Parser.h (source / functions) Hit Total Coverage
Test: output.info Lines: 248 292 84.9 %
Date: 2017-07-14 16:53:18 Functions: 102 130 78.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       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             : #include "mozilla/Array.h"
      13             : #include "mozilla/Maybe.h"
      14             : #include "mozilla/TypeTraits.h"
      15             : 
      16             : #include "jsiter.h"
      17             : #include "jspubtd.h"
      18             : 
      19             : #include "ds/Nestable.h"
      20             : #include "frontend/BytecodeCompiler.h"
      21             : #include "frontend/FullParseHandler.h"
      22             : #include "frontend/LanguageExtensions.h"
      23             : #include "frontend/NameAnalysisTypes.h"
      24             : #include "frontend/NameCollections.h"
      25             : #include "frontend/SharedContext.h"
      26             : #include "frontend/SyntaxParseHandler.h"
      27             : 
      28             : namespace js {
      29             : 
      30             : class ModuleObject;
      31             : 
      32             : namespace frontend {
      33             : 
      34             : class ParserBase;
      35             : 
      36             : template <class ParseHandler, typename CharT> class Parser;
      37             : 
      38             : /*
      39             :  * The struct ParseContext stores information about the current parsing context,
      40             :  * which is part of the parser state (see the field Parser::pc). The current
      41             :  * parsing context is either the global context, or the function currently being
      42             :  * parsed. When the parser encounters a function definition, it creates a new
      43             :  * ParseContext, makes it the new current context.
      44             :  */
      45        7641 : class ParseContext : public Nestable<ParseContext>
      46             : {
      47             :   public:
      48             :     // The intra-function statement stack.
      49             :     //
      50             :     // Used for early error checking that depend on the nesting structure of
      51             :     // statements, such as continue/break targets, labels, and unbraced
      52             :     // lexical declarations.
      53       19901 :     class Statement : public Nestable<Statement>
      54             :     {
      55             :         StatementKind kind_;
      56             : 
      57             :       public:
      58             :         using Nestable<Statement>::enclosing;
      59             :         using Nestable<Statement>::findNearest;
      60             : 
      61       19901 :         Statement(ParseContext* pc, StatementKind kind)
      62       19901 :           : Nestable<Statement>(&pc->innermostStatement_),
      63       19901 :             kind_(kind)
      64       19901 :         { }
      65             : 
      66             :         template <typename T> inline bool is() const;
      67             :         template <typename T> inline T& as();
      68             : 
      69        6753 :         StatementKind kind() const {
      70        6753 :             return kind_;
      71             :         }
      72             : 
      73         501 :         void refineForKind(StatementKind newForKind) {
      74         501 :             MOZ_ASSERT(kind_ == StatementKind::ForLoop);
      75         501 :             MOZ_ASSERT(newForKind == StatementKind::ForInLoop ||
      76             :                        newForKind == StatementKind::ForOfLoop);
      77         501 :             kind_ = newForKind;
      78         501 :         }
      79             :     };
      80             : 
      81           0 :     class LabelStatement : public Statement
      82             :     {
      83             :         RootedAtom label_;
      84             : 
      85             :       public:
      86           0 :         LabelStatement(ParseContext* pc, JSAtom* label)
      87           0 :           : Statement(pc, StatementKind::Label),
      88           0 :             label_(pc->sc_->context, label)
      89           0 :         { }
      90             : 
      91           0 :         HandleAtom label() const {
      92           0 :             return label_;
      93             :         }
      94             :     };
      95             : 
      96          32 :     struct ClassStatement : public Statement
      97             :     {
      98             :         FunctionBox* constructorBox;
      99             : 
     100          32 :         explicit ClassStatement(ParseContext* pc)
     101          32 :           : Statement(pc, StatementKind::Class),
     102          32 :             constructorBox(nullptr)
     103          32 :         { }
     104             :     };
     105             : 
     106             :     // The intra-function scope stack.
     107             :     //
     108             :     // Tracks declared and used names within a scope.
     109       18834 :     class Scope : public Nestable<Scope>
     110             :     {
     111             :         // Names declared in this scope. Corresponds to the union of
     112             :         // VarDeclaredNames and LexicallyDeclaredNames in the ES spec.
     113             :         //
     114             :         // A 'var' declared name is a member of the declared name set of every
     115             :         // scope in its scope contour.
     116             :         //
     117             :         // A lexically declared name is a member only of the declared name set of
     118             :         // the scope in which it is declared.
     119             :         PooledMapPtr<DeclaredNameMap> declared_;
     120             : 
     121             :         // FunctionBoxes in this scope that need to be considered for Annex
     122             :         // B.3.3 semantics. This is checked on Scope exit, as by then we have
     123             :         // all the declared names and would know if Annex B.3.3 is applicable.
     124             :         PooledVectorPtr<FunctionBoxVector> possibleAnnexBFunctionBoxes_;
     125             : 
     126             :         // Monotonically increasing id.
     127             :         uint32_t id_;
     128             : 
     129       29316 :         bool maybeReportOOM(ParseContext* pc, bool result) {
     130       29316 :             if (!result)
     131           0 :                 ReportOutOfMemory(pc->sc()->context);
     132       29316 :             return result;
     133             :         }
     134             : 
     135             :       public:
     136             :         using DeclaredNamePtr = DeclaredNameMap::Ptr;
     137             :         using AddDeclaredNamePtr = DeclaredNameMap::AddPtr;
     138             : 
     139             :         using Nestable<Scope>::enclosing;
     140             : 
     141             :         explicit inline Scope(ParserBase* parser);
     142             : 
     143             :         void dump(ParseContext* pc);
     144             : 
     145       92525 :         uint32_t id() const {
     146       92525 :             return id_;
     147             :         }
     148             : 
     149       18834 :         MOZ_MUST_USE bool init(ParseContext* pc) {
     150       18834 :             if (id_ == UINT32_MAX) {
     151           0 :                 pc->tokenStream_.reportErrorNoOffset(JSMSG_NEED_DIET, js_script_str);
     152           0 :                 return false;
     153             :             }
     154             : 
     155       18834 :             return declared_.acquire(pc->sc()->context);
     156             :         }
     157             : 
     158       13020 :         DeclaredNamePtr lookupDeclaredName(JSAtom* name) {
     159       13020 :             return declared_->lookup(name);
     160             :         }
     161             : 
     162       30228 :         AddDeclaredNamePtr lookupDeclaredNameForAdd(JSAtom* name) {
     163       30228 :             return declared_->lookupForAdd(name);
     164             :         }
     165             : 
     166       29316 :         MOZ_MUST_USE bool addDeclaredName(ParseContext* pc, AddDeclaredNamePtr& p, JSAtom* name,
     167             :                                           DeclarationKind kind, uint32_t pos)
     168             :         {
     169       29316 :             return maybeReportOOM(pc, declared_->add(p, name, DeclaredNameInfo(kind, pos)));
     170             :         }
     171             : 
     172             :         // Add a FunctionBox as a possible candidate for Annex B.3.3 semantics.
     173             :         MOZ_MUST_USE bool addPossibleAnnexBFunctionBox(ParseContext* pc, FunctionBox* funbox);
     174             : 
     175             :         // Check if the candidate function boxes for Annex B.3.3 should in
     176             :         // fact get Annex B semantics. Checked on Scope exit.
     177             :         MOZ_MUST_USE bool propagateAndMarkAnnexBFunctionBoxes(ParseContext* pc);
     178             : 
     179             :         // Add and remove catch parameter names. Used to implement the odd
     180             :         // semantics of catch bodies.
     181             :         bool addCatchParameters(ParseContext* pc, Scope& catchParamScope);
     182             :         void removeCatchParameters(ParseContext* pc, Scope& catchParamScope);
     183             : 
     184        7641 :         void useAsVarScope(ParseContext* pc) {
     185        7641 :             MOZ_ASSERT(!pc->varScope_);
     186        7641 :             pc->varScope_ = this;
     187        7641 :         }
     188             : 
     189             :         // An iterator for the set of names a scope binds: the set of all
     190             :         // declared names for 'var' scopes, and the set of lexically declared
     191             :         // names for non-'var' scopes.
     192       34161 :         class BindingIter
     193             :         {
     194             :             friend class Scope;
     195             : 
     196             :             DeclaredNameMap::Range declaredRange_;
     197             :             mozilla::DebugOnly<uint32_t> count_;
     198             :             bool isVarScope_;
     199             : 
     200       34161 :             BindingIter(Scope& scope, bool isVarScope)
     201       34161 :               : declaredRange_(scope.declared_->all()),
     202             :                 count_(0),
     203       34161 :                 isVarScope_(isVarScope)
     204             :             {
     205       34161 :                 settle();
     206       34161 :             }
     207             : 
     208       90402 :             void settle() {
     209             :                 // Both var and lexically declared names are binding in a var
     210             :                 // scope.
     211       90402 :                 if (isVarScope_)
     212       67992 :                     return;
     213             : 
     214             :                 // Otherwise, pop only lexically declared names are
     215             :                 // binding. Pop the range until we find such a name.
     216        2956 :                 while (!declaredRange_.empty()) {
     217        8536 :                     if (BindingKindIsLexical(kind()))
     218        5580 :                         break;
     219        2956 :                     declaredRange_.popFront();
     220             :                 }
     221             :             }
     222             : 
     223             :           public:
     224      293362 :             bool done() const {
     225      293362 :                 return declaredRange_.empty();
     226             :             }
     227             : 
     228       90402 :             explicit operator bool() const {
     229       90402 :                 return !done();
     230             :             }
     231             : 
     232       56806 :             JSAtom* name() {
     233       56806 :                 MOZ_ASSERT(!done());
     234       56806 :                 return declaredRange_.front().key();
     235             :             }
     236             : 
     237       52904 :             DeclarationKind declarationKind() {
     238       52904 :                 MOZ_ASSERT(!done());
     239       52904 :                 return declaredRange_.front().value()->kind();
     240             :             }
     241             : 
     242       44372 :             BindingKind kind() {
     243       44372 :                 return DeclarationKindToBindingKind(declarationKind());
     244             :             }
     245             : 
     246       35797 :             bool closedOver() {
     247       35797 :                 MOZ_ASSERT(!done());
     248       35797 :                 return declaredRange_.front().value()->closedOver();
     249             :             }
     250             : 
     251        1212 :             void setClosedOver() {
     252        1212 :                 MOZ_ASSERT(!done());
     253        1212 :                 return declaredRange_.front().value()->setClosedOver();
     254             :             }
     255             : 
     256       56241 :             void operator++(int) {
     257       56241 :                 MOZ_ASSERT(!done());
     258       56241 :                 MOZ_ASSERT(count_ != UINT32_MAX);
     259       56241 :                 declaredRange_.popFront();
     260       56241 :                 settle();
     261       56241 :             }
     262             :         };
     263             : 
     264             :         inline BindingIter bindings(ParseContext* pc);
     265             :     };
     266             : 
     267         536 :     class VarScope : public Scope
     268             :     {
     269             :       public:
     270             :         explicit inline VarScope(ParserBase* parser);
     271             :     };
     272             : 
     273             :   private:
     274             :     // Trace logging of parsing time.
     275             :     AutoFrontendTraceLog traceLog_;
     276             : 
     277             :     // Context shared between parsing and bytecode generation.
     278             :     SharedContext* sc_;
     279             : 
     280             :     // TokenStream used for error reporting.
     281             :     TokenStreamAnyChars& tokenStream_;
     282             : 
     283             :     // The innermost statement, i.e., top of the statement stack.
     284             :     Statement* innermostStatement_;
     285             : 
     286             :     // The innermost scope, i.e., top of the scope stack.
     287             :     //
     288             :     // The outermost scope in the stack is usually varScope_. In the case of
     289             :     // functions, the outermost scope is functionScope_, which may be
     290             :     // varScope_. See comment above functionScope_.
     291             :     Scope* innermostScope_;
     292             : 
     293             :     // If isFunctionBox() and the function is a named lambda, the DeclEnv
     294             :     // scope for named lambdas.
     295             :     mozilla::Maybe<Scope> namedLambdaScope_;
     296             : 
     297             :     // If isFunctionBox(), the scope for the function. If there are no
     298             :     // parameter expressions, this is scope for the entire function. If there
     299             :     // are parameter expressions, this holds the special function names
     300             :     // ('.this', 'arguments') and the formal parameers.
     301             :     mozilla::Maybe<Scope> functionScope_;
     302             : 
     303             :     // The body-level scope. This always exists, but not necessarily at the
     304             :     // beginning of parsing the script in the case of functions with parameter
     305             :     // expressions.
     306             :     Scope* varScope_;
     307             : 
     308             :     // Simple formal parameter names, in order of appearance. Only used when
     309             :     // isFunctionBox().
     310             :     PooledVectorPtr<AtomVector> positionalFormalParameterNames_;
     311             : 
     312             :     // Closed over binding names, in order of appearance. Null-delimited
     313             :     // between scopes. Only used when syntax parsing.
     314             :     PooledVectorPtr<AtomVector> closedOverBindingsForLazy_;
     315             : 
     316             :     // Monotonically increasing id.
     317             :     uint32_t scriptId_;
     318             : 
     319             :     // Set when compiling a function using Parser::standaloneFunctionBody via
     320             :     // the Function or Generator constructor.
     321             :     bool isStandaloneFunctionBody_;
     322             : 
     323             :     // Set when encountering a super.property inside a method. We need to mark
     324             :     // the nearest super scope as needing a home object.
     325             :     bool superScopeNeedsHomeObject_;
     326             : 
     327             :   public:
     328             :     // lastYieldOffset stores the offset of the last yield that was parsed.
     329             :     // NoYieldOffset is its initial value.
     330             :     static const uint32_t NoYieldOffset = UINT32_MAX;
     331             :     uint32_t lastYieldOffset;
     332             : 
     333             :     // lastAwaitOffset stores the offset of the last await that was parsed.
     334             :     // NoAwaitOffset is its initial value.
     335             :     static const uint32_t NoAwaitOffset = UINT32_MAX;
     336             :     uint32_t         lastAwaitOffset;
     337             : 
     338             :     // All inner functions in this context. Only used when syntax parsing.
     339             :     Rooted<GCVector<JSFunction*, 8>> innerFunctionsForLazy;
     340             : 
     341             :     // In a function context, points to a Directive struct that can be updated
     342             :     // to reflect new directives encountered in the Directive Prologue that
     343             :     // require reparsing the function. In global/module/generator-tail contexts,
     344             :     // we don't need to reparse when encountering a DirectivePrologue so this
     345             :     // pointer may be nullptr.
     346             :     Directives* newDirectives;
     347             : 
     348             :     // Set when parsing a function and it has 'return <expr>;'
     349             :     bool funHasReturnExpr;
     350             : 
     351             :     // Set when parsing a function and it has 'return;'
     352             :     bool funHasReturnVoid;
     353             : 
     354             :   public:
     355             :     template <class ParseHandler, typename CharT>
     356        7641 :     ParseContext(Parser<ParseHandler, CharT>* prs, SharedContext* sc, Directives* newDirectives)
     357        7641 :       : Nestable<ParseContext>(&prs->pc),
     358        7641 :         traceLog_(sc->context,
     359             :                   mozilla::IsSame<ParseHandler, FullParseHandler>::value
     360             :                   ? TraceLogger_ParsingFull
     361             :                   : TraceLogger_ParsingSyntax,
     362             :                   prs->tokenStream),
     363             :         sc_(sc),
     364             :         tokenStream_(prs->tokenStream),
     365             :         innermostStatement_(nullptr),
     366             :         innermostScope_(nullptr),
     367             :         varScope_(nullptr),
     368        7641 :         positionalFormalParameterNames_(prs->context->frontendCollectionPool()),
     369        7641 :         closedOverBindingsForLazy_(prs->context->frontendCollectionPool()),
     370        7641 :         scriptId_(prs->usedNames.nextScriptId()),
     371             :         isStandaloneFunctionBody_(false),
     372             :         superScopeNeedsHomeObject_(false),
     373             :         lastYieldOffset(NoYieldOffset),
     374             :         lastAwaitOffset(NoAwaitOffset),
     375       15282 :         innerFunctionsForLazy(prs->context, GCVector<JSFunction*, 8>(prs->context)),
     376             :         newDirectives(newDirectives),
     377             :         funHasReturnExpr(false),
     378       53487 :         funHasReturnVoid(false)
     379             :     {
     380        7641 :         if (isFunctionBox()) {
     381        7373 :             if (functionBox()->function()->isNamedLambda())
     382         714 :                 namedLambdaScope_.emplace(prs);
     383        7373 :             functionScope_.emplace(prs);
     384             :         }
     385        7641 :     }
     386             : 
     387             :     MOZ_MUST_USE bool init();
     388             : 
     389      218396 :     SharedContext* sc() {
     390      218396 :         return sc_;
     391             :     }
     392             : 
     393       96987 :     bool isFunctionBox() const {
     394       96987 :         return sc_->isFunctionBox();
     395             :     }
     396             : 
     397      106753 :     FunctionBox* functionBox() {
     398      106753 :         return sc_->asFunctionBox();
     399             :     }
     400             : 
     401        9485 :     Statement* innermostStatement() {
     402        9485 :         return innermostStatement_;
     403             :     }
     404             : 
     405       95495 :     Scope* innermostScope() {
     406             :         // There is always at least one scope: the 'var' scope.
     407       95495 :         MOZ_ASSERT(innermostScope_);
     408       95495 :         return innermostScope_;
     409             :     }
     410             : 
     411        1101 :     Scope& namedLambdaScope() {
     412        1101 :         MOZ_ASSERT(functionBox()->function()->isNamedLambda());
     413        1101 :         return *namedLambdaScope_;
     414             :     }
     415             : 
     416       39535 :     Scope& functionScope() {
     417       39535 :         MOZ_ASSERT(isFunctionBox());
     418       39535 :         return *functionScope_;
     419             :     }
     420             : 
     421       33473 :     Scope& varScope() {
     422       33473 :         MOZ_ASSERT(varScope_);
     423       33473 :         return *varScope_;
     424             :     }
     425             : 
     426        7654 :     bool isFunctionExtraBodyVarScopeInnermost() {
     427        8056 :         return isFunctionBox() && functionBox()->hasParameterExprs &&
     428        8056 :                innermostScope() == varScope_;
     429             :     }
     430             : 
     431             :     template <typename Predicate /* (Statement*) -> bool */>
     432        6792 :     Statement* findInnermostStatement(Predicate predicate) {
     433        6792 :         return Statement::findNearest(innermostStatement_, predicate);
     434             :     }
     435             : 
     436             :     template <typename T, typename Predicate /* (Statement*) -> bool */>
     437           0 :     T* findInnermostStatement(Predicate predicate) {
     438           0 :         return Statement::findNearest<T>(innermostStatement_, predicate);
     439             :     }
     440             : 
     441             :     template <typename T>
     442          31 :     T* findInnermostStatement() {
     443          31 :         return Statement::findNearest<T>(innermostStatement_);
     444             :     }
     445             : 
     446       31264 :     AtomVector& positionalFormalParameterNames() {
     447       31264 :         return *positionalFormalParameterNames_;
     448             :     }
     449             : 
     450        9686 :     AtomVector& closedOverBindingsForLazy() {
     451        9686 :         return *closedOverBindingsForLazy_;
     452             :     }
     453             : 
     454             :     // True if we are at the topmost level of a entire script or function body.
     455             :     // For example, while parsing this code we would encounter f1 and f2 at
     456             :     // body level, but we would not encounter f3 or f4 at body level:
     457             :     //
     458             :     //   function f1() { function f2() { } }
     459             :     //   if (cond) { function f3() { if (cond) { function f4() { } } } }
     460             :     //
     461       17550 :     bool atBodyLevel() {
     462       17550 :         return !innermostStatement_;
     463             :     }
     464             : 
     465             :     bool atGlobalLevel() {
     466             :         return atBodyLevel() && sc_->isGlobalContext();
     467             :     }
     468             : 
     469             :     // True if we are at the topmost level of a module only.
     470        1831 :     bool atModuleLevel() {
     471        1831 :         return atBodyLevel() && sc_->isModuleContext();
     472             :     }
     473             : 
     474          15 :     void setIsStandaloneFunctionBody() {
     475          15 :         isStandaloneFunctionBody_ = true;
     476          15 :     }
     477             : 
     478           0 :     bool isStandaloneFunctionBody() const {
     479           0 :         return isStandaloneFunctionBody_;
     480             :     }
     481             : 
     482          13 :     void setSuperScopeNeedsHomeObject() {
     483          13 :         MOZ_ASSERT(sc_->allowSuperProperty());
     484          13 :         superScopeNeedsHomeObject_ = true;
     485          13 :     }
     486             : 
     487        8853 :     bool superScopeNeedsHomeObject() const {
     488        8853 :         return superScopeNeedsHomeObject_;
     489             :     }
     490             : 
     491      133479 :     bool useAsmOrInsideUseAsm() const {
     492      133479 :         return sc_->isFunctionBox() && sc_->asFunctionBox()->useAsmOrInsideUseAsm();
     493             :     }
     494             : 
     495             :     // Most functions start off being parsed as non-generators.
     496             :     // Non-generators transition to LegacyGenerator on parsing "yield" in JS 1.7.
     497             :     // An ES6 generator is marked as a "star generator" before its body is parsed.
     498       36807 :     GeneratorKind generatorKind() const {
     499       36807 :         return sc_->isFunctionBox() ? sc_->asFunctionBox()->generatorKind() : NotGenerator;
     500             :     }
     501             : 
     502       14664 :     bool isLegacyGenerator() const {
     503       14664 :         return generatorKind() == LegacyGenerator;
     504             :     }
     505             : 
     506        7373 :     bool isStarGenerator() const {
     507        7373 :         return generatorKind() == StarGenerator;
     508             :     }
     509             : 
     510       24018 :     bool isAsync() const {
     511       24018 :         return sc_->isFunctionBox() && sc_->asFunctionBox()->isAsync();
     512             :     }
     513             : 
     514        7373 :     bool needsDotGeneratorName() const {
     515        7373 :         return isStarGenerator() || isLegacyGenerator() || isAsync();
     516             :     }
     517             : 
     518        7373 :     FunctionAsyncKind asyncKind() const {
     519        7373 :         return isAsync() ? AsyncFunction : SyncFunction;
     520             :     }
     521             : 
     522           7 :     bool isArrowFunction() const {
     523           7 :         return sc_->isFunctionBox() && sc_->asFunctionBox()->function()->isArrow();
     524             :     }
     525             : 
     526           0 :     bool isMethod() const {
     527           0 :         return sc_->isFunctionBox() && sc_->asFunctionBox()->function()->isMethod();
     528             :     }
     529             : 
     530       98679 :     uint32_t scriptId() const {
     531       98679 :         return scriptId_;
     532             :     }
     533             : 
     534             :     bool annexBAppliesToLexicalFunctionInInnermostScope(FunctionBox* funbox);
     535             : 
     536             :     bool tryDeclareVar(HandlePropertyName name, DeclarationKind kind, uint32_t beginPos,
     537             :                        mozilla::Maybe<DeclarationKind>* redeclaredKind, uint32_t* prevPos);
     538             : 
     539             :   private:
     540             :     mozilla::Maybe<DeclarationKind> isVarRedeclaredInInnermostScope(HandlePropertyName name,
     541             :                                                                     DeclarationKind kind);
     542             :     mozilla::Maybe<DeclarationKind> isVarRedeclaredInEval(HandlePropertyName name,
     543             :                                                           DeclarationKind kind);
     544             : 
     545             :     enum DryRunOption { NotDryRun, DryRunInnermostScopeOnly };
     546             :     template <DryRunOption dryRunOption>
     547             :     bool tryDeclareVarHelper(HandlePropertyName name, DeclarationKind kind, uint32_t beginPos,
     548             :                              mozilla::Maybe<DeclarationKind>* redeclaredKind, uint32_t* prevPos);
     549             : 
     550             : };
     551             : 
     552             : template <>
     553             : inline bool
     554           0 : ParseContext::Statement::is<ParseContext::LabelStatement>() const
     555             : {
     556           0 :     return kind_ == StatementKind::Label;
     557             : }
     558             : 
     559             : template <>
     560             : inline bool
     561          87 : ParseContext::Statement::is<ParseContext::ClassStatement>() const
     562             : {
     563          87 :     return kind_ == StatementKind::Class;
     564             : }
     565             : 
     566             : template <typename T>
     567             : inline T&
     568          31 : ParseContext::Statement::as()
     569             : {
     570          31 :     MOZ_ASSERT(is<T>());
     571          31 :     return static_cast<T&>(*this);
     572             : }
     573             : 
     574             : inline ParseContext::Scope::BindingIter
     575       34161 : ParseContext::Scope::bindings(ParseContext* pc)
     576             : {
     577             :     // In function scopes with parameter expressions, function special names
     578             :     // (like '.this') are declared as vars in the function scope, despite its
     579             :     // not being the var scope.
     580       34161 :     return BindingIter(*this, pc->varScope_ == this || pc->functionScope_.ptrOr(nullptr) == this);
     581             : }
     582             : 
     583             : inline
     584        5951 : Directives::Directives(ParseContext* parent)
     585        5951 :   : strict_(parent->sc()->strict()),
     586        5951 :     asmJS_(parent->useAsmOrInsideUseAsm())
     587        5951 : {}
     588             : 
     589             : enum VarContext { HoistVars, DontHoistVars };
     590             : enum PropListType { ObjectLiteral, ClassBody, DerivedClassBody };
     591             : enum class PropertyType {
     592             :     Normal,
     593             :     Shorthand,
     594             :     CoverInitializedName,
     595             :     Getter,
     596             :     GetterNoExpressionClosure,
     597             :     Setter,
     598             :     SetterNoExpressionClosure,
     599             :     Method,
     600             :     GeneratorMethod,
     601             :     AsyncMethod,
     602             :     AsyncGeneratorMethod,
     603             :     Constructor,
     604             :     DerivedConstructor
     605             : };
     606             : 
     607             : // Specify a value for an ES6 grammar parametrization.  We have no enum for
     608             : // [Return] because its behavior is exactly equivalent to checking whether
     609             : // we're in a function box -- easier and simpler than passing an extra
     610             : // parameter everywhere.
     611             : enum YieldHandling { YieldIsName, YieldIsKeyword };
     612             : enum AwaitHandling : uint8_t { AwaitIsName, AwaitIsKeyword, AwaitIsModuleKeyword };
     613             : enum InHandling { InAllowed, InProhibited };
     614             : enum DefaultHandling { NameRequired, AllowDefaultName };
     615             : enum TripledotHandling { TripledotAllowed, TripledotProhibited };
     616             : 
     617             : // A data structure for tracking used names per parsing session in order to
     618             : // compute which bindings are closed over. Scripts and scopes are numbered
     619             : // monotonically in textual order and name uses are tracked by lists of
     620             : // (script id, scope id) pairs of their use sites.
     621             : //
     622             : // Intuitively, in a pair (P,S), P tracks the most nested function that has a
     623             : // use of u, and S tracks the most nested scope that is still being parsed.
     624             : //
     625             : // P is used to answer the question "is u used by a nested function?"
     626             : // S is used to answer the question "is u used in any scopes currently being
     627             : //                                   parsed?"
     628             : //
     629             : // The algorithm:
     630             : //
     631             : // Let Used by a map of names to lists.
     632             : //
     633             : // 1. Number all scopes in monotonic increasing order in textual order.
     634             : // 2. Number all scripts in monotonic increasing order in textual order.
     635             : // 3. When an identifier u is used in scope numbered S in script numbered P,
     636             : //    and u is found in Used,
     637             : //   a. Append (P,S) to Used[u].
     638             : //   b. Otherwise, assign the the list [(P,S)] to Used[u].
     639             : // 4. When we finish parsing a scope S in script P, for each declared name d in
     640             : //    Declared(S):
     641             : //   a. If d is found in Used, mark d as closed over if there is a value
     642             : //     (P_d, S_d) in Used[d] such that P_d > P and S_d > S.
     643             : //   b. Remove all values (P_d, S_d) in Used[d] such that S_d are >= S.
     644             : //
     645             : // Steps 1 and 2 are implemented by UsedNameTracker::next{Script,Scope}Id.
     646             : // Step 3 is implemented by UsedNameTracker::noteUsedInScope.
     647             : // Step 4 is implemented by UsedNameTracker::noteBoundInScope and
     648             : // Parser::propagateFreeNamesAndMarkClosedOverBindings.
     649        1697 : class UsedNameTracker
     650             : {
     651             :   public:
     652             :     struct Use
     653             :     {
     654             :         uint32_t scriptId;
     655             :         uint32_t scopeId;
     656             :     };
     657             : 
     658       36722 :     class UsedNameInfo
     659             :     {
     660             :         friend class UsedNameTracker;
     661             : 
     662             :         Vector<Use, 6> uses_;
     663             : 
     664             :         void resetToScope(uint32_t scriptId, uint32_t scopeId);
     665             : 
     666             :       public:
     667       11634 :         explicit UsedNameInfo(JSContext* cx)
     668       11634 :           : uses_(cx)
     669       11634 :         { }
     670             : 
     671       24954 :         UsedNameInfo(UsedNameInfo&& other)
     672       24954 :           : uses_(mozilla::Move(other.uses_))
     673       24954 :         { }
     674             : 
     675       77354 :         bool noteUsedInScope(uint32_t scriptId, uint32_t scopeId) {
     676       77354 :             if (uses_.empty() || uses_.back().scopeId < scopeId)
     677       45495 :                 return uses_.append(Use { scriptId, scopeId });
     678       31859 :             return true;
     679             :         }
     680             : 
     681       18876 :         void noteBoundInScope(uint32_t scriptId, uint32_t scopeId, bool* closedOver) {
     682       18876 :             *closedOver = false;
     683       75746 :             while (!uses_.empty()) {
     684       29466 :                 Use& innermost = uses_.back();
     685       29466 :                 if (innermost.scopeId < scopeId)
     686        1031 :                     break;
     687       28435 :                 if (innermost.scriptId > scriptId)
     688        1997 :                     *closedOver = true;
     689       28435 :                 uses_.popBack();
     690             :             }
     691       18876 :         }
     692             : 
     693        6154 :         bool isUsedInScript(uint32_t scriptId) const {
     694        6154 :             return !uses_.empty() && uses_.back().scriptId >= scriptId;
     695             :         }
     696             :     };
     697             : 
     698             :     using UsedNameMap = HashMap<JSAtom*,
     699             :                                 UsedNameInfo,
     700             :                                 DefaultHasher<JSAtom*>>;
     701             : 
     702             :   private:
     703             :     // The map of names to chains of uses.
     704             :     UsedNameMap map_;
     705             : 
     706             :     // Monotonically increasing id for all nested scripts.
     707             :     uint32_t scriptCounter_;
     708             : 
     709             :     // Monotonically increasing id for all nested scopes.
     710             :     uint32_t scopeCounter_;
     711             : 
     712             :   public:
     713        1696 :     explicit UsedNameTracker(JSContext* cx)
     714        1696 :       : map_(cx),
     715             :         scriptCounter_(0),
     716        1696 :         scopeCounter_(0)
     717        1696 :     { }
     718             : 
     719        1696 :     MOZ_MUST_USE bool init() {
     720        1696 :         return map_.init();
     721             :     }
     722             : 
     723        7641 :     uint32_t nextScriptId() {
     724        7641 :         MOZ_ASSERT(scriptCounter_ != UINT32_MAX,
     725             :                    "ParseContext::Scope::init should have prevented wraparound");
     726        7641 :         return scriptCounter_++;
     727             :     }
     728             : 
     729       18834 :     uint32_t nextScopeId() {
     730       18834 :         MOZ_ASSERT(scopeCounter_ != UINT32_MAX);
     731       18834 :         return scopeCounter_++;
     732             :     }
     733             : 
     734       30235 :     UsedNameMap::Ptr lookup(JSAtom* name) const {
     735       30235 :         return map_.lookup(name);
     736             :     }
     737             : 
     738             :     MOZ_MUST_USE bool noteUse(JSContext* cx, JSAtom* name,
     739             :                               uint32_t scriptId, uint32_t scopeId);
     740             : 
     741             :     struct RewindToken
     742             :     {
     743             :       private:
     744             :         friend class UsedNameTracker;
     745             :         uint32_t scriptId;
     746             :         uint32_t scopeId;
     747             :     };
     748             : 
     749        1551 :     RewindToken getRewindToken() const {
     750             :         RewindToken token;
     751        1551 :         token.scriptId = scriptCounter_;
     752        1551 :         token.scopeId = scopeCounter_;
     753        1551 :         return token;
     754             :     }
     755             : 
     756             :     // Resets state so that scriptId and scopeId are the innermost script and
     757             :     // scope, respectively. Used for rewinding state on syntax parse failure.
     758             :     void rewind(RewindToken token);
     759             : 
     760             :     // Resets state to beginning of compilation.
     761           0 :     void reset() {
     762           0 :         map_.clear();
     763             :         RewindToken token;
     764           0 :         token.scriptId = 0;
     765           0 :         token.scopeId = 0;
     766           0 :         rewind(token);
     767           0 :     }
     768             : };
     769             : 
     770             : template <class Parser>
     771             : class AutoAwaitIsKeyword;
     772             : 
     773             : class ParserBase : public StrictModeGetter
     774             : {
     775             :   private:
     776        1902 :     ParserBase* thisForCtor() { return this; }
     777             : 
     778             :   public:
     779             :     JSContext* const context;
     780             : 
     781             :     LifoAlloc& alloc;
     782             : 
     783             :     TokenStream tokenStream;
     784             :     LifoAlloc::Mark tempPoolMark;
     785             : 
     786             :     /* list of parsed objects for GC tracing */
     787             :     ObjectBox* traceListHead;
     788             : 
     789             :     /* innermost parse context (stack-allocated) */
     790             :     ParseContext* pc;
     791             : 
     792             :     // For tracking used names in this parsing session.
     793             :     UsedNameTracker& usedNames;
     794             : 
     795             :     ScriptSource*       ss;
     796             : 
     797             :     /* Root atoms and objects allocated for the parsed tree. */
     798             :     AutoKeepAtoms       keepAtoms;
     799             : 
     800             :     /* Perform constant-folding; must be true when interfacing with the emitter. */
     801             :     const bool          foldConstants:1;
     802             : 
     803             :   protected:
     804             : #if DEBUG
     805             :     /* Our fallible 'checkOptions' member function has been called. */
     806             :     bool checkOptionsCalled:1;
     807             : #endif
     808             : 
     809             :     /* Unexpected end of input, i.e. TOK_EOF not at top-level. */
     810             :     bool isUnexpectedEOF_:1;
     811             : 
     812             :     /* AwaitHandling */ uint8_t awaitHandling_:2;
     813             : 
     814             :   public:
     815        1071 :     bool awaitIsKeyword() const {
     816        1071 :       return awaitHandling_ != AwaitIsName;
     817             :     }
     818             : 
     819             :     ParserBase(JSContext* cx, LifoAlloc& alloc, const ReadOnlyCompileOptions& options,
     820             :                const char16_t* chars, size_t length, bool foldConstants,
     821             :                UsedNameTracker& usedNames, LazyScript* lazyOuterFunction);
     822             :     ~ParserBase();
     823             : 
     824           0 :     const char* getFilename() const { return tokenStream.getFilename(); }
     825        2071 :     JSVersion versionNumber() const { return tokenStream.versionNumber(); }
     826      749259 :     TokenPos pos() const { return tokenStream.currentToken().pos; }
     827             : 
     828             :     // Determine whether |yield| is a valid name in the current context, or
     829             :     // whether it's prohibited due to strictness, JS version, or occurrence
     830             :     // inside a star generator.
     831          48 :     bool yieldExpressionsSupported() {
     832          96 :         return (versionNumber() >= JSVERSION_1_7 && !pc->isAsync()) ||
     833          48 :                pc->isStarGenerator() ||
     834          48 :                pc->isLegacyGenerator();
     835             :     }
     836             : 
     837        1006 :     bool asyncIterationSupported() {
     838             : #ifdef RELEASE_OR_BETA
     839             :         return false;
     840             : #else
     841             :         // Expose Async Iteration only to web content until the spec proposal
     842             :         // gets stable.
     843        1006 :         return !options().isProbablySystemOrAddonCode;
     844             : #endif
     845             :     }
     846             : 
     847           0 :     virtual bool strictMode() { return pc->sc()->strict(); }
     848          64 :     bool setLocalStrictMode(bool strict) {
     849          64 :         MOZ_ASSERT(tokenStream.debugHasNoLookahead());
     850          64 :         return pc->sc()->setLocalStrictMode(strict);
     851             :     }
     852             : 
     853       56490 :     const ReadOnlyCompileOptions& options() const {
     854       56490 :         return tokenStream.options();
     855             :     }
     856             : 
     857           0 :     bool isUnexpectedEOF() const { return isUnexpectedEOF_; }
     858             : 
     859             :     bool reportNoOffset(ParseReportKind kind, bool strict, unsigned errorNumber, ...);
     860             : 
     861             :     /* Report the given error at the current offset. */
     862             :     void error(unsigned errorNumber, ...);
     863             :     void errorWithNotes(UniquePtr<JSErrorNotes> notes, unsigned errorNumber, ...);
     864             : 
     865             :     /* Report the given error at the given offset. */
     866             :     void errorAt(uint32_t offset, unsigned errorNumber, ...);
     867             :     void errorWithNotesAt(UniquePtr<JSErrorNotes> notes, uint32_t offset,
     868             :                           unsigned errorNumber, ...);
     869             : 
     870             :     /*
     871             :      * Handle a strict mode error at the current offset.  Report an error if in
     872             :      * strict mode code, or warn if not, using the given error number and
     873             :      * arguments.
     874             :      */
     875             :     MOZ_MUST_USE bool strictModeError(unsigned errorNumber, ...);
     876             : 
     877             :     /*
     878             :      * Handle a strict mode error at the given offset.  Report an error if in
     879             :      * strict mode code, or warn if not, using the given error number and
     880             :      * arguments.
     881             :      */
     882             :     MOZ_MUST_USE bool strictModeErrorAt(uint32_t offset, unsigned errorNumber, ...);
     883             : 
     884             :     /* Report the given warning at the current offset. */
     885             :     MOZ_MUST_USE bool warning(unsigned errorNumber, ...);
     886             : 
     887             :     /* Report the given warning at the given offset. */
     888             :     MOZ_MUST_USE bool warningAt(uint32_t offset, unsigned errorNumber, ...);
     889             : 
     890             :     /*
     891             :      * If extra warnings are enabled, report the given warning at the current
     892             :      * offset.
     893             :      */
     894             :     MOZ_MUST_USE bool extraWarning(unsigned errorNumber, ...);
     895             : 
     896             :     /*
     897             :      * If extra warnings are enabled, report the given warning at the given
     898             :      * offset.
     899             :      */
     900             :     MOZ_MUST_USE bool extraWarningAt(uint32_t offset, unsigned errorNumber, ...);
     901             : 
     902             :     bool isValidStrictBinding(PropertyName* name);
     903             : 
     904             :     void addTelemetry(DeprecatedLanguageExtension e);
     905             : 
     906             :     bool warnOnceAboutExprClosure();
     907             :     bool warnOnceAboutForEach();
     908             : 
     909         991 :     bool allowsForEachIn() {
     910             : #if !JS_HAS_FOR_EACH_IN
     911             :         return false;
     912             : #else
     913         991 :         return options().forEachStatementOption && versionNumber() >= JSVERSION_1_6;
     914             : #endif
     915             :     }
     916             : 
     917             :     bool hasValidSimpleStrictParameterNames();
     918             : 
     919             : 
     920             :     /*
     921             :      * Create a new function object given a name (which is optional if this is
     922             :      * a function expression).
     923             :      */
     924             :     JSFunction* newFunction(HandleAtom atom, FunctionSyntaxKind kind,
     925             :                             GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
     926             :                             HandleObject proto);
     927             : 
     928             :     // A Parser::Mark is the extension of the LifoAlloc::Mark to the entire
     929             :     // Parser's state. Note: clients must still take care that any ParseContext
     930             :     // that points into released ParseNodes is destroyed.
     931           0 :     class Mark
     932             :     {
     933             :         friend class ParserBase;
     934             :         LifoAlloc::Mark mark;
     935             :         ObjectBox* traceListHead;
     936             :     };
     937           0 :     Mark mark() const {
     938           0 :         Mark m;
     939           0 :         m.mark = alloc.mark();
     940           0 :         m.traceListHead = traceListHead;
     941           0 :         return m;
     942             :     }
     943           0 :     void release(Mark m) {
     944           0 :         alloc.release(m.mark);
     945           0 :         traceListHead = m.traceListHead;
     946           0 :     }
     947             : 
     948             :     ObjectBox* newObjectBox(JSObject* obj);
     949             : 
     950             :     mozilla::Maybe<GlobalScope::Data*> newGlobalScopeData(ParseContext::Scope& scope);
     951             :     mozilla::Maybe<ModuleScope::Data*> newModuleScopeData(ParseContext::Scope& scope);
     952             :     mozilla::Maybe<EvalScope::Data*> newEvalScopeData(ParseContext::Scope& scope);
     953             :     mozilla::Maybe<FunctionScope::Data*> newFunctionScopeData(ParseContext::Scope& scope,
     954             :                                                               bool hasParameterExprs);
     955             :     mozilla::Maybe<VarScope::Data*> newVarScopeData(ParseContext::Scope& scope);
     956             :     mozilla::Maybe<LexicalScope::Data*> newLexicalScopeData(ParseContext::Scope& scope);
     957             : 
     958             :   protected:
     959             :     enum InvokedPrediction { PredictUninvoked = false, PredictInvoked = true };
     960             :     enum ForInitLocation { InForInit, NotInForInit };
     961             : };
     962             : 
     963             : inline
     964       18834 : ParseContext::Scope::Scope(ParserBase* parser)
     965       18834 :   : Nestable<Scope>(&parser->pc->innermostScope_),
     966       18834 :     declared_(parser->context->frontendCollectionPool()),
     967       18834 :     possibleAnnexBFunctionBoxes_(parser->context->frontendCollectionPool()),
     968       56502 :     id_(parser->usedNames.nextScopeId())
     969       18834 : { }
     970             : 
     971             : inline
     972         536 : ParseContext::VarScope::VarScope(ParserBase* parser)
     973         536 :   : Scope(parser)
     974             : {
     975         536 :     useAsVarScope(parser->pc);
     976         536 : }
     977             : 
     978             : template <class ParseHandler, typename CharT>
     979             : class Parser final : public ParserBase, private JS::AutoGCRooter
     980             : {
     981             :   private:
     982             :     using Node = typename ParseHandler::Node;
     983             : 
     984             :     /*
     985             :      * A class for temporarily stashing errors while parsing continues.
     986             :      *
     987             :      * The ability to stash an error is useful for handling situations where we
     988             :      * aren't able to verify that an error has occurred until later in the parse.
     989             :      * For instance | ({x=1}) | is always parsed as an object literal with
     990             :      * a SyntaxError, however, in the case where it is followed by '=>' we rewind
     991             :      * and reparse it as a valid arrow function. Here a PossibleError would be
     992             :      * set to 'pending' when the initial SyntaxError was encountered then 'resolved'
     993             :      * just before rewinding the parser.
     994             :      *
     995             :      * There are currently two kinds of PossibleErrors: Expression and
     996             :      * Destructuring errors. Expression errors are used to mark a possible
     997             :      * syntax error when a grammar production is used in an expression context.
     998             :      * For example in |{x = 1}|, we mark the CoverInitializedName |x = 1| as a
     999             :      * possible expression error, because CoverInitializedName productions
    1000             :      * are disallowed when an actual ObjectLiteral is expected.
    1001             :      * Destructuring errors are used to record possible syntax errors in
    1002             :      * destructuring contexts. For example in |[...rest, ] = []|, we initially
    1003             :      * mark the trailing comma after the spread expression as a possible
    1004             :      * destructuring error, because the ArrayAssignmentPattern grammar
    1005             :      * production doesn't allow a trailing comma after the rest element.
    1006             :      *
    1007             :      * When using PossibleError one should set a pending error at the location
    1008             :      * where an error occurs. From that point, the error may be resolved
    1009             :      * (invalidated) or left until the PossibleError is checked.
    1010             :      *
    1011             :      * Ex:
    1012             :      *   PossibleError possibleError(*this);
    1013             :      *   possibleError.setPendingExpressionErrorAt(pos, JSMSG_BAD_PROP_ID);
    1014             :      *   // A JSMSG_BAD_PROP_ID ParseError is reported, returns false.
    1015             :      *   if (!possibleError.checkForExpressionError())
    1016             :      *       return false; // we reach this point with a pending exception
    1017             :      *
    1018             :      *   PossibleError possibleError(*this);
    1019             :      *   possibleError.setPendingExpressionErrorAt(pos, JSMSG_BAD_PROP_ID);
    1020             :      *   // Returns true, no error is reported.
    1021             :      *   if (!possibleError.checkForDestructuringError())
    1022             :      *       return false; // not reached, no pending exception
    1023             :      *
    1024             :      *   PossibleError possibleError(*this);
    1025             :      *   // Returns true, no error is reported.
    1026             :      *   if (!possibleError.checkForExpressionError())
    1027             :      *       return false; // not reached, no pending exception
    1028             :      */
    1029             :     class MOZ_STACK_CLASS PossibleError
    1030             :     {
    1031             :       private:
    1032             :         enum class ErrorKind { Expression, Destructuring, DestructuringWarning };
    1033             : 
    1034             :         enum class ErrorState { None, Pending };
    1035             : 
    1036      217206 :         struct Error {
    1037             :             ErrorState state_ = ErrorState::None;
    1038             : 
    1039             :             // Error reporting fields.
    1040             :             uint32_t offset_;
    1041             :             unsigned errorNumber_;
    1042             :         };
    1043             : 
    1044             :         Parser<ParseHandler, CharT>& parser_;
    1045             :         Error exprError_;
    1046             :         Error destructuringError_;
    1047             :         Error destructuringWarning_;
    1048             : 
    1049             :         // Returns the error report.
    1050             :         Error& error(ErrorKind kind);
    1051             : 
    1052             :         // Return true if an error is pending without reporting.
    1053             :         bool hasError(ErrorKind kind);
    1054             : 
    1055             :         // Resolve any pending error.
    1056             :         void setResolved(ErrorKind kind);
    1057             : 
    1058             :         // Set a pending error. Only a single error may be set per instance and
    1059             :         // error kind.
    1060             :         void setPending(ErrorKind kind, const TokenPos& pos, unsigned errorNumber);
    1061             : 
    1062             :         // If there is a pending error, report it and return false, otherwise
    1063             :         // return true.
    1064             :         MOZ_MUST_USE bool checkForError(ErrorKind kind);
    1065             : 
    1066             :         // If there is a pending warning, report it and return either false or
    1067             :         // true depending on the werror option, otherwise return true.
    1068             :         MOZ_MUST_USE bool checkForWarning(ErrorKind kind);
    1069             : 
    1070             :         // Transfer an existing error to another instance.
    1071             :         void transferErrorTo(ErrorKind kind, PossibleError* other);
    1072             : 
    1073             :       public:
    1074             :         explicit PossibleError(Parser<ParseHandler, CharT>& parser);
    1075             : 
    1076             :         // Return true if a pending destructuring error is present.
    1077             :         bool hasPendingDestructuringError();
    1078             : 
    1079             :         // Set a pending destructuring error. Only a single error may be set
    1080             :         // per instance, i.e. subsequent calls to this method are ignored and
    1081             :         // won't overwrite the existing pending error.
    1082             :         void setPendingDestructuringErrorAt(const TokenPos& pos, unsigned errorNumber);
    1083             : 
    1084             :         // Set a pending destructuring warning. Only a single warning may be
    1085             :         // set per instance, i.e. subsequent calls to this method are ignored
    1086             :         // and won't overwrite the existing pending warning.
    1087             :         void setPendingDestructuringWarningAt(const TokenPos& pos, unsigned errorNumber);
    1088             : 
    1089             :         // Set a pending expression error. Only a single error may be set per
    1090             :         // instance, i.e. subsequent calls to this method are ignored and won't
    1091             :         // overwrite the existing pending error.
    1092             :         void setPendingExpressionErrorAt(const TokenPos& pos, unsigned errorNumber);
    1093             : 
    1094             :         // If there is a pending destructuring error or warning, report it and
    1095             :         // return false, otherwise return true. Clears any pending expression
    1096             :         // error.
    1097             :         MOZ_MUST_USE bool checkForDestructuringErrorOrWarning();
    1098             : 
    1099             :         // If there is a pending expression error, report it and return false,
    1100             :         // otherwise return true. Clears any pending destructuring error or
    1101             :         // warning.
    1102             :         MOZ_MUST_USE bool checkForExpressionError();
    1103             : 
    1104             :         // Pass pending errors between possible error instances. This is useful
    1105             :         // for extending the lifetime of a pending error beyond the scope of
    1106             :         // the PossibleError where it was initially set (keeping in mind that
    1107             :         // PossibleError is a MOZ_STACK_CLASS).
    1108             :         void transferErrorsTo(PossibleError* other);
    1109             :     };
    1110             : 
    1111             :     // When ParseHandler is FullParseHandler:
    1112             :     //
    1113             :     //   If non-null, this field holds the syntax parser used to attempt lazy
    1114             :     //   parsing of inner functions. If null, then lazy parsing is disabled.
    1115             :     //
    1116             :     // When ParseHandler is SyntaxParseHandler:
    1117             :     //
    1118             :     //   If non-null, this field must be a sentinel value signaling that the
    1119             :     //   syntax parse was aborted. If null, then lazy parsing was aborted due
    1120             :     //   to encountering unsupported language constructs.
    1121             :     using SyntaxParser = Parser<SyntaxParseHandler, CharT>;
    1122             :     SyntaxParser* syntaxParser_;
    1123             : 
    1124             :   public:
    1125             :     /* State specific to the kind of parse being performed. */
    1126             :     ParseHandler handler;
    1127             : 
    1128         455 :     void prepareNodeForMutation(Node node) { handler.prepareNodeForMutation(node); }
    1129        3376 :     void freeTree(Node node) { handler.freeTree(node); }
    1130             : 
    1131             :   public:
    1132             :     Parser(JSContext* cx, LifoAlloc& alloc, const ReadOnlyCompileOptions& options,
    1133             :            const CharT* chars, size_t length, bool foldConstants, UsedNameTracker& usedNames,
    1134             :            SyntaxParser* syntaxParser, LazyScript* lazyOuterFunction);
    1135             :     ~Parser();
    1136             : 
    1137             :     friend class AutoAwaitIsKeyword<Parser>;
    1138             :     void setAwaitHandling(AwaitHandling awaitHandling);
    1139             : 
    1140             :     // If ParseHandler is SyntaxParseHandler, whether the last syntax parse was
    1141             :     // aborted due to unsupported language constructs.
    1142             :     //
    1143             :     // If ParseHandler is FullParseHandler, false.
    1144             :     bool hadAbortedSyntaxParse();
    1145             : 
    1146             :     // If ParseHandler is SyntaxParseHandler, clear whether the last syntax
    1147             :     // parse was aborted.
    1148             :     //
    1149             :     // If ParseHandler is FullParseHandler, do nothing.
    1150             :     void clearAbortedSyntaxParse();
    1151             : 
    1152             :     bool checkOptions();
    1153             : 
    1154             :     friend void js::frontend::TraceParser(JSTracer* trc, JS::AutoGCRooter* parser);
    1155             : 
    1156             :     /*
    1157             :      * Parse a top-level JS script.
    1158             :      */
    1159             :     Node parse();
    1160             : 
    1161             :     FunctionBox* newFunctionBox(Node fn, JSFunction* fun, uint32_t toStringStart,
    1162             :                                 Directives directives,
    1163             :                                 GeneratorKind generatorKind, FunctionAsyncKind asyncKind);
    1164             : 
    1165             :     void trace(JSTracer* trc);
    1166             : 
    1167             :   private:
    1168           0 :     Parser* thisForCtor() { return this; }
    1169             : 
    1170             :     Node stringLiteral();
    1171             :     Node noSubstitutionTaggedTemplate();
    1172             :     Node noSubstitutionUntaggedTemplate();
    1173             :     Node templateLiteral(YieldHandling yieldHandling);
    1174             :     bool taggedTemplate(YieldHandling yieldHandling, Node nodeList, TokenKind tt);
    1175             :     bool appendToCallSiteObj(Node callSiteObj);
    1176             :     bool addExprAndGetNextTemplStrToken(YieldHandling yieldHandling, Node nodeList,
    1177             :                                         TokenKind* ttp);
    1178             :     bool checkStatementsEOF();
    1179             : 
    1180             :     inline Node newName(PropertyName* name);
    1181             :     inline Node newName(PropertyName* name, TokenPos pos);
    1182             : 
    1183             :     // If ParseHandler is SyntaxParseHandler, flag the current syntax parse as
    1184             :     // aborted due to unsupported language constructs and return
    1185             :     // false. Aborting the current syntax parse does not disable attempts to
    1186             :     // syntax parse future inner functions.
    1187             :     //
    1188             :     // If ParseHandler is FullParseHandler, disable syntax parsing of all
    1189             :     // future inner functions and return true.
    1190             :     inline bool abortIfSyntaxParser();
    1191             : 
    1192             :     // If ParseHandler is SyntaxParseHandler, do nothing.
    1193             :     //
    1194             :     // If ParseHandler is FullParseHandler, disable syntax parsing of all
    1195             :     // future inner functions.
    1196             :     void disableSyntaxParser();
    1197             : 
    1198             :   public:
    1199             :     /* Public entry points for parsing. */
    1200             :     Node statementListItem(YieldHandling yieldHandling, bool canHaveDirectives = false);
    1201             : 
    1202             :     // Parse the body of an eval.
    1203             :     //
    1204             :     // Eval scripts are distinguished from global scripts in that in ES6, per
    1205             :     // 18.2.1.1 steps 9 and 10, all eval scripts are executed under a fresh
    1206             :     // lexical scope.
    1207             :     Node evalBody(EvalSharedContext* evalsc);
    1208             : 
    1209             :     // Parse the body of a global script.
    1210             :     Node globalBody(GlobalSharedContext* globalsc);
    1211             : 
    1212             :     // Parse a module.
    1213             :     Node moduleBody(ModuleSharedContext* modulesc);
    1214             : 
    1215             :     // Parse a function, used for the Function, GeneratorFunction, and
    1216             :     // AsyncFunction constructors.
    1217             :     Node standaloneFunction(HandleFunction fun, HandleScope enclosingScope,
    1218             :                             const mozilla::Maybe<uint32_t>& parameterListEnd,
    1219             :                             GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
    1220             :                             Directives inheritedDirectives, Directives* newDirectives);
    1221             : 
    1222             :     // Parse a function, given only its arguments and body. Used for lazily
    1223             :     // parsed functions.
    1224             :     Node standaloneLazyFunction(HandleFunction fun, uint32_t toStringStart, bool strict,
    1225             :                                 GeneratorKind generatorKind, FunctionAsyncKind asyncKind);
    1226             : 
    1227             :     // Parse an inner function given an enclosing ParseContext and a
    1228             :     // FunctionBox for the inner function.
    1229             :     bool innerFunction(Node pn, ParseContext* outerpc, FunctionBox* funbox, uint32_t toStringStart,
    1230             :                        InHandling inHandling, YieldHandling yieldHandling,
    1231             :                        FunctionSyntaxKind kind,
    1232             :                        Directives inheritedDirectives, Directives* newDirectives);
    1233             : 
    1234             :     // Parse a function's formal parameters and its body assuming its function
    1235             :     // ParseContext is already on the stack.
    1236             :     bool functionFormalParametersAndBody(InHandling inHandling, YieldHandling yieldHandling,
    1237             :                                          Node pn, FunctionSyntaxKind kind,
    1238             :                                          const mozilla::Maybe<uint32_t>& parameterListEnd = mozilla::Nothing(),
    1239             :                                          bool isStandaloneFunction = false);
    1240             : 
    1241             :     // Match the current token against the BindingIdentifier production with
    1242             :     // the given Yield parameter.  If there is no match, report a syntax
    1243             :     // error.
    1244             :     PropertyName* bindingIdentifier(YieldHandling yieldHandling);
    1245             : 
    1246             :   private:
    1247             :     /*
    1248             :      * JS parsers, from lowest to highest precedence.
    1249             :      *
    1250             :      * Each parser must be called during the dynamic scope of a ParseContext
    1251             :      * object, pointed to by this->pc.
    1252             :      *
    1253             :      * Each returns a parse node tree or null on error.
    1254             :      *
    1255             :      * Parsers whose name has a '1' suffix leave the TokenStream state
    1256             :      * pointing to the token one past the end of the parsed fragment.  For a
    1257             :      * number of the parsers this is convenient and avoids a lot of
    1258             :      * unnecessary ungetting and regetting of tokens.
    1259             :      *
    1260             :      * Some parsers have two versions:  an always-inlined version (with an 'i'
    1261             :      * suffix) and a never-inlined version (with an 'n' suffix).
    1262             :      */
    1263             :     Node functionStmt(uint32_t toStringStart,
    1264             :                       YieldHandling yieldHandling, DefaultHandling defaultHandling,
    1265             :                       FunctionAsyncKind asyncKind = SyncFunction);
    1266             :     Node functionExpr(uint32_t toStringStart, InvokedPrediction invoked = PredictUninvoked,
    1267             :                       FunctionAsyncKind asyncKind = SyncFunction);
    1268             : 
    1269             :     Node statementList(YieldHandling yieldHandling);
    1270             :     Node statement(YieldHandling yieldHandling);
    1271             :     bool maybeParseDirective(Node list, Node pn, bool* cont);
    1272             : 
    1273             :     Node blockStatement(YieldHandling yieldHandling,
    1274             :                         unsigned errorNumber = JSMSG_CURLY_IN_COMPOUND);
    1275             :     Node doWhileStatement(YieldHandling yieldHandling);
    1276             :     Node whileStatement(YieldHandling yieldHandling);
    1277             : 
    1278             :     Node forStatement(YieldHandling yieldHandling);
    1279             :     bool forHeadStart(YieldHandling yieldHandling,
    1280             :                       IteratorKind iterKind,
    1281             :                       ParseNodeKind* forHeadKind,
    1282             :                       Node* forInitialPart,
    1283             :                       mozilla::Maybe<ParseContext::Scope>& forLetImpliedScope,
    1284             :                       Node* forInOrOfExpression);
    1285             :     Node expressionAfterForInOrOf(ParseNodeKind forHeadKind, YieldHandling yieldHandling);
    1286             : 
    1287             :     Node switchStatement(YieldHandling yieldHandling);
    1288             :     Node continueStatement(YieldHandling yieldHandling);
    1289             :     Node breakStatement(YieldHandling yieldHandling);
    1290             :     Node returnStatement(YieldHandling yieldHandling);
    1291             :     Node withStatement(YieldHandling yieldHandling);
    1292             :     Node throwStatement(YieldHandling yieldHandling);
    1293             :     Node tryStatement(YieldHandling yieldHandling);
    1294             :     Node catchBlockStatement(YieldHandling yieldHandling, ParseContext::Scope& catchParamScope);
    1295             :     Node debuggerStatement();
    1296             : 
    1297             :     Node variableStatement(YieldHandling yieldHandling);
    1298             : 
    1299             :     Node labeledStatement(YieldHandling yieldHandling);
    1300             :     Node labeledItem(YieldHandling yieldHandling);
    1301             : 
    1302             :     Node ifStatement(YieldHandling yieldHandling);
    1303             :     Node consequentOrAlternative(YieldHandling yieldHandling);
    1304             : 
    1305             :     // While on a |let| TOK_NAME token, examine |next|.  Indicate whether
    1306             :     // |next|, the next token already gotten with modifier TokenStream::None,
    1307             :     // continues a LexicalDeclaration.
    1308             :     bool nextTokenContinuesLetDeclaration(TokenKind next, YieldHandling yieldHandling);
    1309             : 
    1310             :     Node lexicalDeclaration(YieldHandling yieldHandling, DeclarationKind kind);
    1311             : 
    1312             :     Node importDeclaration();
    1313             : 
    1314             :     bool processExport(Node node);
    1315             :     bool processExportFrom(Node node);
    1316             : 
    1317             :     Node exportFrom(uint32_t begin, Node specList);
    1318             :     Node exportBatch(uint32_t begin);
    1319             :     bool checkLocalExportNames(Node node);
    1320             :     Node exportClause(uint32_t begin);
    1321             :     Node exportFunctionDeclaration(uint32_t begin, uint32_t toStringStart,
    1322             :                                    FunctionAsyncKind asyncKind = SyncFunction);
    1323             :     Node exportVariableStatement(uint32_t begin);
    1324             :     Node exportClassDeclaration(uint32_t begin);
    1325             :     Node exportLexicalDeclaration(uint32_t begin, DeclarationKind kind);
    1326             :     Node exportDefaultFunctionDeclaration(uint32_t begin, uint32_t toStringStart,
    1327             :                                           FunctionAsyncKind asyncKind = SyncFunction);
    1328             :     Node exportDefaultClassDeclaration(uint32_t begin);
    1329             :     Node exportDefaultAssignExpr(uint32_t begin);
    1330             :     Node exportDefault(uint32_t begin);
    1331             :     Node exportDeclaration();
    1332             : 
    1333             :     Node expressionStatement(YieldHandling yieldHandling,
    1334             :                              InvokedPrediction invoked = PredictUninvoked);
    1335             : 
    1336             :     // Declaration parsing.  The main entrypoint is Parser::declarationList,
    1337             :     // with sub-functionality split out into the remaining methods.
    1338             : 
    1339             :     // |blockScope| may be non-null only when |kind| corresponds to a lexical
    1340             :     // declaration (that is, PNK_LET or PNK_CONST).
    1341             :     //
    1342             :     // The for* parameters, for normal declarations, should be null/ignored.
    1343             :     // They should be non-null only when Parser::forHeadStart parses a
    1344             :     // declaration at the start of a for-loop head.
    1345             :     //
    1346             :     // In this case, on success |*forHeadKind| is PNK_FORHEAD, PNK_FORIN, or
    1347             :     // PNK_FOROF, corresponding to the three for-loop kinds.  The precise value
    1348             :     // indicates what was parsed.
    1349             :     //
    1350             :     // If parsing recognized a for(;;) loop, the next token is the ';' within
    1351             :     // the loop-head that separates the init/test parts.
    1352             :     //
    1353             :     // Otherwise, for for-in/of loops, the next token is the ')' ending the
    1354             :     // loop-head.  Additionally, the expression that the loop iterates over was
    1355             :     // parsed into |*forInOrOfExpression|.
    1356             :     Node declarationList(YieldHandling yieldHandling,
    1357             :                          ParseNodeKind kind,
    1358             :                          ParseNodeKind* forHeadKind = nullptr,
    1359             :                          Node* forInOrOfExpression = nullptr);
    1360             : 
    1361             :     // The items in a declaration list are either patterns or names, with or
    1362             :     // without initializers.  These two methods parse a single pattern/name and
    1363             :     // any associated initializer -- and if parsing an |initialDeclaration|
    1364             :     // will, if parsing in a for-loop head (as specified by |forHeadKind| being
    1365             :     // non-null), consume additional tokens up to the closing ')' in a
    1366             :     // for-in/of loop head, returning the iterated expression in
    1367             :     // |*forInOrOfExpression|.  (An "initial declaration" is the first
    1368             :     // declaration in a declaration list: |a| but not |b| in |var a, b|, |{c}|
    1369             :     // but not |d| in |let {c} = 3, d|.)
    1370             :     Node declarationPattern(Node decl, DeclarationKind declKind, TokenKind tt,
    1371             :                             bool initialDeclaration, YieldHandling yieldHandling,
    1372             :                             ParseNodeKind* forHeadKind, Node* forInOrOfExpression);
    1373             :     Node declarationName(Node decl, DeclarationKind declKind, TokenKind tt,
    1374             :                          bool initialDeclaration, YieldHandling yieldHandling,
    1375             :                          ParseNodeKind* forHeadKind, Node* forInOrOfExpression);
    1376             : 
    1377             :     // Having parsed a name (not found in a destructuring pattern) declared by
    1378             :     // a declaration, with the current token being the '=' separating the name
    1379             :     // from its initializer, parse and bind that initializer -- and possibly
    1380             :     // consume trailing in/of and subsequent expression, if so directed by
    1381             :     // |forHeadKind|.
    1382             :     bool initializerInNameDeclaration(Node decl, Node binding, Handle<PropertyName*> name,
    1383             :                                       DeclarationKind declKind, bool initialDeclaration,
    1384             :                                       YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
    1385             :                                       Node* forInOrOfExpression);
    1386             : 
    1387             :     Node expr(InHandling inHandling, YieldHandling yieldHandling,
    1388             :               TripledotHandling tripledotHandling, PossibleError* possibleError = nullptr,
    1389             :               InvokedPrediction invoked = PredictUninvoked);
    1390             :     Node assignExpr(InHandling inHandling, YieldHandling yieldHandling,
    1391             :                     TripledotHandling tripledotHandling, PossibleError* possibleError = nullptr,
    1392             :                     InvokedPrediction invoked = PredictUninvoked);
    1393             :     Node assignExprWithoutYieldOrAwait(YieldHandling yieldHandling);
    1394             :     Node yieldExpression(InHandling inHandling);
    1395             :     Node condExpr1(InHandling inHandling, YieldHandling yieldHandling,
    1396             :                    TripledotHandling tripledotHandling,
    1397             :                    PossibleError* possibleError,
    1398             :                    InvokedPrediction invoked = PredictUninvoked);
    1399             :     Node orExpr1(InHandling inHandling, YieldHandling yieldHandling,
    1400             :                  TripledotHandling tripledotHandling,
    1401             :                  PossibleError* possibleError,
    1402             :                  InvokedPrediction invoked = PredictUninvoked);
    1403             :     Node unaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
    1404             :                    PossibleError* possibleError = nullptr,
    1405             :                    InvokedPrediction invoked = PredictUninvoked);
    1406             :     Node memberExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
    1407             :                     TokenKind tt, bool allowCallSyntax = true,
    1408             :                     PossibleError* possibleError = nullptr,
    1409             :                     InvokedPrediction invoked = PredictUninvoked);
    1410             :     Node primaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
    1411             :                      TokenKind tt, PossibleError* possibleError,
    1412             :                      InvokedPrediction invoked = PredictUninvoked);
    1413             :     Node exprInParens(InHandling inHandling, YieldHandling yieldHandling,
    1414             :                       TripledotHandling tripledotHandling, PossibleError* possibleError = nullptr);
    1415             : 
    1416             :     bool tryNewTarget(Node& newTarget);
    1417             :     bool checkAndMarkSuperScope();
    1418             : 
    1419             :     Node methodDefinition(uint32_t toStringStart, PropertyType propType, HandleAtom funName);
    1420             : 
    1421             :     /*
    1422             :      * Additional JS parsers.
    1423             :      */
    1424             :     bool functionArguments(YieldHandling yieldHandling, FunctionSyntaxKind kind,
    1425             :                            Node funcpn);
    1426             : 
    1427             :     Node functionDefinition(Node func, uint32_t toStringStart,
    1428             :                             InHandling inHandling, YieldHandling yieldHandling,
    1429             :                             HandleAtom name, FunctionSyntaxKind kind,
    1430             :                             GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
    1431             :                             bool tryAnnexB = false);
    1432             : 
    1433             :     // Parse a function body.  Pass StatementListBody if the body is a list of
    1434             :     // statements; pass ExpressionBody if the body is a single expression.
    1435             :     enum FunctionBodyType { StatementListBody, ExpressionBody };
    1436             :     Node functionBody(InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind,
    1437             :                       FunctionBodyType type);
    1438             : 
    1439             :     Node unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind, JSOp op, uint32_t begin);
    1440             : 
    1441             :     Node condition(InHandling inHandling, YieldHandling yieldHandling);
    1442             : 
    1443             :     /* comprehensions */
    1444             :     Node generatorComprehensionLambda(unsigned begin);
    1445             :     Node comprehensionFor(GeneratorKind comprehensionKind);
    1446             :     Node comprehensionIf(GeneratorKind comprehensionKind);
    1447             :     Node comprehensionTail(GeneratorKind comprehensionKind);
    1448             :     Node comprehension(GeneratorKind comprehensionKind);
    1449             :     Node arrayComprehension(uint32_t begin);
    1450             :     Node generatorComprehension(uint32_t begin);
    1451             : 
    1452             :     bool argumentList(YieldHandling yieldHandling, Node listNode, bool* isSpread,
    1453             :                       PossibleError* possibleError = nullptr);
    1454             :     Node destructuringDeclaration(DeclarationKind kind, YieldHandling yieldHandling,
    1455             :                                   TokenKind tt);
    1456             :     Node destructuringDeclarationWithoutYieldOrAwait(DeclarationKind kind, YieldHandling yieldHandling,
    1457             :                                                      TokenKind tt);
    1458             : 
    1459             :     bool namedImportsOrNamespaceImport(TokenKind tt, Node importSpecSet);
    1460             :     bool checkExportedName(JSAtom* exportName);
    1461             :     bool checkExportedNamesForDeclaration(Node node);
    1462             :     bool checkExportedNameForClause(Node node);
    1463             :     bool checkExportedNameForFunction(Node node);
    1464             :     bool checkExportedNameForClass(Node node);
    1465             : 
    1466             :     enum ClassContext { ClassStatement, ClassExpression };
    1467             :     Node classDefinition(YieldHandling yieldHandling, ClassContext classContext,
    1468             :                          DefaultHandling defaultHandling);
    1469             : 
    1470             :     bool checkLabelOrIdentifierReference(PropertyName* ident,
    1471             :                                          uint32_t offset,
    1472             :                                          YieldHandling yieldHandling,
    1473             :                                          TokenKind hint = TOK_LIMIT);
    1474             : 
    1475           0 :     bool checkLocalExportName(PropertyName* ident, uint32_t offset) {
    1476           0 :         return checkLabelOrIdentifierReference(ident, offset, YieldIsName);
    1477             :     }
    1478             : 
    1479             :     bool checkBindingIdentifier(PropertyName* ident,
    1480             :                                 uint32_t offset,
    1481             :                                 YieldHandling yieldHandling,
    1482             :                                 TokenKind hint = TOK_LIMIT);
    1483             : 
    1484             :     PropertyName* labelOrIdentifierReference(YieldHandling yieldHandling);
    1485             : 
    1486           0 :     PropertyName* labelIdentifier(YieldHandling yieldHandling) {
    1487           0 :         return labelOrIdentifierReference(yieldHandling);
    1488             :     }
    1489             : 
    1490       82073 :     PropertyName* identifierReference(YieldHandling yieldHandling) {
    1491       82073 :         return labelOrIdentifierReference(yieldHandling);
    1492             :     }
    1493             : 
    1494           0 :     PropertyName* importedBinding() {
    1495           0 :         return bindingIdentifier(YieldIsName);
    1496             :     }
    1497             : 
    1498             :     Node identifierReference(Handle<PropertyName*> name);
    1499             : 
    1500             :     bool matchLabel(YieldHandling yieldHandling, MutableHandle<PropertyName*> label);
    1501             : 
    1502             :     bool matchInOrOf(bool* isForInp, bool* isForOfp);
    1503             : 
    1504             :     bool hasUsedFunctionSpecialName(HandlePropertyName name);
    1505             :     bool declareFunctionArgumentsObject();
    1506             :     bool declareFunctionThis();
    1507             :     Node newInternalDotName(HandlePropertyName name);
    1508             :     Node newThisName();
    1509             :     Node newDotGeneratorName();
    1510             :     bool declareDotGeneratorName();
    1511             : 
    1512             :     bool skipLazyInnerFunction(Node pn, uint32_t toStringStart, FunctionSyntaxKind kind,
    1513             :                                bool tryAnnexB);
    1514             :     bool innerFunction(Node pn, ParseContext* outerpc, HandleFunction fun, uint32_t toStringStart,
    1515             :                        InHandling inHandling, YieldHandling yieldHandling,
    1516             :                        FunctionSyntaxKind kind,
    1517             :                        GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
    1518             :                        Directives inheritedDirectives, Directives* newDirectives);
    1519             :     bool trySyntaxParseInnerFunction(Node pn, HandleFunction fun, uint32_t toStringStart,
    1520             :                                      InHandling inHandling, YieldHandling yieldHandling,
    1521             :                                      FunctionSyntaxKind kind,
    1522             :                                      GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
    1523             :                                      bool tryAnnexB,
    1524             :                                      Directives inheritedDirectives, Directives* newDirectives);
    1525             :     bool finishFunctionScopes(bool isStandaloneFunction);
    1526             :     bool finishFunction(bool isStandaloneFunction = false);
    1527             :     bool leaveInnerFunction(ParseContext* outerpc);
    1528             : 
    1529             :     bool matchOrInsertSemicolonHelper(TokenStream::Modifier modifier);
    1530             :     bool matchOrInsertSemicolonAfterExpression();
    1531             :     bool matchOrInsertSemicolonAfterNonExpression();
    1532             : 
    1533             :   public:
    1534             :     enum FunctionCallBehavior {
    1535             :         PermitAssignmentToFunctionCalls,
    1536             :         ForbidAssignmentToFunctionCalls
    1537             :     };
    1538             : 
    1539             :     bool isValidSimpleAssignmentTarget(Node node,
    1540             :                                        FunctionCallBehavior behavior = ForbidAssignmentToFunctionCalls);
    1541             : 
    1542             :   private:
    1543             :     bool checkIncDecOperand(Node operand, uint32_t operandOffset);
    1544             :     bool checkStrictAssignment(Node lhs);
    1545             : 
    1546             :     void reportMissingClosing(unsigned errorNumber, unsigned noteNumber, uint32_t openedPos);
    1547             : 
    1548             :     void reportRedeclaration(HandlePropertyName name, DeclarationKind prevKind, TokenPos pos,
    1549             :                              uint32_t prevPos);
    1550             :     bool notePositionalFormalParameter(Node fn, HandlePropertyName name, uint32_t beginPos,
    1551             :                                        bool disallowDuplicateParams, bool* duplicatedParam);
    1552             :     bool noteDestructuredPositionalFormalParameter(Node fn, Node destruct);
    1553             : 
    1554             :     bool checkLexicalDeclarationDirectlyWithinBlock(ParseContext::Statement& stmt,
    1555             :                                                     DeclarationKind kind, TokenPos pos);
    1556             :     bool noteDeclaredName(HandlePropertyName name, DeclarationKind kind, TokenPos pos);
    1557             :     bool noteUsedName(HandlePropertyName name);
    1558             :     bool hasUsedName(HandlePropertyName name);
    1559             : 
    1560             :     // Required on Scope exit.
    1561             :     bool propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope);
    1562             : 
    1563             :     Node finishLexicalScope(ParseContext::Scope& scope, Node body);
    1564             : 
    1565             :     Node propertyName(YieldHandling yieldHandling,
    1566             :                       const mozilla::Maybe<DeclarationKind>& maybeDecl, Node propList,
    1567             :                       PropertyType* propType, MutableHandleAtom propAtom);
    1568             :     Node computedPropertyName(YieldHandling yieldHandling,
    1569             :                               const mozilla::Maybe<DeclarationKind>& maybeDecl, Node literal);
    1570             :     Node arrayInitializer(YieldHandling yieldHandling, PossibleError* possibleError);
    1571             :     Node newRegExp();
    1572             : 
    1573             :     Node objectLiteral(YieldHandling yieldHandling, PossibleError* possibleError);
    1574             : 
    1575             :     Node bindingInitializer(Node lhs, DeclarationKind kind, YieldHandling yieldHandling);
    1576             :     Node bindingIdentifier(DeclarationKind kind, YieldHandling yieldHandling);
    1577             :     Node bindingIdentifierOrPattern(DeclarationKind kind, YieldHandling yieldHandling,
    1578             :                                     TokenKind tt);
    1579             :     Node objectBindingPattern(DeclarationKind kind, YieldHandling yieldHandling);
    1580             :     Node arrayBindingPattern(DeclarationKind kind, YieldHandling yieldHandling);
    1581             : 
    1582             :     void checkDestructuringAssignmentTarget(Node expr, TokenPos exprPos,
    1583             :                                             PossibleError* possibleError);
    1584             :     void checkDestructuringAssignmentElement(Node expr, TokenPos exprPos,
    1585             :                                              PossibleError* possibleError);
    1586             : 
    1587        9971 :     Node newNumber(const Token& tok) {
    1588        9971 :         return handler.newNumber(tok.number(), tok.decimalPoint(), tok.pos);
    1589             :     }
    1590             : 
    1591       24440 :     static Node null() { return ParseHandler::null(); }
    1592             : 
    1593             :     JSAtom* prefixAccessorName(PropertyType propType, HandleAtom propAtom);
    1594             : 
    1595             :     bool asmJS(Node list);
    1596             : };
    1597             : 
    1598             : template <class Parser>
    1599             : class MOZ_STACK_CLASS AutoAwaitIsKeyword
    1600             : {
    1601             :   private:
    1602             :     Parser* parser_;
    1603             :     AwaitHandling oldAwaitHandling_;
    1604             : 
    1605             :   public:
    1606       15950 :     AutoAwaitIsKeyword(Parser* parser, AwaitHandling awaitHandling) {
    1607       15950 :         parser_ = parser;
    1608       15950 :         oldAwaitHandling_ = static_cast<AwaitHandling>(parser_->awaitHandling_);
    1609             : 
    1610             :         // 'await' is always a keyword in module contexts, so we don't modify
    1611             :         // the state when the original handling is AwaitIsModuleKeyword.
    1612       15950 :         if (oldAwaitHandling_ != AwaitIsModuleKeyword)
    1613       15950 :             parser_->setAwaitHandling(awaitHandling);
    1614       15950 :     }
    1615             : 
    1616       15950 :     ~AutoAwaitIsKeyword() {
    1617       15950 :         parser_->setAwaitHandling(oldAwaitHandling_);
    1618       15950 :     }
    1619             : };
    1620             : 
    1621             : } /* namespace frontend */
    1622             : } /* namespace js */
    1623             : 
    1624             : #endif /* frontend_Parser_h */

Generated by: LCOV version 1.13